diff --git a/BUILD.gn b/BUILD.gn index 9b8f60b..ab7465f 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -231,9 +231,14 @@ deps += [ "//extensions:extensions_browsertests", "//extensions:extensions_unittests", - "//extensions/browser/api/declarative_net_request/filter_list_converter", "//extensions/shell:app_shell_unittests", ] + + # TODO(crbug.com/981112): This target is failing to compile consistently in + # coverage build, remove this condition when the bug is fixed. + if (!use_clang_coverage) { + deps += [ "//extensions/browser/api/declarative_net_request/filter_list_converter" ] + } } if (enable_remoting) {
diff --git a/DEPS b/DEPS index 02ce51b..e687e5f 100644 --- a/DEPS +++ b/DEPS
@@ -142,7 +142,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '11eb847a2080aa944b2596a6c2f8f3bdc0eaa493', + 'skia_revision': '8063f6cca02538ef152c2b7afc29d06cb750f034', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -154,15 +154,15 @@ # 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': '35c847eb2902c4f298ae386c22b872db911a325c', + 'angle_revision': 'b00ecb9a18f36fadc975e7b1328e884b4dea2526', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '72d8104846debbd3aba9ab244fcc38302c9adf43', + 'swiftshader_revision': '68cfc78ee7f74d69901ba0dd54b7cba27b0b60d9', # 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': '3dd6ef0648987f3c0b4b74aada0406a90e7947bd', + 'pdfium_revision': '73bd37c824051aac631abaf567bab7dcd02093df', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -205,7 +205,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '8a36dcd7cfe8f70fcb11176d1b27b0b41d2a4c25', + 'catapult_revision': 'a78382fe6b0dc64a868b3d53e08d50f75f45a427', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -273,7 +273,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. - 'shaderc_revision': '23bbb3211ecee065c118b14b4c8bd13f0a61c04d', + 'shaderc_revision': '77d7b65ee2a1ad30e68975bfbeaa68e15db5036b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -481,7 +481,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'dc0267693ad4813d4216424bdf20def3ae21bfac', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '00142ad6d9906f97ec5da8ae039ea75afb3e76f5', 'condition': 'checkout_ios', }, @@ -831,7 +831,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'ff4f6bccd80028223aeff72710d58f7de668d94f', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '92afaf53fddb7cb46ef7ee8d752521f6868be7d8', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1191,7 +1191,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '449133b69d26534e25f15aadcd36efc84b6ae468', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '4d4473304b71ccb8f10be9f2293e2eaf8ec1e075', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1400,7 +1400,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@8157a80b7293b3e46154c232c78e94a8a1803d00', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@db705459336149dd1751af0b0d6fb6f3142d5f12', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index 0818133..ff5fc10 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -1102,12 +1102,12 @@ return true; } -void AwContentBrowserClient::WillCreateWebSocket( - content::RenderFrameHost* frame, - network::mojom::WebSocketRequest* request, - network::mojom::AuthenticationHandlerPtr* auth_handler, - network::mojom::TrustedHeaderClientPtr* header_client, - uint32_t* options) { +uint32_t AwContentBrowserClient::GetWebSocketOptions( + content::RenderFrameHost* frame) { + uint32_t options = network::mojom::kWebSocketOptionNone; + if (!frame) { + return options; + } content::WebContents* web_contents = content::WebContents::FromRenderFrameHost(frame); AwContents* aw_contents = AwContents::FromWebContents(web_contents); @@ -1116,10 +1116,11 @@ AwCookieAccessPolicy::GetInstance()->GetShouldAcceptCookies(); bool third_party_cookie_policy = aw_contents->AllowThirdPartyCookies(); if (!global_cookie_policy) { - *options |= network::mojom::kWebSocketOptionBlockAllCookies; + options |= network::mojom::kWebSocketOptionBlockAllCookies; } else if (!third_party_cookie_policy) { - *options |= network::mojom::kWebSocketOptionBlockThirdPartyCookies; + options |= network::mojom::kWebSocketOptionBlockThirdPartyCookies; } + return options; } void AwContentBrowserClient::WillCreateRestrictedCookieManager(
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index d15ef02..efa65e8f 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -241,12 +241,7 @@ network::mojom::URLLoaderFactoryRequest* factory_request, network::mojom::TrustedURLLoaderHeaderClientPtrInfo* header_client, bool* bypass_redirect_checks) override; - void WillCreateWebSocket( - content::RenderFrameHost* frame, - network::mojom::WebSocketRequest* request, - network::mojom::AuthenticationHandlerPtr* authentication_handler, - network::mojom::TrustedHeaderClientPtr* header_client, - uint32_t* options) override; + uint32_t GetWebSocketOptions(content::RenderFrameHost* frame) override; void WillCreateRestrictedCookieManager( const url::Origin& origin, bool is_service_worker,
diff --git a/ash/display/screen_orientation_controller.cc b/ash/display/screen_orientation_controller.cc index be0a3ae..62dafdc 100644 --- a/ash/display/screen_orientation_controller.cc +++ b/ash/display/screen_orientation_controller.cc
@@ -12,6 +12,7 @@ #include "ash/public/cpp/ash_switches.h" #include "ash/shell.h" #include "ash/wm/mru_window_tracker.h" +#include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "base/auto_reset.h" @@ -218,9 +219,11 @@ user_rotation_(display::Display::ROTATE_0), current_rotation_(display::Display::ROTATE_0) { Shell::Get()->tablet_mode_controller()->AddObserver(this); + Shell::Get()->AddShellObserver(this); } ScreenOrientationController::~ScreenOrientationController() { + Shell::Get()->RemoveShellObserver(this); Shell::Get()->tablet_mode_controller()->RemoveObserver(this); AccelerometerReader::GetInstance()->RemoveObserver(this); Shell::Get()->window_tree_host_manager()->RemoveObserver(this); @@ -415,6 +418,14 @@ UnlockAll(); } +void ScreenOrientationController::OnSplitViewModeStarted() { + ApplyLockForActiveWindow(); +} + +void ScreenOrientationController::OnSplitViewModeEnded() { + ApplyLockForActiveWindow(); +} + void ScreenOrientationController::SetDisplayRotation( display::Display::Rotation rotation, display::Display::RotationSource source, @@ -589,6 +600,13 @@ return; Shell* shell = Shell::Get(); + + if (shell->split_view_controller()->InTabletSplitViewMode()) { + // While split view is enabled, ignore rotation lock set by windows. + LockRotationToOrientation(user_locked_orientation_); + return; + } + MruWindowTracker::WindowList mru_windows( shell->mru_window_tracker()->BuildMruWindowList(kActiveDesk));
diff --git a/ash/display/screen_orientation_controller.h b/ash/display/screen_orientation_controller.h index 1e7dabe..aff856d 100644 --- a/ash/display/screen_orientation_controller.h +++ b/ash/display/screen_orientation_controller.h
@@ -12,6 +12,7 @@ #include "ash/ash_export.h" #include "ash/display/display_configuration_controller.h" #include "ash/display/window_tree_host_manager.h" +#include "ash/shell_observer.h" #include "ash/wm/tablet_mode/tablet_mode_observer.h" #include "base/macros.h" #include "base/observer_list.h" @@ -55,7 +56,8 @@ public aura::WindowObserver, public AccelerometerReader::Observer, public WindowTreeHostManager::Observer, - public TabletModeObserver { + public TabletModeObserver, + public ShellObserver { public: // Observer that reports changes to the state of ScreenOrientationProvider's // rotation lock. @@ -152,6 +154,10 @@ void OnTabletModeEnding() override; void OnTabletModeEnded() override; + // ShellObserver: + void OnSplitViewModeStarted() override; + void OnSplitViewModeEnded() override; + private: friend class ScreenOrientationControllerTestApi;
diff --git a/ash/display/screen_orientation_controller_unittest.cc b/ash/display/screen_orientation_controller_unittest.cc index cebce12..ce5daf6 100644 --- a/ash/display/screen_orientation_controller_unittest.cc +++ b/ash/display/screen_orientation_controller_unittest.cc
@@ -23,6 +23,7 @@ #include "ash/test/ash_test_helper.h" #include "ash/test_shell_delegate.h" #include "ash/window_factory.h" +#include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "base/command_line.h" @@ -331,6 +332,30 @@ EXPECT_FALSE(RotationLocked()); } +TEST_F(ScreenOrientationControllerTest, SplitViewPreventsLock) { + EnableTabletMode(true); + + std::unique_ptr<aura::Window> child_window1 = CreateControlWindow(); + std::unique_ptr<aura::Window> child_window2 = CreateControlWindow(); + std::unique_ptr<aura::Window> focus_window1(CreateAppWindowInShellWithId(0)); + std::unique_ptr<aura::Window> focus_window2(CreateAppWindowInShellWithId(1)); + + AddWindowAndActivateParent(child_window1.get(), focus_window1.get()); + AddWindowAndShow(child_window2.get(), focus_window2.get()); + Lock(child_window1.get(), OrientationLockType::kLandscape); + Lock(child_window2.get(), OrientationLockType::kPortrait); + ASSERT_TRUE(RotationLocked()); + + Shell::Get()->split_view_controller()->SnapWindow(focus_window1.get(), + SplitViewController::LEFT); + Shell::Get()->split_view_controller()->SnapWindow(focus_window1.get(), + SplitViewController::RIGHT); + EXPECT_FALSE(RotationLocked()); + + Shell::Get()->split_view_controller()->EndSplitView(); + EXPECT_TRUE(RotationLocked()); +} + // Tests that accelerometer readings in each of the screen angles will trigger a // rotation of the internal display. TEST_F(ScreenOrientationControllerTest, DisplayRotation) {
diff --git a/chrome/VERSION b/chrome/VERSION index 4fa6b80..2cc594a5 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=77 MINOR=0 -BUILD=3843 +BUILD=3844 PATCH=0
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java index 19a80b3..ca735e9 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java
@@ -114,6 +114,7 @@ @Override public void restoreCompleted() { Tab currentTab = mTabModelSelector.getCurrentTab(); + if (currentTab == null) return; resetTabStripWithRelatedTabsForId(currentTab.getId()); } };
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java new file mode 100644 index 0000000..946095d --- /dev/null +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java
@@ -0,0 +1,250 @@ +// 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. + +package org.chromium.chrome.browser.tasks.tab_management; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.ThemeColorProvider; +import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabCreatorManager; +import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelFilterProvider; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; +import org.chromium.chrome.browser.tasks.tabgroup.TabGroupModelFilter; +import org.chromium.chrome.browser.toolbar.bottom.BottomControlsCoordinator; +import org.chromium.ui.modelutil.PropertyModel; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Tests for {@link TabGroupUiMediator}. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class TabGroupUiMediatorUnitTest { + private static final int TAB1_ID = 456; + private static final int TAB2_ID = 789; + private static final int TAB3_ID = 123; + private static final int POSITION1 = 0; + private static final int POSITION2 = 1; + private static final int POSITION3 = 2; + private static final int TAB1_ROOT_ID = TAB1_ID; + private static final int TAB2_ROOT_ID = TAB2_ID; + private static final int TAB3_ROOT_ID = TAB2_ID; + + @Mock + BottomControlsCoordinator.BottomControlsVisibilityController mVisibilityController; + @Mock + TabGroupUiMediator.ResetHandler mResetHandler; + @Mock + TabModelSelector mTabModelSelector; + @Mock + TabCreatorManager mTabCreatorManager; + @Mock + TabCreatorManager.TabCreator mTabCreator; + @Mock + OverviewModeBehavior mOverviewModeBehavior; + @Mock + ThemeColorProvider mThemeColorProvider; + @Mock + TabModel mTabModel; + @Mock + TabModelFilterProvider mTabModelFilterProvider; + @Mock + TabGroupModelFilter mTabGroupModelFilter; + @Captor + ArgumentCaptor<TabModelObserver> mTabModelObserverArgumentCaptor; + @Captor + ArgumentCaptor<OverviewModeBehavior.OverviewModeObserver> mOverviewModeObserverArgumentCaptor; + @Captor + ArgumentCaptor<TabModelSelectorObserver> mTabModelSelectorObserverArgumentCaptor; + @Captor + ArgumentCaptor<ThemeColorProvider.ThemeColorObserver> mThemeColorObserverArgumentCaptor; + @Captor + ArgumentCaptor<ThemeColorProvider.TintObserver> mTintObserverArgumentCaptor; + + private Tab mTab1; + private Tab mTab2; + private Tab mTab3; + private PropertyModel mModel; + private TabGroupUiMediator mTabGroupUiMediator; + private boolean mIsVisible; + private InOrder mVisibilityControllerInOrder; + + private Tab prepareTab(int tabId, int rootId) { + Tab tab = mock(Tab.class); + doReturn(tabId).when(tab).getId(); + doReturn(rootId).when(tab).getRootId(); + return tab; + } + + private void initAndAssertProperties(boolean tabModelHasTab) { + if (!tabModelHasTab) { + doReturn(TabModel.INVALID_TAB_INDEX).when(mTabModel).index(); + doReturn(0).when(mTabModel).getCount(); + doReturn(0).when(mTabGroupModelFilter).getCount(); + doReturn(null).when(mTabModelSelector).getCurrentTab(); + } + + mTabGroupUiMediator = new TabGroupUiMediator(mVisibilityController, mResetHandler, mModel, + mTabModelSelector, mTabCreatorManager, mOverviewModeBehavior, mThemeColorProvider); + + if (!tabModelHasTab) { + verify(mResetHandler, never()).resetStripWithListOfTabs(any()); + mVisibilityControllerInOrder.verify(mVisibilityController, never()) + .setBottomControlsVisible(anyBoolean()); + } else { + verify(mResetHandler).resetStripWithListOfTabs(any()); + mVisibilityControllerInOrder.verify(mVisibilityController) + .setBottomControlsVisible(anyBoolean()); + } + } + + @Before + public void setUp() { + // Each test must call initAndAssertProperties. After setUp() and + // initAndAssertProperties(true), TabModel has 3 tabs in the following order: mTab1, mTab2, + // and mTab3, while mTab2 and mTab3 are in a group. By default mTab1 is selected. If + // initAndAssertProperties(false) is called instead, there's no tabs in TabModel. + RecordUserAction.setDisabledForTests(true); + RecordHistogram.setDisabledForTests(true); + + MockitoAnnotations.initMocks(this); + + mIsVisible = false; + + // Set up Tabs + mTab1 = prepareTab(TAB1_ID, TAB1_ROOT_ID); + mTab2 = prepareTab(TAB2_ID, TAB2_ROOT_ID); + mTab3 = prepareTab(TAB3_ID, TAB3_ROOT_ID); + + // Set up TabModel. + doReturn(false).when(mTabModel).isIncognito(); + doReturn(3).when(mTabModel).getCount(); + doReturn(0).when(mTabModel).index(); + doReturn(mTab1).when(mTabModel).getTabAt(0); + doReturn(mTab2).when(mTabModel).getTabAt(1); + doReturn(mTab3).when(mTabModel).getTabAt(2); + doReturn(POSITION1).when(mTabModel).indexOf(mTab1); + doReturn(POSITION2).when(mTabModel).indexOf(mTab2); + doReturn(POSITION3).when(mTabModel).indexOf(mTab3); + + // Set up TabGroupModelFilter. + doReturn(false).when(mTabGroupModelFilter).isIncognito(); + doReturn(2).when(mTabGroupModelFilter).getCount(); + doReturn(mTab1).when(mTabModel).getTabAt(0); + doReturn(mTab2).when(mTabModel).getTabAt(1); + doReturn(POSITION1).when(mTabModel).indexOf(mTab1); + doReturn(POSITION2).when(mTabModel).indexOf(mTab2); + doReturn(POSITION2).when(mTabModel).indexOf(mTab3); + List<Tab> tabs1 = new ArrayList<>(Arrays.asList(mTab1)); + List<Tab> tabs2 = new ArrayList<>(Arrays.asList(mTab2, mTab3)); + doReturn(tabs1).when(mTabGroupModelFilter).getRelatedTabList(TAB1_ID); + doReturn(tabs2).when(mTabGroupModelFilter).getRelatedTabList(TAB2_ID); + doReturn(tabs2).when(mTabGroupModelFilter).getRelatedTabList(TAB3_ID); + + // Set up TabModelSelector, TabModelFilterProvider, TabGroupModelFilter. + doReturn(mTabModel).when(mTabModelSelector).getCurrentModel(); + doReturn(mTab1).when(mTabModelSelector).getCurrentTab(); + doNothing().when(mTabModelSelector) + .addObserver(mTabModelSelectorObserverArgumentCaptor.capture()); + + doReturn(mTabModelFilterProvider).when(mTabModelSelector).getTabModelFilterProvider(); + doNothing().when(mTabModelFilterProvider) + .addTabModelFilterObserver(mTabModelObserverArgumentCaptor.capture()); + + doReturn(mTabGroupModelFilter).when(mTabModelFilterProvider).getCurrentTabModelFilter(); + + // Set up OverviewModeBehavior + doNothing().when(mOverviewModeBehavior) + .addOverviewModeObserver(mOverviewModeObserverArgumentCaptor.capture()); + + // Set up ThemeColorProvider + doNothing().when(mThemeColorProvider) + .addThemeColorObserver(mThemeColorObserverArgumentCaptor.capture()); + doNothing().when(mThemeColorProvider) + .addTintObserver(mTintObserverArgumentCaptor.capture()); + + // Set up ResetHandler + doNothing().when(mResetHandler).resetStripWithListOfTabs(any()); + doNothing().when(mResetHandler).resetGridWithListOfTabs(any()); + + // Set up TabCreatorManager + doReturn(mTabCreator).when(mTabCreatorManager).getTabCreator(anyBoolean()); + doReturn(null).when(mTabCreator).createNewTab(any(), anyInt(), any()); + + mVisibilityControllerInOrder = inOrder(mVisibilityController); + mModel = new PropertyModel(TabStripToolbarViewProperties.ALL_KEYS); + } + + @After + public void tearDown() { + RecordUserAction.setDisabledForTests(false); + RecordHistogram.setDisabledForTests(false); + } + + @Test + public void restoreCompleted_TabModelNoTab() { + // Simulate no tab in current TabModel. + initAndAssertProperties(false); + + // Simulate restore finished. + mTabModelObserverArgumentCaptor.getValue().restoreCompleted(); + + mVisibilityControllerInOrder.verify(mVisibilityController, never()) + .setBottomControlsVisible(anyBoolean()); + } + + @Test + public void restoreCompleted_UiNotVisible() { + // Assume mTab1 is selected, and it does not have related tabs. + initAndAssertProperties(true); + doReturn(POSITION1).when(mTabModel).index(); + doReturn(mTab1).when(mTabModelSelector).getCurrentTab(); + // Simulate restore finished. + mTabModelObserverArgumentCaptor.getValue().restoreCompleted(); + + mVisibilityControllerInOrder.verify(mVisibilityController).setBottomControlsVisible(false); + } + + @Test + public void restoreCompleted_UiVisible() { + // Assume mTab2 is selected, and it has related tabs mTab2 and mTab3. + initAndAssertProperties(true); + doReturn(POSITION2).when(mTabModel).index(); + doReturn(mTab2).when(mTabModelSelector).getCurrentTab(); + // Simulate restore finished. + mTabModelObserverArgumentCaptor.getValue().restoreCompleted(); + + mVisibilityControllerInOrder.verify(mVisibilityController).setBottomControlsVisible(true); + } +} \ No newline at end of file
diff --git a/chrome/android/features/tab_ui/tab_management_java_sources.gni b/chrome/android/features/tab_ui/tab_management_java_sources.gni index 318f98f..69fb4345 100644 --- a/chrome/android/features/tab_ui/tab_management_java_sources.gni +++ b/chrome/android/features/tab_ui/tab_management_java_sources.gni
@@ -22,5 +22,6 @@ "//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/GridTabSwitcherMediatorUnitTest.java", "//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java", "//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java", + "//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java", "//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java", ]
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index c868fdf..b727990 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -865,6 +865,8 @@ <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> + <data android:mimeType="multipart/related" /> + <data android:mimeType="message/rfc822" /> </intent-filter> </activity>
diff --git a/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected b/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected index cad4e13a..6fe743f 100644 --- a/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected +++ b/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected
@@ -185,6 +185,8 @@ <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="message/rfc822"/> + <data android:mimeType="multipart/related"/> <data android:mimeType="text/plain"/> </intent-filter> </activity>
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index b8a80341..41b079b 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-77.0.3842.0_rc-r1-merged.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-77.0.3843.0_rc-r1-merged.afdo.bz2 \ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 226e64a..da5c8ac 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -3880,7 +3880,10 @@ <message name="IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD" desc="Text in the add fingerprint dialog telling users to place finger on the sensor on the keyboard."> Touch the fingerprint sensor with your finger </message> - <message name="IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_TOP_RIGHT_ARIA_LABEL" desc="Aria label in the add fingerprint dialog telling users that the fingerprint sensor is on the keyboard. Only visible by screen reader software."> + <message name="IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_RIGHT_ARIA_LABEL" desc="Aria label in the add fingerprint dialog telling users that the fingerprint sensor is in the bottom right corner of the keyboard. Only visible by screen reader software."> + The fingerprint sensor is the bottom right-hand key on your keyboard. Touch it lightly with any finger. + </message> + <message name="IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_TOP_RIGHT_ARIA_LABEL" desc="Aria label in the add fingerprint dialog telling users that the fingerprint sensor is in the top right corner of the keyboard. Only visible by screen reader software."> The fingerprint sensor is the top right-hand key on your keyboard. Touch it lightly with any finger. </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 1521d56..688591c 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4063,6 +4063,13 @@ flag_descriptions::kSafetyTipDescription, kOsAll, FEATURE_VALUE_TYPE(features::kSafetyTipUI)}, +#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) + {"animated-avatar-button", flag_descriptions::kAnimatedAvatarButtonName, + flag_descriptions::kAnimatedAvatarButtonDescription, + kOsWin | kOsMac | kOsLinux, + FEATURE_VALUE_TYPE(features::kAnimatedAvatarButton)}, +#endif // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/android/thumbnail/thumbnail_cache.cc b/chrome/browser/android/thumbnail/thumbnail_cache.cc index 71bff47..ed1d82c 100644 --- a/chrome/browser/android/thumbnail/thumbnail_cache.cc +++ b/chrome/browser/android/thumbnail/thumbnail_cache.cc
@@ -48,21 +48,27 @@ // Indicates whether we prefer to have more free CPU memory over GPU memory. const bool kPreferCPUMemory = true; -size_t NextPowerOfTwo(size_t x) { +unsigned int NextPowerOfTwo(int a) { + DCHECK(a >= 0); + auto x = static_cast<unsigned int>(a); --x; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; + x |= x >> 1u; + x |= x >> 2u; + x |= x >> 4u; + x |= x >> 8u; + x |= x >> 16u; return x + 1; } -size_t RoundUpMod4(size_t x) { - return (x + 3) & ~3; +unsigned int RoundUpMod4(int a) { + DCHECK(a >= 0); + auto x = static_cast<unsigned int>(a); + return (x + 3u) & ~3u; } gfx::Size GetEncodedSize(const gfx::Size& bitmap_size, bool supports_npot) { + DCHECK(bitmap_size.width() >= 0); + DCHECK(bitmap_size.height() >= 0); DCHECK(!bitmap_size.IsEmpty()); if (!supports_npot) return gfx::Size(NextPowerOfTwo(bitmap_size.width()), @@ -139,15 +145,15 @@ read_in_progress_(false), cache_(default_cache_size), approximation_cache_(approximation_cache_size), - ui_resource_provider_(NULL), + ui_resource_provider_(nullptr), weak_factory_(this) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - memory_pressure_.reset(new base::MemoryPressureListener( - base::Bind(&ThumbnailCache::OnMemoryPressure, base::Unretained(this)))); + memory_pressure_ = std::make_unique<base::MemoryPressureListener>( + base::Bind(&ThumbnailCache::OnMemoryPressure, base::Unretained(this))); } ThumbnailCache::~ThumbnailCache() { - SetUIResourceProvider(NULL); + SetUIResourceProvider(nullptr); } void ThumbnailCache::SetUIResourceProvider( @@ -243,13 +249,12 @@ } } - return NULL; + return nullptr; } void ThumbnailCache::InvalidateThumbnailIfChanged(TabId tab_id, const GURL& url) { - ThumbnailMetaDataMap::iterator meta_data_iter = - thumbnail_meta_data_.find(tab_id); + auto meta_data_iter = thumbnail_meta_data_.find(tab_id); if (meta_data_iter == thumbnail_meta_data_.end()) { thumbnail_meta_data_[tab_id] = ThumbnailMetaData(base::Time(), url); } else if (meta_data_iter->second.url() != url) { @@ -275,8 +280,7 @@ bool ThumbnailCache::CheckAndUpdateThumbnailMetaData(TabId tab_id, const GURL& url) { base::Time current_time = base::Time::Now(); - ThumbnailMetaDataMap::iterator meta_data_iter = - thumbnail_meta_data_.find(tab_id); + auto meta_data_iter = thumbnail_meta_data_.find(tab_id); if (meta_data_iter != thumbnail_meta_data_.end() && meta_data_iter->second.url() == url && (current_time - meta_data_iter->second.capture_time()) < @@ -305,8 +309,8 @@ } else { // Early out if called with the same input as last time (We only care // about the first mCache.MaximumCacheSize() entries). - TabIdList::const_iterator visible_iter = visible_ids_.begin(); - TabIdList::const_iterator priority_iter = priority.begin(); + auto visible_iter = visible_ids_.begin(); + auto priority_iter = priority.begin(); while (visible_iter != visible_ids_.end() && priority_iter != priority.end()) { if (*priority_iter != *visible_iter || !cache_.Get(*priority_iter)) { @@ -324,7 +328,7 @@ read_queue_.clear(); visible_ids_.clear(); size_t count = 0; - TabIdList::const_iterator iter = priority.begin(); + auto iter = priority.begin(); while (iter != priority.end() && count < ids_size) { TabId tab_id = *iter; visible_ids_.push_back(tab_id); @@ -470,11 +474,9 @@ bool found_key_to_remove = false; // 1. Find a cached item not in this list - for (ExpiringThumbnailCache::iterator iter = cache_.begin(); - iter != cache_.end(); - iter++) { - if (!base::Contains(visible_ids_, iter->first)) { - key_to_remove = iter->first; + for (auto& item : cache_) { + if (!base::Contains(visible_ids_, item.first)) { + key_to_remove = item.first; found_key_to_remove = true; break; } @@ -498,8 +500,7 @@ } void ThumbnailCache::RemoveFromReadQueue(TabId tab_id) { - TabIdList::iterator read_iter = - std::find(read_queue_.begin(), read_queue_.end(), tab_id); + auto read_iter = std::find(read_queue_.begin(), read_queue_.end(), tab_id); if (read_iter != read_queue_.end()) read_queue_.erase(read_iter); } @@ -561,17 +562,20 @@ return false; // Write ETC1 header. + CHECK(compressed_data->width() >= 0); + CHECK(compressed_data->height() >= 0); + unsigned width = static_cast<unsigned>(compressed_data->width()); + unsigned height = static_cast<unsigned>(compressed_data->height()); + unsigned char etc1_buffer[ETC_PKM_HEADER_SIZE]; - etc1_pkm_format_header(etc1_buffer, compressed_data->width(), - compressed_data->height()); + etc1_pkm_format_header(etc1_buffer, width, height); int header_bytes_written = file.WriteAtCurrentPos( reinterpret_cast<char*>(etc1_buffer), ETC_PKM_HEADER_SIZE); if (header_bytes_written != ETC_PKM_HEADER_SIZE) return false; - int data_size = etc1_get_encoded_data_size(compressed_data->width(), - compressed_data->height()); + int data_size = etc1_get_encoded_data_size(width, height); int pixel_bytes_written = file.WriteAtCurrentPos( reinterpret_cast<char*>(compressed_data->pixels()), data_size); @@ -894,8 +898,7 @@ const gfx::Size& content_size) { read_in_progress_ = false; - TabIdList::iterator iter = - std::find(read_queue_.begin(), read_queue_.end(), tab_id); + auto iter = std::find(read_queue_.begin(), read_queue_.end(), tab_id); if (iter == read_queue_.end()) { ReadNextThumbnail(); return; @@ -904,8 +907,7 @@ read_queue_.erase(iter); if (!cache_.Get(tab_id) && compressed_data) { - ThumbnailMetaDataMap::iterator meta_iter = - thumbnail_meta_data_.find(tab_id); + auto meta_iter = thumbnail_meta_data_.find(tab_id); base::Time time_stamp = base::Time::Now(); if (meta_iter != thumbnail_meta_data_.end()) time_stamp = meta_iter->second.capture_time(); @@ -939,7 +941,6 @@ (approx_thumbnail && approx_thumbnail->time_stamp() == time_stamp)) { Remove(tab_id); } - return; } void ThumbnailCache::DecompressionTask( @@ -951,7 +952,7 @@ SkBitmap raw_data_small; bool success = false; - if (compressed_data.get()) { + if (compressed_data) { gfx::Size buffer_size = gfx::Size(compressed_data->width(), compressed_data->height()); @@ -992,14 +993,10 @@ base::BindOnce(post_decompression_callback, success, raw_data_small)); } -ThumbnailCache::ThumbnailMetaData::ThumbnailMetaData() { -} - ThumbnailCache::ThumbnailMetaData::ThumbnailMetaData( const base::Time& current_time, - const GURL& url) - : capture_time_(current_time), url_(url) { -} + GURL url) + : capture_time_(current_time), url_(std::move(url)) {} std::pair<SkBitmap, float> ThumbnailCache::CreateApproximation( const SkBitmap& bitmap, @@ -1018,7 +1015,7 @@ dst_bitmap.eraseColor(0); SkCanvas canvas(dst_bitmap); canvas.scale(new_scale, new_scale); - canvas.drawBitmap(bitmap, 0, 0, NULL); + canvas.drawBitmap(bitmap, 0, 0, nullptr); dst_bitmap.setImmutable(); return std::make_pair(dst_bitmap, new_scale * scale);
diff --git a/chrome/browser/android/thumbnail/thumbnail_cache.h b/chrome/browser/android/thumbnail/thumbnail_cache.h index 380f0f9..30e516ca 100644 --- a/chrome/browser/android/thumbnail/thumbnail_cache.h +++ b/chrome/browser/android/thumbnail/thumbnail_cache.h
@@ -84,8 +84,8 @@ private: class ThumbnailMetaData { public: - ThumbnailMetaData(); - ThumbnailMetaData(const base::Time& current_time, const GURL& url); + ThumbnailMetaData() = default; + ThumbnailMetaData(const base::Time& current_time, GURL url); const GURL& url() const { return url_; } base::Time capture_time() const { return capture_time_; }
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 5b3b534..b9a6f50 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -5079,24 +5079,46 @@ return interceptors; } -void ChromeContentBrowserClient::WillCreateWebSocket( - content::RenderFrameHost* frame, - network::mojom::WebSocketRequest* request, - network::mojom::AuthenticationHandlerPtr* auth_handler, - network::mojom::TrustedHeaderClientPtr* header_client, - uint32_t* options) { +bool ChromeContentBrowserClient::WillInterceptWebSocket( + content::RenderFrameHost* frame) { #if BUILDFLAG(ENABLE_EXTENSIONS) - auto* web_request_api = + if (!frame) { + return false; + } + const auto* web_request_api = extensions::BrowserContextKeyedAPIFactory<extensions::WebRequestAPI>::Get( frame->GetProcess()->GetBrowserContext()); // NOTE: Some unit test environments do not initialize // BrowserContextKeyedAPI factories for e.g. WebRequest. if (!web_request_api) - return; + return false; - web_request_api->MaybeProxyWebSocket(frame, request, auth_handler, - header_client); + return web_request_api->MayHaveProxies(); +#else + return false; +#endif +} + +void ChromeContentBrowserClient::CreateWebSocket( + content::RenderFrameHost* frame, + WebSocketFactory factory, + const GURL& url, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + network::mojom::WebSocketHandshakeClientPtr handshake_client) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (!frame) { + return; + } + auto* web_request_api = + extensions::BrowserContextKeyedAPIFactory<extensions::WebRequestAPI>::Get( + frame->GetProcess()->GetBrowserContext()); + + DCHECK(web_request_api); + web_request_api->ProxyWebSocket(frame, std::move(factory), url, + site_for_cookies, user_agent, + std::move(handshake_client)); #endif }
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 4cd801e4..3944a88 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -496,12 +496,14 @@ int frame_tree_node_id, const scoped_refptr<network::SharedURLLoaderFactory>& network_loader_factory) override; - void WillCreateWebSocket( + bool WillInterceptWebSocket(content::RenderFrameHost* frame) override; + void CreateWebSocket( content::RenderFrameHost* frame, - network::mojom::WebSocketRequest* request, - network::mojom::AuthenticationHandlerPtr* auth_handler, - network::mojom::TrustedHeaderClientPtr* header_client, - uint32_t* options) override; + WebSocketFactory factory, + const GURL& url, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + network::mojom::WebSocketHandshakeClientPtr handshake_client) override; void OnNetworkServiceCreated( network::mojom::NetworkService* network_service) override; network::mojom::NetworkContextPtr CreateNetworkContext(
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc index c3885c2..e7740c4 100644 --- a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc +++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
@@ -420,6 +420,36 @@ << message_; } +IN_PROC_BROWSER_TEST_F(FileManagerPrivateApiTest, FormatVolume) { + // Catch-all rule to ensure that FormatMountedDevice does not get called with + // other arguments that don't match the rules below. + EXPECT_CALL(*disk_mount_manager_mock_, FormatMountedDevice(_, _, _)).Times(0); + + EXPECT_CALL(*disk_mount_manager_mock_, + FormatMountedDevice( + chromeos::CrosDisksClient::GetRemovableDiskMountPoint() + .AppendASCII("mount_path1") + .AsUTF8Unsafe(), + "vfat", "NEWLABEL1")) + .Times(1); + EXPECT_CALL(*disk_mount_manager_mock_, + FormatMountedDevice( + chromeos::CrosDisksClient::GetRemovableDiskMountPoint() + .AppendASCII("mount_path2") + .AsUTF8Unsafe(), + "exfat", "NEWLABEL2")) + .Times(1); + EXPECT_CALL(*disk_mount_manager_mock_, + FormatMountedDevice( + chromeos::CrosDisksClient::GetRemovableDiskMountPoint() + .AppendASCII("mount_path3") + .AsUTF8Unsafe(), + "ntfs", "NEWLABEL3")) + .Times(1); + + ASSERT_TRUE(RunComponentExtensionTest("file_browser/format_test")); +} + IN_PROC_BROWSER_TEST_F(FileManagerPrivateApiTest, Permissions) { EXPECT_TRUE( RunExtensionTestIgnoreManifestWarnings("file_browser/permissions"));
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index f74b92c..371bd94 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -611,6 +611,7 @@ #endif TestCase("dirContextMenuRecent"), TestCase("dirContextMenuMyFiles").EnableMyFilesVolume(), + TestCase("dirContextMenuMyFilesWithPaste").EnableMyFilesVolume(), TestCase("dirContextMenuCrostini"), TestCase("dirContextMenuPlayFiles"), TestCase("dirContextMenuUsbs"),
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index 5db8229..8144d9e 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -100,7 +100,6 @@ ::switches::kDisablePartialRaster, ::switches::kDisablePepper3DImageChromium, ::switches::kDisablePreferCompositingToLCDText, - ::switches::kDisablePanelFitting, ::switches::kDisableRGBA4444Textures, ::switches::kDisableThreadedScrolling, ::switches::kDisableTouchDragDrop,
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc index 8556059e..5be3239e 100644 --- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -90,6 +90,7 @@ #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.h" +#include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/grit/chromium_strings.h" @@ -2799,4 +2800,19 @@ TermsOfServiceDownloadTest, testing::Bool()); +IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, WebAppsInPublicSession) { + UploadAndInstallDeviceLocalAccountPolicy(); + // Add an account with DeviceLocalAccount::Type::TYPE_PUBLIC_SESSION. + AddPublicSessionToDevicePolicy(kAccountId1); + WaitForPolicy(); + + StartLogin(std::string(), std::string()); + WaitForSessionStart(); + + // WebAppProvider should be enabled for TYPE_PUBLIC_SESSION user account. + Profile* profile = GetProfileForTest(); + ASSERT_TRUE(profile); + EXPECT_TRUE(web_app::WebAppProvider::Get(profile)); +} + } // namespace policy
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc index 3c5f8c1..fc4a9d6 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -1471,31 +1471,6 @@ << message_; } -// Tests the WebRequestProxyingWebSocket does not crash when there is a -// connection error before AddChannelRequest is called. Regression test for -// http://crbug.com/878574. -IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, - WebSocketConnectionErrorBeforeChannelRequest) { - InstallWebRequestExtension("extension"); - - network::mojom::WebSocketPtr web_socket; - network::mojom::WebSocketRequest request = mojo::MakeRequest(&web_socket); - network::mojom::AuthenticationHandlerPtr auth_handler; - content::RenderFrameHost* host = - browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(); - extensions::BrowserContextKeyedAPIFactory<extensions::WebRequestAPI>::Get( - profile()) - ->MaybeProxyWebSocket(host, &request, &auth_handler, nullptr); - content::BrowserContext::GetDefaultStoragePartition(profile()) - ->GetNetworkContext() - ->CreateWebSocket(std::move(request), network::mojom::kBrowserProcessId, - host->GetProcess()->GetID(), - url::Origin::Create(GURL("http://example.com")), - network::mojom::kWebSocketOptionNone, - std::move(auth_handler), nullptr); - web_socket.reset(); -} - // Tests that a clean close from the server is not reported as an error when // there is a race between OnDropChannel and SendFrame. // Regression test for https://crbug.com/937790.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 852f5032..80a2ac8 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -98,6 +98,11 @@ "expiry_milestone": 76 }, { + "name": "animated-avatar-button", + "owners": ["jkrcal"], + "expiry_milestone": 78 + }, + { "name": "app-management", "owners": [ "//chrome/browser/resources/app_management/OWNERS" ], "expiry_milestone": 76
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index e0d0421..8173a1a 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3418,6 +3418,11 @@ const char kDirectManipulationStylusDescription[] = "If enabled, Chrome will scroll web pages on stylus drag."; +const char kAnimatedAvatarButtonName[] = "Animated avatar button"; +const char kAnimatedAvatarButtonDescription[] = + "If enabled, Chrome will animate a pill with identity information around " + "the avatar button on start-up and on sign-in."; + #endif // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) #if defined(OS_MACOSX) || defined(OS_CHROMEOS)
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index dfc10c5..8658045 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2059,6 +2059,9 @@ extern const char kDirectManipulationStylusName[]; extern const char kDirectManipulationStylusDescription[]; +extern const char kAnimatedAvatarButtonName[]; +extern const char kAnimatedAvatarButtonDescription[]; + #endif // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) #if defined(OS_MACOSX) || defined(OS_CHROMEOS)
diff --git a/chrome/browser/performance_manager/observers/working_set_trimmer_win.cc b/chrome/browser/performance_manager/observers/working_set_trimmer_win.cc index 4420ca86..112443f 100644 --- a/chrome/browser/performance_manager/observers/working_set_trimmer_win.cc +++ b/chrome/browser/performance_manager/observers/working_set_trimmer_win.cc
@@ -46,15 +46,26 @@ WorkingSetTrimmer::WorkingSetTrimmer() = default; WorkingSetTrimmer::~WorkingSetTrimmer() = default; -bool WorkingSetTrimmer::ShouldObserve(const NodeBase* node) { - return node->type() == ProcessNodeImpl::Type(); +void WorkingSetTrimmer::OnPassedToGraph(Graph* graph) { + RegisterObservers(graph); +} + +void WorkingSetTrimmer::OnTakenFromGraph(Graph* graph) { + UnregisterObservers(graph); } void WorkingSetTrimmer::OnAllFramesInProcessFrozen( - ProcessNodeImpl* process_node) { - if (process_node->process().IsValid()) { - EmptyWorkingSet(process_node->process(), process_node->launch_time()); - } + const ProcessNode* process_node) { + if (process_node->GetProcess().IsValid()) + EmptyWorkingSet(process_node->GetProcess(), process_node->GetLaunchTime()); +} + +void WorkingSetTrimmer::RegisterObservers(Graph* graph) { + graph->AddProcessNodeObserver(this); +} + +void WorkingSetTrimmer::UnregisterObservers(Graph* graph) { + graph->RemoveProcessNodeObserver(this); } } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/observers/working_set_trimmer_win.h b/chrome/browser/performance_manager/observers/working_set_trimmer_win.h index 092a881..a6332ff 100644 --- a/chrome/browser/performance_manager/observers/working_set_trimmer_win.h +++ b/chrome/browser/performance_manager/observers/working_set_trimmer_win.h
@@ -6,7 +6,8 @@ #define CHROME_BROWSER_PERFORMANCE_MANAGER_OBSERVERS_WORKING_SET_TRIMMER_WIN_H_ #include "base/macros.h" -#include "chrome/browser/performance_manager/observers/graph_observer.h" +#include "chrome/browser/performance_manager/public/graph/graph.h" +#include "chrome/browser/performance_manager/public/graph/process_node.h" namespace performance_manager { @@ -26,14 +27,25 @@ // to be compressed and/or written to disk preemptively, which makes more // memory available quickly for foreground processes and improves global // browser performance. -class WorkingSetTrimmer : public GraphImplObserverDefaultImpl { +class WorkingSetTrimmer : public GraphOwned, + public ProcessNode::ObserverDefaultImpl { public: WorkingSetTrimmer(); ~WorkingSetTrimmer() override; - // GraphObserver: - bool ShouldObserve(const NodeBase* node) override; - void OnAllFramesInProcessFrozen(ProcessNodeImpl* process_node) override; + // GraphOwned implementation: + void OnPassedToGraph(Graph* graph) override; + void OnTakenFromGraph(Graph* graph) override; + + // ProcessNodeObserver: + void OnAllFramesInProcessFrozen(const ProcessNode* process_node) override; + + protected: + // (Un)registers the various node observer flavors of this object with the + // graph. These are invoked by OnPassedToGraph and OnTakenFromGraph, but + // hoisted to their own functions for testing. + void RegisterObservers(Graph* graph); + void UnregisterObservers(Graph* graph); private: DISALLOW_COPY_AND_ASSIGN(WorkingSetTrimmer);
diff --git a/chrome/browser/performance_manager/performance_manager.cc b/chrome/browser/performance_manager/performance_manager.cc index 3faf462..339a3ac 100644 --- a/chrome/browser/performance_manager/performance_manager.cc +++ b/chrome/browser/performance_manager/performance_manager.cc
@@ -273,7 +273,7 @@ #if defined(OS_WIN) if (base::FeatureList::IsEnabled(features::kEmptyWorkingSet)) - RegisterObserver(std::make_unique<WorkingSetTrimmer>()); + graph_.PassToGraph(std::make_unique<WorkingSetTrimmer>()); #endif interface_registry_.AddInterface(base::BindRepeating(
diff --git a/chrome/browser/resources/chromeos/camera/src/css/main.css b/chrome/browser/resources/chromeos/camera/src/css/main.css index 894695b..e0335ab 100644 --- a/chrome/browser/resources/chromeos/camera/src/css/main.css +++ b/chrome/browser/resources/chromeos/camera/src/css/main.css
@@ -406,7 +406,8 @@ #options-group { --option-item-vpadding: 12px; - bottom: calc(var(--bottom-line) + (var(--big-icon) / 2) + 32px - var(--option-item-vpadding)); + --switch-device-gap: 32px; + bottom: calc(var(--bottom-line) + (var(--big-icon) / 2) + var(--switch-device-gap) - var(--option-item-vpadding)); flex-direction: column-reverse; } @@ -414,6 +415,11 @@ bottom: calc(var(--bottom-line) - var(--option-item-vpadding) - (var(--small-icon) / 2)); } +body.max-wnd #options-group { + --option-item-vpadding: 18px; + --switch-device-gap: 48px; +} + #options-group input { margin: var(--option-item-vpadding) 0; } @@ -550,6 +556,10 @@ --small-icon: 40px; } +body.max-wnd #camera { + --bottom-line: 56px; +} + @media screen and (min-height: 800px) { #camera { --modes-height: calc(var(--mode-item-height) * 4 + var(--modes-gradient-padding) * 2);
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera/constraints_preferrer.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera/constraints_preferrer.js index 0d22ee0e..ca1ae2be 100644 --- a/chrome/browser/resources/chromeos/camera/src/js/views/camera/constraints_preferrer.js +++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera/constraints_preferrer.js
@@ -353,7 +353,7 @@ }, }); - return this.deviceResolutions_[deviceId] + return [...this.deviceResolutions_[deviceId]] .sort(sortPrefResol) .flatMap(getFpses) .map(([width, height, fps]) => ([ @@ -493,7 +493,8 @@ (captureR, r) => (r[0] > captureR[0] ? r : captureR), [0, -1]); } - const candidates = previewRs.sort(([w, h], [w2, h2]) => w2 - w) + const candidates = [...previewRs] + .sort(([w, h], [w2, h2]) => w2 - w) .map(([width, height]) => ({ audio: false, video: {
diff --git a/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html b/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html index 6f118634..6636a96 100644 --- a/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html +++ b/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.html
@@ -4,6 +4,7 @@ <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> @@ -20,14 +21,19 @@ width: 500px; } - .fingerprint-scanner-tablet { + .fingerprint-scanner-tablet-power-button { background: - url(chrome://theme/IDR_LOGIN_FINGERPRINT_SCANNER_TABLET_ANIMATION); + url(chrome://theme/IDR_LOGIN_FINGERPRINT_SCANNER_TABLET_POWER_BUTTON_ANIMATION); } - .fingerprint-scanner-laptop { + .fingerprint-scanner-laptop-bottom-right { background: - url(chrome://theme/IDR_LOGIN_FINGERPRINT_SCANNER_LAPTOP_ANIMATION); + url(chrome://theme/IDR_LOGIN_FINGERPRINT_SCANNER_LAPTOP_BOTTOM_RIGHT_ANIMATION); + } + + .fingerprint-scanner-laptop-top-right { + background: + url(chrome://theme/IDR_LOGIN_FINGERPRINT_SCANNER_LAPTOP_TOP_RIGHT_ANIMATION); } #scannerLocation { @@ -62,7 +68,7 @@ <span>[[getInstructionMessage_(step_, problemMessage_)]]</span> </div> <div id="scannerLocation" hidden="[[!showScannerLocation_(step_)]]" - class$="[[getFingerprintScannerAnimationClass_()]]" + class$="[[fingerprintScannerAnimationClass_]]" aria-label="$i18n{configureFingerprintScannerStepAriaLabel}" aria-live="polite" > </div>
diff --git a/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.js b/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.js index 2f770c9..5716825 100644 --- a/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.js +++ b/chrome/browser/resources/settings/people_page/setup_fingerprint_dialog.js
@@ -14,6 +14,18 @@ READY: 3 // The scanner has read the fingerprint successfully. }; +/** + * Fingerprint sensor locations corresponding to the FingerprintLocation + * enumerators in + * /chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h + * @enum {number} + */ +settings.FingerprintLocation = { + TABLET_POWER_BUTTON: 0, + KEYBOARD_TOP_RIGHT: 1, + KEYBOARD_BOTTOM_RIGHT: 2, +}; + (function() { /** @@ -74,6 +86,31 @@ value: 0, observer: 'onProgressChanged_', }, + + /** + * This is used to display right animation for fingerprint sensor. + * @private {string} + */ + fingerprintScannerAnimationClass_: { + type: String, + value: function() { + if (!loadTimeData.getBoolean('fingerprintUnlockEnabled')) { + return ''; + } + const fingerprintLocation = + loadTimeData.getInteger('fingerprintReaderLocation'); + switch (fingerprintLocation) { + case settings.FingerprintLocation.TABLET_POWER_BUTTON: + return 'fingerprint-scanner-tablet-power-button'; + case settings.FingerprintLocation.KEYBOARD_TOP_RIGHT: + return 'fingerprint-scanner-laptop-top-right'; + case settings.FingerprintLocation.KEYBOARD_BOTTOM_RIGHT: + return 'fingerprint-scanner-laptop-bottom-right'; + } + assertNotReached(); + }, + readOnly: true, + }, }, /** @@ -308,16 +345,5 @@ this.$.arc.setProgress(oldValue, newValue, newValue === 100); }, - /** - * Returns the class name for fingerprint scanner animation. - * @private - */ - getFingerprintScannerAnimationClass_: function() { - if (loadTimeData.getBoolean('fingerprintUnlockEnabled') && - loadTimeData.getBoolean('isFingerprintReaderOnKeyboard')) { - return 'fingerprint-scanner-laptop'; - } - return 'fingerprint-scanner-tablet'; - }, }); })();
diff --git a/chrome/browser/search/chrome_colors/chrome_colors_service.cc b/chrome/browser/search/chrome_colors/chrome_colors_service.cc index c889004..f5ad71b 100644 --- a/chrome/browser/search/chrome_colors/chrome_colors_service.cc +++ b/chrome/browser/search/chrome_colors/chrome_colors_service.cc
@@ -13,40 +13,27 @@ ChromeColorsService::~ChromeColorsService() = default; -void ChromeColorsService::ApplyDefaultTheme(content::WebContents* tab) { - SaveThemeRevertState(tab); +void ChromeColorsService::ApplyDefaultTheme() { + if (revert_theme_changes_.is_null()) + revert_theme_changes_ = theme_service_->GetRevertThemeCallback(); theme_service_->UseDefaultTheme(); } -void ChromeColorsService::ApplyAutogeneratedTheme(SkColor color, - content::WebContents* tab) { - SaveThemeRevertState(tab); +void ChromeColorsService::ApplyAutogeneratedTheme(SkColor color) { + if (revert_theme_changes_.is_null()) + revert_theme_changes_ = theme_service_->GetRevertThemeCallback(); theme_service_->BuildFromColor(color); } -void ChromeColorsService::RevertThemeChangesForTab(content::WebContents* tab) { - if (dialog_tab_ == tab) - RevertThemeChanges(); -} - void ChromeColorsService::RevertThemeChanges() { if (!revert_theme_changes_.is_null()) { std::move(revert_theme_changes_).Run(); - ConfirmThemeChanges(); + revert_theme_changes_.Reset(); } } void ChromeColorsService::ConfirmThemeChanges() { revert_theme_changes_.Reset(); - dialog_tab_ = nullptr; -} - -void ChromeColorsService::SaveThemeRevertState(content::WebContents* tab) { - // TODO(crbug.com/980745): Support theme reverting for multiple tabs. - if (revert_theme_changes_.is_null()) { - revert_theme_changes_ = theme_service_->GetRevertThemeCallback(); - dialog_tab_ = tab; - } } void ChromeColorsService::Shutdown() {}
diff --git a/chrome/browser/search/chrome_colors/chrome_colors_service.h b/chrome/browser/search/chrome_colors/chrome_colors_service.h index 55c71a4..8fb73d9 100644 --- a/chrome/browser/search/chrome_colors/chrome_colors_service.h +++ b/chrome/browser/search/chrome_colors/chrome_colors_service.h
@@ -8,7 +8,6 @@ #include "base/callback.h" #include "chrome/browser/themes/theme_service.h" #include "components/keyed_service/core/keyed_service.h" -#include "content/public/browser/web_contents.h" #include "third_party/skia/include/core/SkColor.h" class TestChromeColorsService; @@ -24,18 +23,14 @@ explicit ChromeColorsService(Profile* profile); ~ChromeColorsService() override; - // Applies a theme that can be reverted by saving the previous theme state and - // the |tab| that changes are made from. - void ApplyDefaultTheme(content::WebContents* tab); - void ApplyAutogeneratedTheme(SkColor color, content::WebContents* tab); + // Applies a theme that can be reverted. Saves the previous theme state if + // needed. + void ApplyDefaultTheme(); + void ApplyAutogeneratedTheme(SkColor color); - // Reverts to the previous theme state before first Apply* was used. + // Reverts to the previous theme state before Apply* was used. void RevertThemeChanges(); - // Same as |RevertThemeChanges| but only reverts theme changes if they were - // made from the same tab. Used for reverting changes from a closing NTP. - void RevertThemeChangesForTab(content::WebContents* tab); - // Confirms current theme changes. Since the theme is already installed by // Apply*, this only clears the previously saved state. void ConfirmThemeChanges(); @@ -43,23 +38,14 @@ private: friend class ::TestChromeColorsService; - // Saves the necessary state(revert callback and the current tab) for - // performing theme change revert. Saves the state only if it is not set. - void SaveThemeRevertState(content::WebContents* tab); - // KeyedService implementation: void Shutdown() override; ThemeService* const theme_service_; - // The first tab that used Apply* and hasn't Confirm/Revert the changes. - content::WebContents* dialog_tab_ = nullptr; - // Callback that will revert the theme to the state it was at the time of this // callback's creation. base::OnceClosure revert_theme_changes_; - - DISALLOW_COPY_AND_ASSIGN(ChromeColorsService); }; } // namespace chrome_colors
diff --git a/chrome/browser/search/chrome_colors/chrome_colors_service_unittest.cc b/chrome/browser/search/chrome_colors/chrome_colors_service_unittest.cc index 8e8ec3e4c..5043a01 100644 --- a/chrome/browser/search/chrome_colors/chrome_colors_service_unittest.cc +++ b/chrome/browser/search/chrome_colors/chrome_colors_service_unittest.cc
@@ -7,7 +7,6 @@ #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/themes/theme_service_factory.h" #include "chrome/test/base/browser_with_test_window_test.h" -#include "content/public/test/web_contents_tester.h" #include "testing/gtest/include/gtest/gtest.h" class TestChromeColorsService : public BrowserWithTestWindowTest { @@ -18,9 +17,6 @@ BrowserWithTestWindowTest::SetUp(); chrome_colors_service_ = chrome_colors::ChromeColorsFactory::GetForProfile(profile()); - - tab_ = content::WebContentsTester::CreateTestWebContents(profile(), nullptr) - .get(); } bool HasThemeRevertCallback() { @@ -28,7 +24,6 @@ } chrome_colors::ChromeColorsService* chrome_colors_service_; - content::WebContents* tab_; }; TEST_F(TestChromeColorsService, ApplyAndConfirmAutogeneratedTheme) { @@ -36,12 +31,12 @@ ASSERT_TRUE(theme_service->UsingDefaultTheme()); SkColor theme_color1 = SkColorSetRGB(100, 0, 200); - chrome_colors_service_->ApplyAutogeneratedTheme(theme_color1, tab_); + chrome_colors_service_->ApplyAutogeneratedTheme(theme_color1); EXPECT_TRUE(theme_service->UsingAutogenerated()); EXPECT_TRUE(HasThemeRevertCallback()); SkColor theme_color2 = SkColorSetRGB(100, 0, 200); - chrome_colors_service_->ApplyAutogeneratedTheme(theme_color2, tab_); + chrome_colors_service_->ApplyAutogeneratedTheme(theme_color2); EXPECT_TRUE(theme_service->UsingAutogenerated()); EXPECT_TRUE(HasThemeRevertCallback()); @@ -57,12 +52,12 @@ ASSERT_TRUE(theme_service->UsingDefaultTheme()); SkColor theme_color1 = SkColorSetRGB(100, 0, 200); - chrome_colors_service_->ApplyAutogeneratedTheme(theme_color1, tab_); + chrome_colors_service_->ApplyAutogeneratedTheme(theme_color1); EXPECT_TRUE(theme_service->UsingAutogenerated()); EXPECT_TRUE(HasThemeRevertCallback()); SkColor theme_color2 = SkColorSetRGB(100, 0, 200); - chrome_colors_service_->ApplyAutogeneratedTheme(theme_color2, tab_); + chrome_colors_service_->ApplyAutogeneratedTheme(theme_color2); EXPECT_TRUE(theme_service->UsingAutogenerated()); EXPECT_TRUE(HasThemeRevertCallback()); @@ -80,7 +75,7 @@ ASSERT_EQ(prev_theme_color, theme_service->GetThemeColor()); SkColor new_theme_color = SkColorSetRGB(100, 0, 200); - chrome_colors_service_->ApplyAutogeneratedTheme(new_theme_color, tab_); + chrome_colors_service_->ApplyAutogeneratedTheme(new_theme_color); EXPECT_EQ(new_theme_color, theme_service->GetThemeColor()); EXPECT_TRUE(HasThemeRevertCallback()); @@ -98,7 +93,7 @@ ASSERT_EQ(prev_theme_color, theme_service->GetThemeColor()); SkColor new_theme_color = SkColorSetRGB(100, 0, 200); - chrome_colors_service_->ApplyAutogeneratedTheme(new_theme_color, tab_); + chrome_colors_service_->ApplyAutogeneratedTheme(new_theme_color); EXPECT_EQ(new_theme_color, theme_service->GetThemeColor()); EXPECT_TRUE(HasThemeRevertCallback()); @@ -115,7 +110,7 @@ ASSERT_EQ(prev_theme_color, theme_service->GetThemeColor()); ASSERT_FALSE(theme_service->UsingDefaultTheme()); - chrome_colors_service_->ApplyDefaultTheme(tab_); + chrome_colors_service_->ApplyDefaultTheme(); EXPECT_TRUE(theme_service->UsingDefaultTheme()); EXPECT_TRUE(HasThemeRevertCallback()); @@ -132,7 +127,7 @@ ASSERT_EQ(prev_theme_color, theme_service->GetThemeColor()); ASSERT_FALSE(theme_service->UsingDefaultTheme()); - chrome_colors_service_->ApplyDefaultTheme(tab_); + chrome_colors_service_->ApplyDefaultTheme(); EXPECT_TRUE(theme_service->UsingDefaultTheme()); EXPECT_TRUE(HasThemeRevertCallback()); @@ -141,28 +136,3 @@ EXPECT_EQ(prev_theme_color, theme_service->GetThemeColor()); EXPECT_FALSE(HasThemeRevertCallback()); } - -TEST_F(TestChromeColorsService, RevertThemeChangesForTab) { - ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile()); - ASSERT_TRUE(theme_service->UsingDefaultTheme()); - - SkColor theme_color1 = SkColorSetRGB(100, 0, 200); - chrome_colors_service_->ApplyAutogeneratedTheme(theme_color1, tab_); - EXPECT_TRUE(theme_service->UsingAutogenerated()); - EXPECT_TRUE(HasThemeRevertCallback()); - - chrome_colors_service_->RevertThemeChangesForTab(nullptr); - EXPECT_TRUE(theme_service->UsingAutogenerated()); - EXPECT_TRUE(HasThemeRevertCallback()); - - AddTab(browser(), GURL("chrome://newtab")); - content::WebContents* new_tab = - browser()->tab_strip_model()->GetActiveWebContents(); - chrome_colors_service_->RevertThemeChangesForTab(new_tab); - EXPECT_TRUE(theme_service->UsingAutogenerated()); - EXPECT_TRUE(HasThemeRevertCallback()); - - chrome_colors_service_->RevertThemeChangesForTab(tab_); - EXPECT_FALSE(theme_service->UsingAutogenerated()); - EXPECT_FALSE(HasThemeRevertCallback()); -}
diff --git a/chrome/browser/ui/ash/launcher_page_switches_interactive_uitest.cc b/chrome/browser/ui/ash/launcher_page_switches_interactive_uitest.cc index bf8f784..c1f51b4 100644 --- a/chrome/browser/ui/ash/launcher_page_switches_interactive_uitest.cc +++ b/chrome/browser/ui/ash/launcher_page_switches_interactive_uitest.cc
@@ -8,6 +8,7 @@ #include "ash/public/cpp/test/shell_test_api.h" #include "base/run_loop.h" #include "base/task/post_task.h" +#include "build/build_config.h" #include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" @@ -91,7 +92,13 @@ DISALLOW_COPY_AND_ASSIGN(LauncherPageSwitchesTest); }; -IN_PROC_BROWSER_TEST_P(LauncherPageSwitchesTest, SwitchToNextPage) { +// Flaky on CrOS. See https://crbug.com/981281 +#if defined(OS_CHROMEOS) +#define MAYBE_SwitchToNextPage DISABLED_SwitchToNextPage +#else +#define MAYBE_SwitchToNextPage SwitchToNextPage +#endif +IN_PROC_BROWSER_TEST_P(LauncherPageSwitchesTest, MAYBE_SwitchToNextPage) { ash::PaginationModel* model = ash::ShellTestApi().GetAppListPaginationModel(); ASSERT_TRUE(model); EXPECT_LT(1, model->total_pages()); @@ -102,7 +109,13 @@ waiter.Wait(); } -IN_PROC_BROWSER_TEST_P(LauncherPageSwitchesTest, SwitchToFarPage) { +// Flaky on CrOS. See https://crbug.com/981281 +#if defined(OS_CHROMEOS) +#define MAYBE_SwitchToFarPage DISABLED_SwitchToFarPage +#else +#define MAYBE_SwitchToFarPage SwitchToFarPage +#endif +IN_PROC_BROWSER_TEST_P(LauncherPageSwitchesTest, MAYBE_SwitchToFarPage) { ash::PaginationModel* model = ash::ShellTestApi().GetAppListPaginationModel(); ASSERT_TRUE(model); EXPECT_LT(2, model->total_pages());
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 0b29860..95dbd565 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -2095,7 +2095,6 @@ chrome::NOTIFICATION_TAB_CLOSING, content::Source<NavigationController>(&contents->GetController()), content::NotificationService::NoDetails()); - SearchTabHelper::FromWebContents(contents)->OnTabClosing(); } void Browser::OnTabDetached(WebContents* contents, bool was_active) {
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index efa3a605..e69aec4 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc
@@ -82,6 +82,7 @@ #include "components/sessions/core/base_session_service_test_helper.h" #include "components/translate/core/browser/language_state.h" #include "components/translate/core/common/language_detection_details.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/interstitial_page.h" @@ -102,6 +103,7 @@ #include "content/public/common/frame_navigate_params.h" #include "content/public/common/url_constants.h" #include "content/public/test/browser_test_utils.h" +#include "content/public/test/download_test_observer.h" #include "content/public/test/test_navigation_observer.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" @@ -630,6 +632,84 @@ EXPECT_FALSE(contents->GetMainFrame()->GetProcess()->IsBlocked()); } +// Similar to CrossProcessNavCancelsDialogs, with a renderer-initiated main +// frame navigation with user gesture. +IN_PROC_BROWSER_TEST_F(BrowserTest, RendererCrossProcessNavCancelsDialogs) { + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url(embedded_test_server()->GetURL("/empty.html")); + ui_test_utils::NavigateToURL(browser(), url); + WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); + + // A cross-site renderer-initiated navigation with user gesture (started + // before the dialog is shown) should force the dialog to close. (ExecJS sends + // a user gesture by default.) + GURL url2("http://www.example.com/empty.html"); + content::TestNavigationManager manager(contents, url2); + EXPECT_TRUE(content::ExecJs(contents, "location = '" + url2.spec() + "';")); + EXPECT_TRUE(manager.WaitForRequestStart()); + + JavaScriptDialogTabHelper* js_helper = + JavaScriptDialogTabHelper::FromWebContents(contents); + base::RunLoop dialog_wait; + js_helper->SetDialogShownCallbackForTesting(dialog_wait.QuitClosure()); + content::ExecuteScriptAsync(contents, "alert('dialog')"); + dialog_wait.Run(); + EXPECT_TRUE(js_helper->IsShowingDialogForTesting()); + + // Let the navigation to url2 finish and dismiss the dialog. + manager.WaitForNavigationFinished(); + EXPECT_FALSE(js_helper->IsShowingDialogForTesting()); + + // Make sure input events still work in the renderer process. + EXPECT_FALSE(contents->GetMainFrame()->GetProcess()->IsBlocked()); +} + +// Ensures that a download can complete while a dialog is showing, because it +// poses no risk of dismissing the dialog. +IN_PROC_BROWSER_TEST_F(BrowserTest, DownloadDoesntDismissDialog) { + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url(embedded_test_server()->GetURL("/empty.html")); + ui_test_utils::NavigateToURL(browser(), url); + WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); + + // A renderer-initiated navigation without a user gesture would normally be + // deferred until the dialog is dismissed. If the navigation turns out to be + // a download at response time (e.g., because download-test3.gif has a + // Content-Disposition: attachment response header), then the download should + // not be deferred or dismiss the dialog. + std::unique_ptr<content::DownloadTestObserver> download_waiter( + new content::DownloadTestObserverTerminal( + content::BrowserContext::GetDownloadManager(browser()->profile()), 1, + content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL)); + GURL url2(embedded_test_server()->GetURL("/download-test3.gif")); + content::TestNavigationManager manager(contents, url2); + EXPECT_TRUE(content::ExecJs(contents, "location = '" + url2.spec() + "';", + content::EXECUTE_SCRIPT_NO_USER_GESTURE)); + EXPECT_TRUE(manager.WaitForRequestStart()); + + // Show a dialog while we're waiting for the url2 response. + JavaScriptDialogTabHelper* js_helper = + JavaScriptDialogTabHelper::FromWebContents(contents); + base::RunLoop dialog_wait; + js_helper->SetDialogShownCallbackForTesting(dialog_wait.QuitClosure()); + content::ExecuteScriptAsync(contents, "alert('dialog')"); + dialog_wait.Run(); + EXPECT_TRUE(js_helper->IsShowingDialogForTesting()); + + // Let the url2 response finish and become a download, without dismissing the + // dialog. + manager.WaitForNavigationFinished(); + EXPECT_TRUE(js_helper->IsShowingDialogForTesting()); + download_waiter->WaitForFinished(); + + // Close the dialog after the download finishes, to clean up. + js_helper->ClickDialogButtonForTesting(true, base::string16()); + EXPECT_FALSE(js_helper->IsShowingDialogForTesting()); + + // Make sure input events still work in the renderer process. + EXPECT_FALSE(contents->GetMainFrame()->GetProcess()->IsBlocked()); +} + // Make sure that dialogs are closed after a renderer process dies, and that // subsequent navigations work. See http://crbug/com/343265. IN_PROC_BROWSER_TEST_F(BrowserTest, SadTabCancelsDialogs) {
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc index eeeca342..70317af6 100644 --- a/chrome/browser/ui/search/search_tab_helper.cc +++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -153,11 +153,6 @@ ipc_router_.OnTabDeactivated(); } -void SearchTabHelper::OnTabClosing() { - if (search::IsInstantNTP(web_contents_) && chrome_colors_service_) - chrome_colors_service_->RevertThemeChangesForTab(web_contents_); -} - void SearchTabHelper::DidStartNavigation( content::NavigationHandle* navigation_handle) { if (!navigation_handle->IsInMainFrame() || @@ -482,12 +477,12 @@ void SearchTabHelper::OnApplyDefaultTheme() { if (chrome_colors_service_) - chrome_colors_service_->ApplyDefaultTheme(web_contents_); + chrome_colors_service_->ApplyDefaultTheme(); } void SearchTabHelper::OnApplyAutogeneratedTheme(SkColor color) { if (chrome_colors_service_) - chrome_colors_service_->ApplyAutogeneratedTheme(color, web_contents_); + chrome_colors_service_->ApplyAutogeneratedTheme(color); } void SearchTabHelper::OnRevertThemeChanges() {
diff --git a/chrome/browser/ui/search/search_tab_helper.h b/chrome/browser/ui/search/search_tab_helper.h index eab7f593..fafc41c 100644 --- a/chrome/browser/ui/search/search_tab_helper.h +++ b/chrome/browser/ui/search/search_tab_helper.h
@@ -65,9 +65,6 @@ // Called when the tab corresponding to |this| instance is deactivated. void OnTabDeactivated(); - // Called when the tab corresponding to |this| instance is closing. - void OnTabClosing(); - SearchIPCRouter& ipc_router_for_testing() { return ipc_router_; } private:
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc index d91eb01..cc1d1440 100644 --- a/chrome/browser/ui/ui_features.cc +++ b/chrome/browser/ui/ui_features.cc
@@ -6,6 +6,11 @@ namespace features { +// Enables an animated avatar button (also called identity pill). See +// https://crbug.com/967317 +const base::Feature kAnimatedAvatarButton{"AnimatedAvatarButton", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables tabs to change pinned state when dragging in the tabstrip. // https://crbug.com/965681 const base::Feature kDragToPinTabs{"DragToPinTabs",
diff --git a/chrome/browser/ui/ui_features.h b/chrome/browser/ui/ui_features.h index 9e062d8..4022c2c 100644 --- a/chrome/browser/ui/ui_features.h +++ b/chrome/browser/ui/ui_features.h
@@ -16,6 +16,8 @@ // All features in alphabetical order. The features should be documented // alongside the definition of their values in the .cc file. +extern const base::Feature kAnimatedAvatarButton; + extern const base::Feature kDragToPinTabs; extern const base::Feature kEvDetailsInPageInfo;
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index 5d8f576a..46efe149 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -85,10 +85,14 @@ void NavigateToGoogleAccountPage(Profile* profile, const std::string& email) { // Create a URL so that the account chooser is shown if the account with - // |email| is not signed into the web. + // |email| is not signed into the web. Include a UTM parameter to signal the + // source of the navigation. + GURL google_account = net::AppendQueryParameter( + GURL(chrome::kGoogleAccountURL), "utm_source", "chrome-profile-chooser"); + GURL url(chrome::kGoogleAccountChooserURL); url = net::AppendQueryParameter(url, "Email", email); - url = net::AppendQueryParameter(url, "continue", chrome::kGoogleAccountURL); + url = net::AppendQueryParameter(url, "continue", google_account.spec()); NavigateParams params(profile, url, ui::PAGE_TRANSITION_LINK); params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc index d95df68..b780e5a 100644 --- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc +++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -183,14 +183,15 @@ int animation_id; switch (quick_unlock::GetFingerprintLocation()) { case quick_unlock::FingerprintLocation::TABLET_POWER_BUTTON: - animation_id = IDR_LOGIN_FINGERPRINT_SCANNER_TABLET_ANIMATION; + animation_id = + IDR_LOGIN_FINGERPRINT_SCANNER_TABLET_POWER_BUTTON_ANIMATION; break; case quick_unlock::FingerprintLocation::KEYBOARD_BOTTOM_RIGHT: - animation_id = IDR_LOGIN_FINGERPRINT_SCANNER_LAPTOP_ANIMATION; + animation_id = + IDR_LOGIN_FINGERPRINT_SCANNER_LAPTOP_BOTTOM_RIGHT_ANIMATION; break; case quick_unlock::FingerprintLocation::KEYBOARD_TOP_RIGHT: - // TODO(rsorokin): Add animation for KEYBOARD_TOP_RIGHT. - animation_id = IDR_LOGIN_FINGERPRINT_SCANNER_LAPTOP_ANIMATION; + animation_id = IDR_LOGIN_FINGERPRINT_SCANNER_LAPTOP_TOP_RIGHT_ANIMATION; break; } source->AddResourcePath("fingerprint_scanner_animation.png", animation_id);
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc index d524540..139f524 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -185,44 +185,6 @@ } } -bool ReportPageCountHistogram(UserActionBuckets user_action, int page_count) { - switch (user_action) { - case PRINT_TO_PRINTER: - UMA_HISTOGRAM_COUNTS_1M("PrintPreview.PageCount.PrintToPrinter", - page_count); - return true; - case PRINT_TO_PDF: - UMA_HISTOGRAM_COUNTS_1M("PrintPreview.PageCount.PrintToPDF", page_count); - return true; - case FALLBACK_TO_ADVANCED_SETTINGS_DIALOG: - UMA_HISTOGRAM_COUNTS_1M("PrintPreview.PageCount.SystemDialog", - page_count); - return true; - case PRINT_WITH_CLOUD_PRINT: - UMA_HISTOGRAM_COUNTS_1M("PrintPreview.PageCount.PrintToCloudPrint", - page_count); - return true; - case PRINT_WITH_PRIVET: - UMA_HISTOGRAM_COUNTS_1M("PrintPreview.PageCount.PrintWithPrivet", - page_count); - return true; - case PRINT_WITH_EXTENSION: - UMA_HISTOGRAM_COUNTS_1M("PrintPreview.PageCount.PrintWithExtension", - page_count); - return true; - case OPEN_IN_MAC_PREVIEW: - UMA_HISTOGRAM_COUNTS_1M("PrintPreview.PageCount.OpenInMacPreview", - page_count); - return true; - case PRINT_TO_GOOGLE_DRIVE: - UMA_HISTOGRAM_COUNTS_1M("PrintPreview.PageCount.PrintToGoogleDrive", - page_count); - return true; - default: - return false; - } -} - PrinterType GetPrinterTypeForUserAction(UserActionBuckets user_action) { switch (user_action) { case PRINT_WITH_PRIVET: @@ -808,10 +770,6 @@ ReportPrintDocumentTypeAndSizeHistograms(doc_type, average_page_size_in_kb); } ReportUserActionHistogram(user_action); - if (!ReportPageCountHistogram(user_action, page_count)) { - NOTREACHED(); - return; - } if (user_action == PRINT_WITH_CLOUD_PRINT || user_action == PRINT_TO_GOOGLE_DRIVE) {
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index ea2cd52c..fc71fe5 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -57,6 +57,7 @@ #include "content/public/common/content_switches.h" #include "device/fido/features.h" #include "media/base/media_switches.h" +#include "net/base/url_util.h" #include "services/device/public/cpp/device_features.h" #include "ui/accessibility/accessibility_switches.h" #include "ui/base/l10n/l10n_util.h" @@ -1336,11 +1337,10 @@ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_TOP_RIGHT_ARIA_LABEL; break; case FingerprintLocation::KEYBOARD_BOTTOM_RIGHT: - // TODO(rsorokin): Add correct strings for KEYBOARD_BOTTOM_RIGHT. instruction_id = IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD; aria_label_id = - IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_TOP_RIGHT_ARIA_LABEL; + IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_RIGHT_ARIA_LABEL; break; } html_source->AddLocalizedString( @@ -2108,7 +2108,13 @@ html_source->AddString("activityControlsUrl", chrome::kGoogleAccountActivityControlsURL); - html_source->AddString("googleAccountUrl", chrome::kGoogleAccountURL); + // Add Google Account URL and include UTM parameter to signal the source of + // the navigation. + html_source->AddString( + "googleAccountUrl", + net::AppendQueryParameter(GURL(chrome::kGoogleAccountURL), "utm_source", + "chrome-settings") + .spec()); html_source->AddBoolean("profileShortcutsEnabled", ProfileShortcutManager::IsFeatureEnabled());
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc index 390e95e..8c2b4d4 100644 --- a/chrome/browser/ui/webui/settings/settings_ui.cc +++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -168,6 +168,7 @@ (profile->IsChild() || !profile->GetProfilePolicyConnector()->IsManaged()); } + #endif // defined(OS_CHROMEOS) } // namespace @@ -477,14 +478,9 @@ html_source->AddBoolean("fingerprintUnlockEnabled", fingerprint_unlock_enabled); if (fingerprint_unlock_enabled) { - using FingerprintLocation = chromeos::quick_unlock::FingerprintLocation; - const FingerprintLocation location = - chromeos::quick_unlock::GetFingerprintLocation(); - // TODO(rsorokin): reevaluate once we have KEYBOARD_TOP_RIGHT animation. - html_source->AddBoolean( - "isFingerprintReaderOnKeyboard", - location == FingerprintLocation::KEYBOARD_BOTTOM_RIGHT || - location == FingerprintLocation::KEYBOARD_TOP_RIGHT); + html_source->AddInteger( + "fingerprintReaderLocation", + static_cast<int32_t>(chromeos::quick_unlock::GetFingerprintLocation())); } html_source->AddBoolean("lockScreenNotificationsEnabled", ash::features::IsLockScreenNotificationsEnabled());
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index a79c0ccd..70e7bb3 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -112,7 +112,6 @@ "web_app_install_manager_unittest.cc", "web_app_install_task_unittest.cc", "web_app_registrar_unittest.cc", - "web_app_utils_unittest.cc", ] deps = [
diff --git a/chrome/browser/web_applications/components/BUILD.gn b/chrome/browser/web_applications/components/BUILD.gn index 031311e..ff23d591 100644 --- a/chrome/browser/web_applications/components/BUILD.gn +++ b/chrome/browser/web_applications/components/BUILD.gn
@@ -82,6 +82,7 @@ "//components/favicon/content", "//components/keyed_service/content", "//components/pref_registry", + "//components/user_manager:user_manager", "//content/public/browser", "//extensions/common:common_constants", "//skia", @@ -100,6 +101,7 @@ "web_app_install_utils_unittest.cc", "web_app_shortcut_mac_unittest.mm", "web_app_shortcut_unittest.cc", + "web_app_utils_unittest.cc", ] if (is_desktop_linux) { @@ -119,6 +121,10 @@ "//testing/gmock", "//testing/gtest", ] + + if (is_chromeos) { + deps += [ "//chrome/browser/chromeos" ] + } } source_set("browser_tests") {
diff --git a/chrome/browser/web_applications/components/web_app_constants.h b/chrome/browser/web_applications/components/web_app_constants.h index 4ceadfc..25ece31 100644 --- a/chrome/browser/web_applications/components/web_app_constants.h +++ b/chrome/browser/web_applications/components/web_app_constants.h
@@ -43,7 +43,9 @@ // Store, where the user still needs to accept the Play installation prompt to // install. kIntentToPlayStore = 11, - kMaxValue = kIntentToPlayStore + // A web app has been disabled by device policy or by other reasons. + kWebAppDisabled = 12, + kMaxValue = kWebAppDisabled }; // Where an app was installed from. This affects what flags will be used when
diff --git a/chrome/browser/web_applications/components/web_app_utils.cc b/chrome/browser/web_applications/components/web_app_utils.cc index 1168114..c52366c 100644 --- a/chrome/browser/web_applications/components/web_app_utils.cc +++ b/chrome/browser/web_applications/components/web_app_utils.cc
@@ -9,6 +9,7 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "components/user_manager/user_manager.h" #endif // OS_CHROMEOS namespace web_app { @@ -32,7 +33,14 @@ chromeos::ProfileHelper::IsLockScreenAppProfile(original_profile)) { return false; } -#endif + // Disable Web Apps if running any kiosk app. + auto* user_manager = user_manager::UserManager::Get(); + if (user_manager && (user_manager->IsLoggedInAsKioskApp() || + user_manager->IsLoggedInAsArcKioskApp())) { + return false; + } +#endif // OS_CHROMEOS + return true; }
diff --git a/chrome/browser/web_applications/web_app_utils_unittest.cc b/chrome/browser/web_applications/components/web_app_utils_unittest.cc similarity index 83% rename from chrome/browser/web_applications/web_app_utils_unittest.cc rename to chrome/browser/web_applications/components/web_app_utils_unittest.cc index a5914b6a..1e305d0 100644 --- a/chrome/browser/web_applications/web_app_utils_unittest.cc +++ b/chrome/browser/web_applications/components/web_app_utils_unittest.cc
@@ -4,16 +4,21 @@ #include "chrome/browser/web_applications/components/web_app_utils.h" +#include <memory> + #include "base/files/file_path.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/test/web_app_test.h" #include "chrome/common/chrome_constants.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile_manager.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/login/users/mock_user_manager.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "components/user_manager/scoped_user_manager.h" #endif // OS_CHROMEOS namespace web_app { @@ -49,6 +54,27 @@ EXPECT_FALSE(AreWebAppsEnabled(lock_screen_profile)); EXPECT_FALSE( AreWebAppsEnabled(lock_screen_profile->GetOffTheRecordProfile())); + + using MockUserManager = testing::NiceMock<chromeos::MockUserManager>; + { + auto user_manager = std::make_unique<MockUserManager>(); + user_manager::ScopedUserManager enabler(std::move(user_manager)); + EXPECT_TRUE(AreWebAppsEnabled(regular_profile)); + } + { + auto user_manager = std::make_unique<MockUserManager>(); + EXPECT_CALL(*user_manager, IsLoggedInAsKioskApp()) + .WillOnce(testing::Return(true)); + user_manager::ScopedUserManager enabler(std::move(user_manager)); + EXPECT_FALSE(AreWebAppsEnabled(regular_profile)); + } + { + auto user_manager = std::make_unique<MockUserManager>(); + EXPECT_CALL(*user_manager, IsLoggedInAsArcKioskApp()) + .WillOnce(testing::Return(true)); + user_manager::ScopedUserManager enabler(std::move(user_manager)); + EXPECT_FALSE(AreWebAppsEnabled(regular_profile)); + } #endif }
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_install_finalizer.cc b/chrome/browser/web_applications/extensions/bookmark_app_install_finalizer.cc index eb4d91e1..cb3371db11 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_install_finalizer.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_install_finalizer.cc
@@ -56,6 +56,12 @@ const Extension* extension = crx_installer->extension(); DCHECK(extension); + if (extension != + GetExtensionById(crx_installer->profile(), extension->id())) { + std::move(callback).Run(web_app::AppId(), + web_app::InstallResultCode::kWebAppDisabled); + return; + } DCHECK_EQ(AppLaunchInfo::GetLaunchWebURL(extension), app_url);
diff --git a/chrome/test/data/extensions/api_test/file_browser/format_test/manifest.json b/chrome/test/data/extensions/api_test/file_browser/format_test/manifest.json new file mode 100644 index 0000000..d86259e --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_browser/format_test/manifest.json
@@ -0,0 +1,15 @@ +{ + // chrome-extension://pkplfbidichfdicaijlchgnapepdginl + "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtDfX9dHNh948bt00YhZBm3P6E5QLaOt+v8kXVtibQfiPtOD2FTScB/f0wX/EQWVO7BkaSOsRkTPcPIgocyMPYr2FLgqGLFlYT9nQpKJZUFNF5oJ5rG6Nv7ppf4zEB3j6da1IBRTz2yOZ+6O1TMZxol/V62/QcqrJeggsHTEPGLdr9Ua4b1Ka0xKJnJngZljsbw93FI1o+P9dAh5BS6wTPiZI/vmJVjvMTkSTnaZ3n9Go2t7A0XLcSxLcVyuLAd2mAvSN0mIviOukdM66wr7llif71nKuUt+4qvlr/r9HfwzN6pA4jkwhtS1UD+3CmB+wsHwsnohNcuu4FIQ6rgq/7QIDAQAB", + "name": "chrome.fileManagerPrivate Format Tests", + "version": "0.1", + "manifest_version": 2, + "description": "Tests of chrome.fileManagerPrivate.FormatVolume", + "background": { + "scripts": ["test.js"] + }, + "permissions": [ + "fileManagerPrivate" + ] +} +
diff --git a/chrome/test/data/extensions/api_test/file_browser/format_test/test.js b/chrome/test/data/extensions/api_test/file_browser/format_test/test.js new file mode 100644 index 0000000..57aae50 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_browser/format_test/test.js
@@ -0,0 +1,30 @@ +// 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. + +const expectedError = 'Error in invocation of fileManagerPrivate.' + + 'formatVolume(string volumeId, fileManagerPrivate.FormatFileSystemType ' + + 'filesystem, string volumeLabel): Error at parameter \'filesystem\': ' + + 'Value must be one of exfat, ntfs, vfat.'; + +chrome.test.runTests([ + function formatVolumes() { + const filesystemType = chrome.fileManagerPrivate.FormatFileSystemType; + chrome.fileManagerPrivate.formatVolume( + 'removable:mount_path1', filesystemType.VFAT, 'NEWLABEL1'); + chrome.fileManagerPrivate.formatVolume( + 'removable:mount_path2', filesystemType.EXFAT, 'NEWLABEL2'); + chrome.fileManagerPrivate.formatVolume( + 'removable:mount_path3', filesystemType.NTFS, 'NEWLABEL3'); + + // Test an unsupported filesystem. + chrome.test.assertThrows( + chrome.fileManagerPrivate.formatVolume, + ['removable:mount_path3', 'invalid-fs', 'NEWLABEL3'], expectedError); + + // This test is also checked on the C++ side, which tests that + // disk_mount_manager.FormatMountedVolume() gets called exactly once for + // each corresponding formatVolume() call. + chrome.test.succeed(); + }, +]);
diff --git a/chromecast/browser/cast_media_blocker.cc b/chromecast/browser/cast_media_blocker.cc index 01b1e50..88880a3d 100644 --- a/chromecast/browser/cast_media_blocker.cc +++ b/chromecast/browser/cast_media_blocker.cc
@@ -28,8 +28,8 @@ controllable_(false), background_video_playback_enabled_(false), media_session_(media_session) { - media_session::mojom::MediaSessionObserverPtr observer; - observer_binding_.Bind(mojo::MakeRequest(&observer)); + mojo::PendingRemote<media_session::mojom::MediaSessionObserver> observer; + observer_binding_.Bind(observer.InitWithNewPipeAndPassReceiver()); media_session_->AddObserver(std::move(observer)); }
diff --git a/chromecast/browser/cast_media_blocker_unittest.cc b/chromecast/browser/cast_media_blocker_unittest.cc index 667fa4c..a948a83f 100644 --- a/chromecast/browser/cast_media_blocker_unittest.cc +++ b/chromecast/browser/cast_media_blocker_unittest.cc
@@ -38,8 +38,9 @@ MOCK_METHOD1(SetDuckingVolumeMultiplier, void(double)); MOCK_METHOD1(DidReceiveAction, void(media_session::mojom::MediaSessionAction)); - MOCK_METHOD1(AddObserver, - void(media_session::mojom::MediaSessionObserverPtr)); + MOCK_METHOD1( + AddObserver, + void(mojo::PendingRemote<media_session::mojom::MediaSessionObserver>)); MOCK_METHOD1(GetMediaSessionInfo, void(GetMediaSessionInfoCallback)); MOCK_METHOD1(GetDebugInfo, void(GetDebugInfoCallback)); MOCK_METHOD0(PreviousTrack, void());
diff --git a/components/omnibox/browser/remote_suggestions_service.cc b/components/omnibox/browser/remote_suggestions_service.cc index 5ad5526..2441a8e 100644 --- a/components/omnibox/browser/remote_suggestions_service.cc +++ b/components/omnibox/browser/remote_suggestions_service.cc
@@ -295,6 +295,13 @@ return; } + // As explained in http://crbug.com/968923, we have seen calls to fetch access + // tokens for cusco-chrome-extension scope even when remote suggestion + // feature was supposed to be disabled. This has caused a server issue for + // GSuite users that were using sync. Adding a DCHECK to make sure that this + // code is indeed never called when the custom endpoint URL is not configured. + DCHECK(!OmniboxFieldTrial::GetOnFocusSuggestionsCustomEndpointURL().empty()); + // Create the oauth2 token fetcher. const identity::ScopeSet scopes{ "https://www.googleapis.com/auth/cusco-chrome-extension"};
diff --git a/components/password_manager/core/browser/votes_uploader.cc b/components/password_manager/core/browser/votes_uploader.cc index 3b2fd59..57cb2289 100644 --- a/components/password_manager/core/browser/votes_uploader.cc +++ b/components/password_manager/core/browser/votes_uploader.cc
@@ -451,19 +451,23 @@ const PasswordForm& pending_credentials, const std::map<base::string16, const PasswordForm*>& best_matches, FormStructure* form) { - DCHECK(!password_overridden_ || - best_matches.find(pending_credentials.username_value) != - best_matches.end()) - << "The credential is being overriden, but it does not exist in " - "the best matches."; - const base::string16& known_username = pending_credentials.username_value; + base::string16 known_password; + if (password_overridden_) { + // If we are updating a password, the known value should be the old + // password, not the new one. + auto it = best_matches.find(known_username); + if (it == best_matches.end()) { + // Username was not found, do nothing. + return; + } + known_password = it->second->password_value; + } else { + known_password = pending_credentials.password_value; + } + // If we are updating a password, the known value is the old password, not // the new one. - const base::string16& known_password = - password_overridden_ ? best_matches.at(known_username)->password_value - : pending_credentials.password_value; - for (auto& field : *form) { if (field->value.empty()) continue;
diff --git a/components/signin/core/browser/BUILD.gn b/components/signin/core/browser/BUILD.gn index b9d99f0..740611a 100644 --- a/components/signin/core/browser/BUILD.gn +++ b/components/signin/core/browser/BUILD.gn
@@ -286,6 +286,7 @@ "oauth_multilogin_helper_unittest.cc", "oauth_multilogin_token_fetcher_unittest.cc", "primary_account_manager_unittest.cc", + "primary_account_policy_manager_impl_unittest.cc", "profile_oauth2_token_service_delegate_chromeos_unittest.cc", "signin_error_controller_unittest.cc", "signin_header_helper_unittest.cc", @@ -321,7 +322,7 @@ if (is_chromeos) { sources -= [ "account_investigator_unittest.cc", - "primary_account_manager_unittest.cc", + "primary_account_policy_manager_impl_unittest.cc", "signin_status_metrics_provider_unittest.cc", ]
diff --git a/components/signin/core/browser/primary_account_manager_unittest.cc b/components/signin/core/browser/primary_account_manager_unittest.cc index 892958e..efc60bf 100644 --- a/components/signin/core/browser/primary_account_manager_unittest.cc +++ b/components/signin/core/browser/primary_account_manager_unittest.cc
@@ -20,7 +20,7 @@ #include "components/signin/core/browser/account_consistency_method.h" #include "components/signin/core/browser/account_fetcher_service.h" #include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/primary_account_policy_manager_impl.h" +#include "components/signin/core/browser/primary_account_policy_manager.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_pref_names.h" #include "components/signin/core/browser/test_signin_client.h" @@ -28,6 +28,10 @@ #include "google_apis/gaia/fake_oauth2_token_service_delegate.h" #include "testing/gtest/include/gtest/gtest.h" +#if !defined(OS_CHROMEOS) +#include "components/signin/core/browser/primary_account_policy_manager_impl.h" +#endif + class PrimaryAccountManagerTest : public testing::Test { public: PrimaryAccountManagerTest() @@ -73,13 +77,19 @@ return account_tracker_.PickAccountIdForAccount(gaia_id, email); } - // Create a naked primary account manager if integration with PKSs is not - // needed. void CreatePrimaryAccountManager() { DCHECK(!manager_); - auto policy_manager = + // Supply the primary account manager with a policy manager to reflect + // production usage: null on ChromeOS, a PrimaryAccountPolicyManagerImpl on + // other platforms. + std::unique_ptr<PrimaryAccountPolicyManager> policy_manager; +#if !defined(OS_CHROMEOS) + policy_manager = std::make_unique<PrimaryAccountPolicyManagerImpl>(&test_signin_client_); - policy_manager_ = policy_manager.get(); + policy_manager_ = + static_cast<PrimaryAccountPolicyManagerImpl*>(policy_manager.get()); +#endif + manager_ = std::make_unique<PrimaryAccountManager>( &test_signin_client_, &token_service_, &account_tracker_, account_consistency_, std::move(policy_manager)); @@ -90,8 +100,10 @@ manager_->SetGoogleSigninSucceededCallback( base::BindRepeating(&PrimaryAccountManagerTest::GoogleSigninSucceeded, base::Unretained(this))); +#if !defined(OS_CHROMEOS) manager_->SetGoogleSignedOutCallback(base::BindRepeating( &PrimaryAccountManagerTest::GoogleSignedOut, base::Unretained(this))); +#endif } // Shuts down |manager_|. @@ -125,7 +137,9 @@ ProfileOAuth2TokenService token_service_; AccountTrackerService account_tracker_; AccountFetcherService account_fetcher_; +#if !defined(OS_CHROMEOS) PrimaryAccountPolicyManagerImpl* policy_manager_; +#endif std::unique_ptr<PrimaryAccountManager> manager_; std::vector<std::string> oauth_tokens_fetched_; std::vector<std::string> cookies_; @@ -134,6 +148,7 @@ int num_signouts_; }; +#if !defined(OS_CHROMEOS) TEST_F(PrimaryAccountManagerTest, SignOut) { CreatePrimaryAccountManager(); CoreAccountId main_account_id = @@ -242,29 +257,6 @@ EXPECT_FALSE(manager_->IsAuthenticated()); } -TEST_F(PrimaryAccountManagerTest, Prohibited) { - local_state_.SetString(prefs::kGoogleServicesUsernamePattern, - ".*@google.com"); - CreatePrimaryAccountManager(); - EXPECT_TRUE(policy_manager_->IsAllowedUsername("test@google.com")); - EXPECT_TRUE(policy_manager_->IsAllowedUsername("happy@google.com")); - EXPECT_FALSE(policy_manager_->IsAllowedUsername("test@invalid.com")); - EXPECT_FALSE(policy_manager_->IsAllowedUsername("test@notgoogle.com")); - EXPECT_FALSE(policy_manager_->IsAllowedUsername(std::string())); -} - -TEST_F(PrimaryAccountManagerTest, TestAlternateWildcard) { - // Test to make sure we accept "*@google.com" as a pattern (treat it as if - // the admin entered ".*@google.com"). - local_state_.SetString(prefs::kGoogleServicesUsernamePattern, "*@google.com"); - CreatePrimaryAccountManager(); - EXPECT_TRUE(policy_manager_->IsAllowedUsername("test@google.com")); - EXPECT_TRUE(policy_manager_->IsAllowedUsername("happy@google.com")); - EXPECT_FALSE(policy_manager_->IsAllowedUsername("test@invalid.com")); - EXPECT_FALSE(policy_manager_->IsAllowedUsername("test@notgoogle.com")); - EXPECT_FALSE(policy_manager_->IsAllowedUsername(std::string())); -} - TEST_F(PrimaryAccountManagerTest, ProhibitedAtStartup) { std::string account_id = AddToAccountTracker("gaia_id", "user@gmail.com"); user_prefs_.SetString(prefs::kGoogleServicesAccountId, account_id); @@ -288,6 +280,7 @@ EXPECT_EQ("", manager_->GetAuthenticatedAccountInfo().email); EXPECT_EQ("", manager_->GetAuthenticatedAccountId()); } +#endif TEST_F(PrimaryAccountManagerTest, ExternalSignIn) { CreatePrimaryAccountManager(); @@ -321,6 +314,7 @@ EXPECT_EQ(account_id, manager_->GetAuthenticatedAccountId()); } +#if !defined(OS_CHROMEOS) TEST_F(PrimaryAccountManagerTest, SigninNotAllowed) { std::string user("user@google.com"); std::string account_id = AddToAccountTracker("gaia_id", user); @@ -331,6 +325,7 @@ EXPECT_EQ("", manager_->GetAuthenticatedAccountInfo().email); EXPECT_EQ("", manager_->GetAuthenticatedAccountId()); } +#endif TEST_F(PrimaryAccountManagerTest, UpgradeToNewPrefs) { user_prefs_.SetString(prefs::kGoogleServicesUsername, "user@gmail.com");
diff --git a/components/signin/core/browser/primary_account_policy_manager_impl.h b/components/signin/core/browser/primary_account_policy_manager_impl.h index d6e2451d..2d82d1b1 100644 --- a/components/signin/core/browser/primary_account_policy_manager_impl.h +++ b/components/signin/core/browser/primary_account_policy_manager_impl.h
@@ -31,8 +31,9 @@ PrimaryAccountManager* primary_account_manager) override; private: - FRIEND_TEST_ALL_PREFIXES(PrimaryAccountManagerTest, Prohibited); - FRIEND_TEST_ALL_PREFIXES(PrimaryAccountManagerTest, TestAlternateWildcard); + FRIEND_TEST_ALL_PREFIXES(PrimaryAccountPolicyManagerImplTest, Prohibited); + FRIEND_TEST_ALL_PREFIXES(PrimaryAccountPolicyManagerImplTest, + TestAlternateWildcard); // Returns true if a signin to Chrome is allowed (by policy or pref). bool IsSigninAllowed() const;
diff --git a/components/signin/core/browser/primary_account_policy_manager_impl_unittest.cc b/components/signin/core/browser/primary_account_policy_manager_impl_unittest.cc new file mode 100644 index 0000000..7597152 --- /dev/null +++ b/components/signin/core/browser/primary_account_policy_manager_impl_unittest.cc
@@ -0,0 +1,75 @@ +// 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 "components/signin/core/browser/primary_account_policy_manager_impl.h" + +#include <memory> +#include <string> + +#include "base/test/scoped_task_environment.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/testing_pref_service.h" +#include "components/signin/core/browser/account_consistency_method.h" +#include "components/signin/core/browser/account_tracker_service.h" +#include "components/signin/core/browser/primary_account_manager.h" +#include "components/signin/core/browser/primary_account_policy_manager_impl.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" +#include "components/signin/core/browser/signin_pref_names.h" +#include "components/signin/core/browser/test_signin_client.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "google_apis/gaia/fake_oauth2_token_service_delegate.h" +#include "testing/gtest/include/gtest/gtest.h" + +class PrimaryAccountPolicyManagerImplTest : public testing::Test { + public: + PrimaryAccountPolicyManagerImplTest() + : test_signin_client_(&user_prefs_), + token_service_(&user_prefs_, + std::make_unique<FakeOAuth2TokenServiceDelegate>()), + primary_account_manager_(&test_signin_client_, + &token_service_, + &account_tracker_, + signin::AccountConsistencyMethod::kDisabled, + nullptr /*policy_manager*/), + policy_manager_(&test_signin_client_) { + PrimaryAccountManager::RegisterProfilePrefs(user_prefs_.registry()); + PrimaryAccountManager::RegisterPrefs(local_state_.registry()); + + policy_manager_.InitializePolicy(&local_state_, &primary_account_manager_); + } + + ~PrimaryAccountPolicyManagerImplTest() override { + test_signin_client_.Shutdown(); + } + + base::test::ScopedTaskEnvironment task_environment_; + sync_preferences::TestingPrefServiceSyncable user_prefs_; + TestingPrefServiceSimple local_state_; + TestSigninClient test_signin_client_; + ProfileOAuth2TokenService token_service_; + AccountTrackerService account_tracker_; + PrimaryAccountManager primary_account_manager_; + PrimaryAccountPolicyManagerImpl policy_manager_; +}; + +TEST_F(PrimaryAccountPolicyManagerImplTest, Prohibited) { + local_state_.SetString(prefs::kGoogleServicesUsernamePattern, + ".*@google.com"); + EXPECT_TRUE(policy_manager_.IsAllowedUsername("test@google.com")); + EXPECT_TRUE(policy_manager_.IsAllowedUsername("happy@google.com")); + EXPECT_FALSE(policy_manager_.IsAllowedUsername("test@invalid.com")); + EXPECT_FALSE(policy_manager_.IsAllowedUsername("test@notgoogle.com")); + EXPECT_FALSE(policy_manager_.IsAllowedUsername(std::string())); +} + +TEST_F(PrimaryAccountPolicyManagerImplTest, TestAlternateWildcard) { + // Test to make sure we accept "*@google.com" as a pattern (treat it as if + // the admin entered ".*@google.com"). + local_state_.SetString(prefs::kGoogleServicesUsernamePattern, "*@google.com"); + EXPECT_TRUE(policy_manager_.IsAllowedUsername("test@google.com")); + EXPECT_TRUE(policy_manager_.IsAllowedUsername("happy@google.com")); + EXPECT_FALSE(policy_manager_.IsAllowedUsername("test@invalid.com")); + EXPECT_FALSE(policy_manager_.IsAllowedUsername("test@notgoogle.com")); + EXPECT_FALSE(policy_manager_.IsAllowedUsername(std::string())); +}
diff --git a/components/translate/content/browser/content_translate_driver.cc b/components/translate/content/browser/content_translate_driver.cc index e949bc6..a2d80f97 100644 --- a/components/translate/content/browser/content_translate_driver.cc +++ b/components/translate/content/browser/content_translate_driver.cc
@@ -31,8 +31,10 @@ #include "content/public/browser/page_navigator.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/referrer.h" +#include "content/public/common/web_preferences.h" #include "net/http/http_status_code.h" #include "services/metrics/public/cpp/ukm_source_id.h" #include "services/network/public/mojom/network_context.mojom.h" @@ -139,9 +141,11 @@ // TODO(crbug.com/940068): Since this factory will be removed, sending an // empty network isolation key for now. - process->CreateURLLoaderFactory(origin, net::NetworkIsolationKey(), - std::move(null_header_client), - mojo::MakeRequest(&factory)); + content::WebPreferences preferences = + web_contents()->GetRenderViewHost()->GetWebkitPreferences(); + process->CreateURLLoaderFactory( + origin, &preferences, net::NetworkIsolationKey(), + std::move(null_header_client), mojo::MakeRequest(&factory)); return factory; }
diff --git a/components/viz/service/display_embedder/skia_output_device.cc b/components/viz/service/display_embedder/skia_output_device.cc index 5d778e4..a07b5b1 100644 --- a/components/viz/service/display_embedder/skia_output_device.cc +++ b/components/viz/service/display_embedder/skia_output_device.cc
@@ -21,10 +21,11 @@ gfx::SwapResponse SkiaOutputDevice::PostSubBuffer( const gfx::Rect& rect, + const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { NOTREACHED(); StartSwapBuffers(std::move(feedback)); - return FinishSwapBuffers(gfx::SwapResult::SWAP_FAILED, gfx::Size()); + return FinishSwapBuffers(gfx::SwapResult::SWAP_FAILED); } void SkiaOutputDevice::SetDrawRectangle(const gfx::Rect& draw_rectangle) {} @@ -40,13 +41,13 @@ params_->swap_response.timings.swap_start = base::TimeTicks::Now(); } -gfx::SwapResponse SkiaOutputDevice::FinishSwapBuffers(gfx::SwapResult result, - const gfx::Size& size) { +gfx::SwapResponse SkiaOutputDevice::FinishSwapBuffers(gfx::SwapResult result) { DCHECK(params_); params_->swap_response.result = result; params_->swap_response.timings.swap_end = base::TimeTicks::Now(); - did_swap_buffer_complete_callback_.Run(*params_, size); + did_swap_buffer_complete_callback_.Run( + *params_, gfx::Size(draw_surface_->width(), draw_surface_->height())); if (feedback_) { std::move(*feedback_)
diff --git a/components/viz/service/display_embedder/skia_output_device.h b/components/viz/service/display_embedder/skia_output_device.h index 75c91d9..0c49d762 100644 --- a/components/viz/service/display_embedder/skia_output_device.h +++ b/components/viz/service/display_embedder/skia_output_device.h
@@ -11,9 +11,9 @@ #include "components/viz/service/display/output_surface.h" #include "gpu/command_buffer/common/swap_buffers_complete_params.h" #include "third_party/skia/include/core/SkRefCnt.h" -#include "third_party/skia/src/gpu/GrSemaphore.h" #include "ui/gfx/swap_result.h" +class GrBackendSemaphore; class SkSurface; namespace gfx { @@ -27,29 +27,6 @@ class SkiaOutputDevice { public: - // A helper class for defining a BeginPaint() and EndPaint() scope. - class ScopedPaint { - public: - explicit ScopedPaint(SkiaOutputDevice* device) - : device_(device), sk_surface_(device->BeginPaint()) { - DCHECK(sk_surface_); - } - ~ScopedPaint() { device_->EndPaint(semaphore_); } - - SkSurface* sk_surface() const { return sk_surface_; } - void set_semaphore(const GrBackendSemaphore& semaphore) { - DCHECK(!semaphore_.isInitialized()); - semaphore_ = semaphore; - } - - private: - SkiaOutputDevice* const device_; - SkSurface* const sk_surface_; - GrBackendSemaphore semaphore_; - - DISALLOW_COPY_AND_ASSIGN(ScopedPaint); - }; - using BufferPresentedCallback = base::OnceCallback<void(const gfx::PresentationFeedback& feedback)>; using DidSwapBufferCompleteCallback = @@ -60,15 +37,20 @@ DidSwapBufferCompleteCallback did_swap_buffer_complete_callback); virtual ~SkiaOutputDevice(); + // SkSurface that can be drawn to. + SkSurface* draw_surface() const { return draw_surface_.get(); } + // Changes the size of draw surface and invalidates it's contents. virtual void Reshape(const gfx::Size& size, float device_scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) = 0; - // Presents the back buffer. - virtual gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) = 0; + // Presents DrawSurface. + virtual gfx::SwapResponse SwapBuffers(const GrBackendSemaphore& semaphore, + BufferPresentedCallback feedback) = 0; virtual gfx::SwapResponse PostSubBuffer(const gfx::Rect& rect, + const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback); // Set the rectangle that will be drawn into on the surface. @@ -87,23 +69,13 @@ bool need_swap_semaphore() const { return need_swap_semaphore_; } protected: - // Begin paint the back buffer. - virtual SkSurface* BeginPaint() = 0; - - // End paint the back buffer. - virtual void EndPaint(const GrBackendSemaphore& semaphore) = 0; - - // Helper method for SwapBuffers() and PostSubBuffer(). It should be called - // at the beginning of SwapBuffers() and PostSubBuffer() implementations void StartSwapBuffers(base::Optional<BufferPresentedCallback> feedback); + gfx::SwapResponse FinishSwapBuffers(gfx::SwapResult result); - // Helper method for SwapBuffers() and PostSubBuffer(). It should be called - // at the end of SwapBuffers() and PostSubBuffer() implementations - gfx::SwapResponse FinishSwapBuffers(gfx::SwapResult result, - const gfx::Size& size); - + sk_sp<SkSurface> draw_surface_; OutputSurface::Capabilities capabilities_; + private: const bool need_swap_semaphore_; uint64_t swap_id_ = 0; DidSwapBufferCompleteCallback did_swap_buffer_complete_callback_;
diff --git a/components/viz/service/display_embedder/skia_output_device_gl.cc b/components/viz/service/display_embedder/skia_output_device_gl.cc index d31721a8..ad4d1cfb7 100644 --- a/components/viz/service/display_embedder/skia_output_device_gl.cc +++ b/components/viz/service/display_embedder/skia_output_device_gl.cc
@@ -94,30 +94,28 @@ : kBottomLeft_GrSurfaceOrigin; auto color_type = supports_alpha_ ? kRGBA_8888_SkColorType : kRGB_888x_SkColorType; - sk_surface_ = SkSurface::MakeFromBackendRenderTarget( + draw_surface_ = SkSurface::MakeFromBackendRenderTarget( gr_context_, render_target, origin, color_type, color_space.ToSkColorSpace(), &surface_props); - DCHECK(sk_surface_); + DCHECK(draw_surface_); } gfx::SwapResponse SkiaOutputDeviceGL::SwapBuffers( + const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { // TODO(backer): Support SwapBuffersAsync StartSwapBuffers({}); - return FinishSwapBuffers( - gl_surface_->SwapBuffers(std::move(feedback)), - gfx::Size(sk_surface_->width(), sk_surface_->height())); + return FinishSwapBuffers(gl_surface_->SwapBuffers(std::move(feedback))); } gfx::SwapResponse SkiaOutputDeviceGL::PostSubBuffer( const gfx::Rect& rect, + const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { // TODO(backer): Support PostSubBufferAsync StartSwapBuffers({}); - return FinishSwapBuffers( - gl_surface_->PostSubBuffer(rect.x(), rect.y(), rect.width(), - rect.height(), std::move(feedback)), - gfx::Size(sk_surface_->width(), sk_surface_->height())); + return FinishSwapBuffers(gl_surface_->PostSubBuffer( + rect.x(), rect.y(), rect.width(), rect.height(), std::move(feedback))); } void SkiaOutputDeviceGL::SetDrawRectangle(const gfx::Rect& draw_rectangle) { @@ -132,13 +130,6 @@ gl_surface_->SetBackbufferAllocation(false); } -SkSurface* SkiaOutputDeviceGL::BeginPaint() { - DCHECK(sk_surface_); - return sk_surface_.get(); -} - -void SkiaOutputDeviceGL::EndPaint(const GrBackendSemaphore& semaphore) {} - #if defined(OS_WIN) void SkiaOutputDeviceGL::DidCreateAcceleratedSurfaceChildWindow( gpu::SurfaceHandle parent_window,
diff --git a/components/viz/service/display_embedder/skia_output_device_gl.h b/components/viz/service/display_embedder/skia_output_device_gl.h index e640e36..2263b8b 100644 --- a/components/viz/service/display_embedder/skia_output_device_gl.h +++ b/components/viz/service/display_embedder/skia_output_device_gl.h
@@ -53,14 +53,14 @@ float device_scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) override; - gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) override; + gfx::SwapResponse SwapBuffers(const GrBackendSemaphore& semaphore, + BufferPresentedCallback feedback) override; gfx::SwapResponse PostSubBuffer(const gfx::Rect& rect, + const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) override; void SetDrawRectangle(const gfx::Rect& draw_rectangle) override; void EnsureBackbuffer() override; void DiscardBackbuffer() override; - SkSurface* BeginPaint() override; - void EndPaint(const GrBackendSemaphore& semaphore) override; // gpu::ImageTransportSurfaceDelegate implementation: #if defined(OS_WIN) @@ -82,8 +82,6 @@ scoped_refptr<gl::GLSurface> gl_surface_; GrContext* gr_context_ = nullptr; - sk_sp<SkSurface> sk_surface_; - bool supports_alpha_ = false; base::WeakPtrFactory<SkiaOutputDeviceGL> weak_ptr_factory_{this};
diff --git a/components/viz/service/display_embedder/skia_output_device_offscreen.cc b/components/viz/service/display_embedder/skia_output_device_offscreen.cc index 8cd89133..e676c698 100644 --- a/components/viz/service/display_embedder/skia_output_device_offscreen.cc +++ b/components/viz/service/display_embedder/skia_output_device_offscreen.cc
@@ -35,40 +35,40 @@ SkImageInfo::Make(size.width(), size.height(), kRGBA_8888_SkColorType, has_alpha_ ? kPremul_SkAlphaType : kOpaque_SkAlphaType, color_space.ToSkColorSpace()); - sk_surface_ = SkSurface::MakeRenderTarget( + draw_surface_ = SkSurface::MakeRenderTarget( gr_context_, SkBudgeted::kNo, image_info_, 0 /* sampleCount */, capabilities_.flipped_output_surface ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin, nullptr /* surfaceProps */); - DCHECK(!!sk_surface_); + DCHECK(!!draw_surface_); // Initialize alpha channel to opaque. if (!has_alpha_) { - auto* canvas = sk_surface_->getCanvas(); + auto* canvas = draw_surface_->getCanvas(); canvas->clear(SkColorSetARGB(255, 0, 0, 0)); } } -gfx::SwapResponse SkiaOutputDeviceOffscreen::SwapBuffers( - BufferPresentedCallback feedback) { - // Reshape should have been called first. - DCHECK(sk_surface_); - - StartSwapBuffers(std::move(feedback)); - return FinishSwapBuffers( - gfx::SwapResult::SWAP_ACK, - gfx::Size(sk_surface_->width(), sk_surface_->height())); -} - gfx::SwapResponse SkiaOutputDeviceOffscreen::PostSubBuffer( const gfx::Rect& rect, + const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { - return SwapBuffers(std::move(feedback)); + return SwapBuffers(semaphore, std::move(feedback)); +} + +gfx::SwapResponse SkiaOutputDeviceOffscreen::SwapBuffers( + const GrBackendSemaphore& semaphore, + BufferPresentedCallback feedback) { + // Reshape should have been called first. + DCHECK(draw_surface_); + + StartSwapBuffers(std::move(feedback)); + return FinishSwapBuffers(gfx::SwapResult::SWAP_ACK); } void SkiaOutputDeviceOffscreen::EnsureBackbuffer() { - if (!image_info_.isEmpty() && !sk_surface_) { - sk_surface_ = SkSurface::MakeRenderTarget( + if (!image_info_.isEmpty() && !draw_surface_) { + draw_surface_ = SkSurface::MakeRenderTarget( gr_context_, SkBudgeted::kNo, image_info_, 0 /* sampleCount */, capabilities_.flipped_output_surface ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin, @@ -77,13 +77,7 @@ } void SkiaOutputDeviceOffscreen::DiscardBackbuffer() { - sk_surface_.reset(); + draw_surface_.reset(); } -SkSurface* SkiaOutputDeviceOffscreen::BeginPaint() { - return sk_surface_.get(); -} - -void SkiaOutputDeviceOffscreen::EndPaint(const GrBackendSemaphore& semaphore) {} - } // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_device_offscreen.h b/components/viz/service/display_embedder/skia_output_device_offscreen.h index bebd366..a1f38d7 100644 --- a/components/viz/service/display_embedder/skia_output_device_offscreen.h +++ b/components/viz/service/display_embedder/skia_output_device_offscreen.h
@@ -27,18 +27,18 @@ float device_scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) override; - gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) override; + gfx::SwapResponse SwapBuffers(const GrBackendSemaphore& semaphore, + BufferPresentedCallback feedback) override; gfx::SwapResponse PostSubBuffer(const gfx::Rect& rect, + const GrBackendSemaphore& semaphore, + BufferPresentedCallback feedback) override; void EnsureBackbuffer() override; void DiscardBackbuffer() override; - SkSurface* BeginPaint() override; - void EndPaint(const GrBackendSemaphore& semaphore) override; protected: GrContext* const gr_context_; const bool has_alpha_; - sk_sp<SkSurface> sk_surface_; private: SkImageInfo image_info_;
diff --git a/components/viz/service/display_embedder/skia_output_device_vulkan.cc b/components/viz/service/display_embedder/skia_output_device_vulkan.cc index c9f1f1f..403f3ca 100644 --- a/components/viz/service/display_embedder/skia_output_device_vulkan.cc +++ b/components/viz/service/display_embedder/skia_output_device_vulkan.cc
@@ -32,7 +32,7 @@ } SkiaOutputDeviceVulkan::~SkiaOutputDeviceVulkan() { - DCHECK(!scoped_write_); + scoped_write_.reset(); if (vulkan_surface_) { auto* fence_helper = context_provider_->GetDeviceQueue()->GetFenceHelper(); fence_helper->EnqueueVulkanObjectCleanupForSubmittedWork( @@ -44,45 +44,75 @@ float device_scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) { - DCHECK(!scoped_write_); - - uint32_t generation = 0; - if (!vulkan_surface_) { + if (!vulkan_surface_) CreateVulkanSurface(); - } else { - generation = vulkan_surface_->swap_chain_generation(); - } + scoped_write_.reset(); + auto old_size = vulkan_surface_->size(); vulkan_surface_->SetSize(size); - - if (vulkan_surface_->swap_chain_generation() != generation) { - // swapchain is changed, we need recreate all cached sk surfaces. + if (vulkan_surface_->size() != old_size) { + // Size has been changed, we need to clear all surfaces which will be + // recreated later. sk_surfaces_.clear(); sk_surfaces_.resize(vulkan_surface_->GetSwapChain()->num_images()); } + + UpdateDrawSurface(); } gfx::SwapResponse SkiaOutputDeviceVulkan::SwapBuffers( + const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { // Reshape should have been called first. DCHECK(vulkan_surface_); - DCHECK(!scoped_write_); + DCHECK(draw_surface_); + DCHECK(scoped_write_); StartSwapBuffers(std::move(feedback)); - auto size = vulkan_surface_->size(); - auto response = FinishSwapBuffers(vulkan_surface_->SwapBuffers(), size); + auto backend = draw_surface_->getBackendRenderTarget( + SkSurface::kFlushRead_BackendHandleAccess); + GrVkImageInfo vk_image_info; + if (!backend.getVkImageInfo(&vk_image_info)) + NOTREACHED() << "Failed to get the image info."; + scoped_write_->set_image_layout(vk_image_info.fImageLayout); + scoped_write_->SetEndSemaphore(semaphore.vkSemaphore()); + scoped_write_.reset(); + + auto response = FinishSwapBuffers(vulkan_surface_->SwapBuffers()); + UpdateDrawSurface(); + return response; } -SkSurface* SkiaOutputDeviceVulkan::BeginPaint() { +void SkiaOutputDeviceVulkan::CreateVulkanSurface() { + gfx::AcceleratedWidget accelerated_widget = gfx::kNullAcceleratedWidget; +#if defined(OS_ANDROID) + bool can_be_used_with_surface_control = false; + accelerated_widget = + gpu::GpuSurfaceLookup::GetInstance()->AcquireNativeWidget( + surface_handle_, &can_be_used_with_surface_control); +#else + accelerated_widget = surface_handle_; +#endif + auto vulkan_surface = + context_provider_->GetVulkanImplementation()->CreateViewSurface( + accelerated_widget); + if (!vulkan_surface) + LOG(FATAL) << "Failed to create vulkan surface."; + if (!vulkan_surface->Initialize(context_provider_->GetDeviceQueue(), + gpu::VulkanSurface::FORMAT_RGBA_32)) { + LOG(FATAL) << "Failed to initialize vulkan surface."; + } + vulkan_surface_ = std::move(vulkan_surface); + sk_surfaces_.resize(vulkan_surface_->GetSwapChain()->num_images()); +} + +void SkiaOutputDeviceVulkan::UpdateDrawSurface() { DCHECK(vulkan_surface_); DCHECK(!scoped_write_); scoped_write_.emplace(vulkan_surface_->GetSwapChain()); - if (!scoped_write_->success()) { - scoped_write_.reset(); - return nullptr; - } + auto& sk_surface = sk_surfaces_[scoped_write_->image_index()]; if (!sk_surface) { @@ -110,51 +140,11 @@ SkSurface::kFlushRead_BackendHandleAccess); backend.setVkImageLayout(scoped_write_->image_layout()); } - VkSemaphore vk_semaphore = scoped_write_->TakeBeginSemaphore(); - if (vk_semaphore != VK_NULL_HANDLE) { - GrBackendSemaphore semaphore; - semaphore.initVulkan(vk_semaphore); - auto result = sk_surface->wait(1, &semaphore); - DCHECK(result); - } - return sk_surface.get(); -} - -void SkiaOutputDeviceVulkan::EndPaint(const GrBackendSemaphore& semaphore) { - DCHECK(scoped_write_); - - auto& sk_surface = sk_surfaces_[scoped_write_->image_index()]; - auto backend = sk_surface->getBackendRenderTarget( - SkSurface::kFlushRead_BackendHandleAccess); - GrVkImageInfo vk_image_info; - if (!backend.getVkImageInfo(&vk_image_info)) - NOTREACHED() << "Failed to get the image info."; - scoped_write_->set_image_layout(vk_image_info.fImageLayout); - if (semaphore.isInitialized()) - scoped_write_->SetEndSemaphore(semaphore.vkSemaphore()); - scoped_write_.reset(); -} - -void SkiaOutputDeviceVulkan::CreateVulkanSurface() { - gfx::AcceleratedWidget accelerated_widget = gfx::kNullAcceleratedWidget; -#if defined(OS_ANDROID) - bool can_be_used_with_surface_control = false; - accelerated_widget = - gpu::GpuSurfaceLookup::GetInstance()->AcquireNativeWidget( - surface_handle_, &can_be_used_with_surface_control); -#else - accelerated_widget = surface_handle_; -#endif - auto vulkan_surface = - context_provider_->GetVulkanImplementation()->CreateViewSurface( - accelerated_widget); - if (!vulkan_surface) - LOG(FATAL) << "Failed to create vulkan surface."; - if (!vulkan_surface->Initialize(context_provider_->GetDeviceQueue(), - gpu::VulkanSurface::FORMAT_RGBA_32)) { - LOG(FATAL) << "Failed to initialize vulkan surface."; - } - vulkan_surface_ = std::move(vulkan_surface); + GrBackendSemaphore semaphore; + semaphore.initVulkan(scoped_write_->TakeBeginSemaphore()); + auto result = sk_surface->wait(1, &semaphore); + DCHECK(result); + draw_surface_ = sk_surface; } } // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_device_vulkan.h b/components/viz/service/display_embedder/skia_output_device_vulkan.h index 1c45ecb..cc35ef7 100644 --- a/components/viz/service/display_embedder/skia_output_device_vulkan.h +++ b/components/viz/service/display_embedder/skia_output_device_vulkan.h
@@ -35,13 +35,12 @@ float device_scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) override; - gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) override; - SkSurface* BeginPaint() override; - void EndPaint(const GrBackendSemaphore& semaphore) override; + gfx::SwapResponse SwapBuffers(const GrBackendSemaphore& semaphore, + BufferPresentedCallback feedback) override; private: void CreateVulkanSurface(); - void CreateSkSurface(); + void UpdateDrawSurface(); VulkanContextProvider* const context_provider_;
diff --git a/components/viz/service/display_embedder/skia_output_device_x11.cc b/components/viz/service/display_embedder/skia_output_device_x11.cc index 777348d1..9f20972 100644 --- a/components/viz/service/display_embedder/skia_output_device_x11.cc +++ b/components/viz/service/display_embedder/skia_output_device_x11.cc
@@ -53,14 +53,16 @@ } gfx::SwapResponse SkiaOutputDeviceX11::SwapBuffers( + const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { return PostSubBuffer( - gfx::Rect(0, 0, sk_surface_->width(), sk_surface_->height()), - std::move(feedback)); + gfx::Rect(0, 0, draw_surface_->width(), draw_surface_->height()), + semaphore, std::move(feedback)); } gfx::SwapResponse SkiaOutputDeviceX11::PostSubBuffer( const gfx::Rect& rect, + const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) { StartSwapBuffers(std::move(feedback)); @@ -68,7 +70,7 @@ SkImageInfo::MakeN32(rect.width(), rect.height(), kOpaque_SkAlphaType); DCHECK_GE(pixels_.capacity(), ii.computeMinByteSize()); SkPixmap sk_pixmap(ii, pixels_.data(), ii.minRowBytes()); - bool result = sk_surface_->readPixels(sk_pixmap, rect.x(), rect.y()); + bool result = draw_surface_->readPixels(sk_pixmap, rect.x(), rect.y()); LOG_IF(FATAL, !result) << "Failed to read pixels from offscreen SkSurface."; if (bpp_ == 32 || bpp_ == 16) { @@ -129,9 +131,7 @@ NOTIMPLEMENTED(); } XFlush(display_); - return FinishSwapBuffers( - gfx::SwapResult::SWAP_ACK, - gfx::Size(sk_surface_->width(), sk_surface_->height())); + return FinishSwapBuffers(gfx::SwapResult::SWAP_ACK); } } // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_device_x11.h b/components/viz/service/display_embedder/skia_output_device_x11.h index a82d72e7..f599b7a 100644 --- a/components/viz/service/display_embedder/skia_output_device_x11.h +++ b/components/viz/service/display_embedder/skia_output_device_x11.h
@@ -27,8 +27,10 @@ float device_scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) override; - gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) override; + gfx::SwapResponse SwapBuffers(const GrBackendSemaphore& semaphore, + BufferPresentedCallback feedback) override; gfx::SwapResponse PostSubBuffer(const gfx::Rect& rect, + const GrBackendSemaphore& semaphore, BufferPresentedCallback feedback) override; private:
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 6539529..d0f0cef 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -621,11 +621,8 @@ output_device_->Reshape(size_, device_scale_factor, color_space, has_alpha); if (characterization) { - // Start a paint temporarily for getting sk surface characterization. - scoped_output_device_paint_.emplace(output_device_.get()); output_sk_surface()->characterize(characterization); DCHECK(characterization->isValid()); - scoped_output_device_paint_.reset(); } } @@ -638,12 +635,6 @@ base::OnceClosure on_finished) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(ddl); - DCHECK(!scoped_output_device_paint_); - - // We do not reset scoped_output_device_paint_ after drawing the ddl until - // SwapBuffers() is called, because we may need access to output_sk_surface() - // for CopyOutput(). - scoped_output_device_paint_.emplace(output_device_.get()); DCHECK(output_sk_surface()); if (!MakeCurrent(true /* need_fbo0 */)) @@ -669,8 +660,7 @@ DCHECK(result); } - if (!output_sk_surface()->draw(ddl.get())) - DLOG(ERROR) << "output_sk_surface()->draw() failed."; + output_sk_surface()->draw(ddl.get()); ddl = nullptr; if (overdraw_ddl) { @@ -714,9 +704,10 @@ return; } if (output_device_->need_swap_semaphore()) { - auto& semaphore = scoped_promise_image_access.end_semaphores().back(); - DCHECK(semaphore.isInitialized()); - scoped_output_device_paint_->set_semaphore(std::move(semaphore)); + DCHECK(!swap_buffers_semaphore_.isInitialized()); + swap_buffers_semaphore_ = + scoped_promise_image_access.end_semaphores().back(); + DCHECK(swap_buffers_semaphore_.isInitialized()); } } ReleaseFenceSyncAndPushTextureUpdates(sync_fence_release); @@ -724,14 +715,11 @@ void SkiaOutputSurfaceImplOnGpu::SwapBuffers(OutputSurfaceFrame frame) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK(scoped_output_device_paint_); - DCHECK(output_device_); - - scoped_output_device_paint_.reset(); - + DCHECK(output_sk_surface()); if (!MakeCurrent(!dependency_->IsOffscreen() /* need_fbo0 */)) return; + DCHECK(output_device_); gfx::SwapResponse response; if (frame.sub_buffer_rect && frame.sub_buffer_rect->IsEmpty()) { // TODO(https://crbug.com/898680): Maybe do something for overlays here. @@ -742,10 +730,13 @@ frame.sub_buffer_rect->set_y(size_.height() - frame.sub_buffer_rect->y() - frame.sub_buffer_rect->height()); response = output_device_->PostSubBuffer(*frame.sub_buffer_rect, + swap_buffers_semaphore_, buffer_presented_callback_); } else { - response = output_device_->SwapBuffers(buffer_presented_callback_); + response = output_device_->SwapBuffers(swap_buffers_semaphore_, + buffer_presented_callback_); } + swap_buffers_semaphore_ = GrBackendSemaphore(); for (auto& latency : frame.latency_info) { latency.AddLatencyNumberWithTimestamp( @@ -840,8 +831,6 @@ // TODO(crbug.com/898595): Do this on the GPU instead of CPU with Vulkan. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); bool from_fbo0 = !id; - DCHECK(scoped_output_device_paint_ || !from_fbo0); - if (!MakeCurrent(true /* need_fbo0 */)) return;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index f06fa850..a1146d65 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -175,7 +175,7 @@ bool is_using_vulkan() const { return !!vulkan_context_provider_; } SkSurface* output_sk_surface() const { - return scoped_output_device_paint_->sk_surface(); + return output_device_->draw_surface(); } void CreateFallbackImage(ImageContext* context); @@ -187,9 +187,9 @@ shared_image_representation_factory_; VulkanContextProvider* const vulkan_context_provider_; const RendererSettings renderer_settings_; - const DidSwapBufferCompleteCallback did_swap_buffer_complete_callback_; - const BufferPresentedCallback buffer_presented_callback_; - const ContextLostCallback context_lost_callback_; + DidSwapBufferCompleteCallback did_swap_buffer_complete_callback_; + BufferPresentedCallback buffer_presented_callback_; + ContextLostCallback context_lost_callback_; #if defined(USE_OZONE) // This should outlive gl_surface_ and vulkan_surface_. @@ -205,7 +205,9 @@ size_t max_resource_cache_bytes_ = 0u; std::unique_ptr<SkiaOutputDevice> output_device_; - base::Optional<SkiaOutputDevice::ScopedPaint> scoped_output_device_paint_; + + // Semaphore for SkiaOutputDevice::SwapBuffers() to wait on. + GrBackendSemaphore swap_buffers_semaphore_; // Offscreen surfaces for render passes. It can only be accessed on GPU // thread.
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 87618062..5b00710 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1922,6 +1922,8 @@ "web_contents/aura/types.h", "web_contents/frame_tree_node_id_registry.cc", "web_contents/frame_tree_node_id_registry.h", + "web_contents/javascript_dialog_navigation_deferrer.cc", + "web_contents/javascript_dialog_navigation_deferrer.h", "web_contents/web_contents_impl.cc", "web_contents/web_contents_impl.h", "web_contents/web_contents_view.h", @@ -1986,6 +1988,8 @@ "webrtc/webrtc_internals_ui.cc", "webrtc/webrtc_internals_ui.h", "webrtc/webrtc_internals_ui_observer.h", + "websockets/websocket_connector_impl.cc", + "websockets/websocket_connector_impl.h", "websockets/websocket_handshake_request_info_impl.cc", "websockets/websocket_handshake_request_info_impl.h", "websockets/websocket_manager.cc",
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index 77d4c854..9975d7b 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -152,7 +152,9 @@ BrowserAccessibilityManager::BrowserAccessibilityManager( BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory) - : delegate_(delegate), + : WebContentsObserver(delegate ? delegate->AccessibilityWebContents() + : nullptr), + delegate_(delegate), factory_(factory), tree_(new ui::AXSerializableTree()), user_is_navigating_away_(false), @@ -168,7 +170,9 @@ const ui::AXTreeUpdate& initial_tree, BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory) - : delegate_(delegate), + : WebContentsObserver(delegate ? delegate->AccessibilityWebContents() + : nullptr), + delegate_(delegate), factory_(factory), tree_(new ui::AXSerializableTree()), user_is_navigating_away_(false),
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h index b5ff624..8ca497e8 100644 --- a/content/browser/accessibility/browser_accessibility_manager.h +++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -19,6 +19,7 @@ #include "content/browser/accessibility/browser_accessibility_position.h" #include "content/common/content_export.h" #include "content/public/browser/ax_event_notification_details.h" +#include "content/public/browser/web_contents_observer.h" #include "third_party/blink/public/web/web_ax_enums.h" #include "ui/accessibility/ax_action_data.h" #include "ui/accessibility/ax_event_generator.h" @@ -88,6 +89,7 @@ virtual gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() = 0; virtual gfx::NativeViewAccessible AccessibilityGetNativeViewAccessibleForWindow() = 0; + virtual WebContents* AccessibilityWebContents() = 0; // Returns true if this delegate represents the main (topmost) frame in a // tree of frames. @@ -125,7 +127,8 @@ // Manages a tree of BrowserAccessibility objects. class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeObserver, - public ui::AXTreeManager { + public ui::AXTreeManager, + public WebContentsObserver { protected: using BrowserAccessibilityPositionInstance = BrowserAccessibilityPosition::AXPositionInstance; @@ -188,11 +191,14 @@ virtual void OnWindowBlurred(); // Notify the accessibility manager about page navigation. + // TODO(domfarolino, dmazzoni): Implement WebContentsObserver methods that + // correspond to the ones we provide today, so we can stop being manually + // notified of navigation events when they happen. void UserIsNavigatingAway(); virtual void UserIsReloading(); void NavigationSucceeded(); void NavigationFailed(); - void DidStopLoading(); + void DidStopLoading() override; // Keep track of if this page is hidden by an interstitial, in which case // we need to suppress all events.
diff --git a/content/browser/accessibility/test_browser_accessibility_delegate.cc b/content/browser/accessibility/test_browser_accessibility_delegate.cc index eabb8180..4679bc6 100644 --- a/content/browser/accessibility/test_browser_accessibility_delegate.cc +++ b/content/browser/accessibility/test_browser_accessibility_delegate.cc
@@ -46,6 +46,10 @@ return nullptr; } +WebContents* TestBrowserAccessibilityDelegate::AccessibilityWebContents() { + return nullptr; +} + bool TestBrowserAccessibilityDelegate::AccessibilityIsMainFrame() const { return is_root_frame_; }
diff --git a/content/browser/accessibility/test_browser_accessibility_delegate.h b/content/browser/accessibility/test_browser_accessibility_delegate.h index 10dca8b..d42f436 100644 --- a/content/browser/accessibility/test_browser_accessibility_delegate.h +++ b/content/browser/accessibility/test_browser_accessibility_delegate.h
@@ -22,6 +22,7 @@ gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() override; gfx::NativeViewAccessible AccessibilityGetNativeViewAccessibleForWindow() override; + WebContents* AccessibilityWebContents() override; bool AccessibilityIsMainFrame() const override; bool got_fatal_error() const;
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc index d38d9d0..f367008b 100644 --- a/content/browser/frame_host/frame_tree_node.cc +++ b/content/browser/frame_host/frame_tree_node.cc
@@ -516,6 +516,8 @@ // Notify accessibility that the user is no longer trying to load or // reload a page. + // TODO(domfarolino): Remove this in favor of notifying via the delegate's + // DidStopLoading() above. BrowserAccessibilityManager* manager = current_frame_host()->browser_accessibility_manager(); if (manager)
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index ad82e369..7437f47 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -108,6 +108,7 @@ #include "content/browser/web_package/prefetched_signed_exchange_cache.h" #include "content/browser/webauth/authenticator_environment_impl.h" #include "content/browser/webauth/authenticator_impl.h" +#include "content/browser/websockets/websocket_connector_impl.h" #include "content/browser/websockets/websocket_manager.h" #include "content/browser/webui/url_data_manager_backend.h" #include "content/browser/webui/web_ui_controller_factory_registry.h" @@ -1635,6 +1636,10 @@ return nullptr; } +WebContents* RenderFrameHostImpl::AccessibilityWebContents() { + return delegate()->GetAsWebContents(); +} + bool RenderFrameHostImpl::AccessibilityIsMainFrame() const { return frame_tree_node()->IsMainFrame(); } @@ -4164,7 +4169,7 @@ base::Unretained(this))); registry_->AddInterface(base::BindRepeating( - &RenderFrameHostImpl::CreateWebSocket, base::Unretained(this))); + &RenderFrameHostImpl::CreateWebSocketConnector, base::Unretained(this))); registry_->AddInterface(base::BindRepeating( &RenderFrameHostImpl::CreateDedicatedWorkerHostFactory, @@ -5772,15 +5777,16 @@ &default_factory_request); // Create the URLLoaderFactory - either via ContentBrowserClient or ourselves. + WebPreferences preferences = GetRenderViewHost()->GetWebkitPreferences(); if (GetCreateNetworkFactoryCallbackForRenderFrame().is_null()) { - GetProcess()->CreateURLLoaderFactory(origin, network_isolation_key_, - std::move(header_client), - std::move(default_factory_request)); + GetProcess()->CreateURLLoaderFactory( + origin, &preferences, network_isolation_key_, std::move(header_client), + std::move(default_factory_request)); } else { network::mojom::URLLoaderFactoryPtr original_factory; - GetProcess()->CreateURLLoaderFactory(origin, network_isolation_key_, - std::move(header_client), - mojo::MakeRequest(&original_factory)); + GetProcess()->CreateURLLoaderFactory( + origin, &preferences, network_isolation_key_, std::move(header_client), + mojo::MakeRequest(&original_factory)); GetCreateNetworkFactoryCallbackForRenderFrame().Run( std::move(default_factory_request), GetProcess()->GetID(), original_factory.PassInterface()); @@ -6013,21 +6019,12 @@ base::Unretained(this)))); } -void RenderFrameHostImpl::CreateWebSocket( - network::mojom::WebSocketRequest request) { - network::mojom::AuthenticationHandlerPtr auth_handler; - - network::mojom::TrustedHeaderClientPtr header_client; - uint32_t options = network::mojom::kWebSocketOptionNone; - GetContentClient()->browser()->WillCreateWebSocket( - this, &request, &auth_handler, &header_client, &options); - - // This is to support usage of WebSockets in cases in which there is an - // associated RenderFrame. This is important for showing the correct security - // state of the page and also honoring user override of bad certificates. - WebSocketManager::CreateWebSocket( - process_->GetID(), routing_id_, last_committed_origin_, options, - std::move(auth_handler), std::move(header_client), std::move(request)); +void RenderFrameHostImpl::CreateWebSocketConnector( + blink::mojom::WebSocketConnectorRequest request) { + mojo::MakeStrongBinding( + std::make_unique<WebSocketConnectorImpl>( + GetProcess()->GetID(), routing_id_, last_committed_origin_), + std::move(request)); } void RenderFrameHostImpl::CreateDedicatedWorkerHostFactory(
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 9a91048c..72aea75c 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -82,6 +82,7 @@ #include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h" #include "third_party/blink/public/mojom/sms/sms_receiver.mojom-forward.h" #include "third_party/blink/public/mojom/webauthn/authenticator.mojom.h" +#include "third_party/blink/public/mojom/websockets/websocket_connector.mojom.h" #include "third_party/blink/public/mojom/worker/dedicated_worker_host_factory.mojom.h" #include "third_party/blink/public/platform/web_focus_type.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" @@ -308,6 +309,7 @@ gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() override; gfx::NativeViewAccessible AccessibilityGetNativeViewAccessibleForWindow() override; + WebContents* AccessibilityWebContents() override; bool AccessibilityIsMainFrame() const override; // RenderProcessHostObserver implementation. @@ -1389,7 +1391,8 @@ void BindMediaInterfaceFactoryRequest( media::mojom::InterfaceFactoryRequest request); - void CreateWebSocket(network::mojom::WebSocketRequest request); + void CreateWebSocketConnector( + blink::mojom::WebSocketConnectorRequest request); void CreateDedicatedWorkerHostFactory( blink::mojom::DedicatedWorkerHostFactoryRequest request);
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc index 1485b12..a09d204 100644 --- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -3519,7 +3519,7 @@ // Ensure that document hosted on file: URL can successfully execute pushState // with arbitrary origin, when universal access setting is enabled. // TODO(nasko): The test is disabled on Mac, since universal access from file -// scheme behaves differently. +// scheme behaves differently. See also https://crbug.com/981018. #if defined(OS_MACOSX) #define MAYBE_EnsureUniversalAccessFromFileSchemeSucceeds \ DISABLED_EnsureUniversalAccessFromFileSchemeSucceeds @@ -5565,7 +5565,7 @@ // TODO(nasko): Consider moving this into RenderProcessHostWatcher. class RenderProcessReadyObserver : public RenderProcessHostObserver { public: - RenderProcessReadyObserver(RenderProcessHost* render_process_host) + explicit RenderProcessReadyObserver(RenderProcessHost* render_process_host) : render_process_host_(render_process_host), quit_closure_(run_loop_.QuitClosure()) { render_process_host_->AddObserver(this);
diff --git a/content/browser/loader/cors_file_origin_browsertest.cc b/content/browser/loader/cors_file_origin_browsertest.cc index ca890e3..8da28c6 100644 --- a/content/browser/loader/cors_file_origin_browsertest.cc +++ b/content/browser/loader/cors_file_origin_browsertest.cc
@@ -14,8 +14,12 @@ #include "base/synchronization/waitable_event.h" #include "base/test/scoped_command_line.h" #include "base/test/scoped_feature_list.h" +#include "build/build_config.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/web_contents.h" #include "content/public/common/content_paths.h" #include "content/public/common/content_switches.h" +#include "content/public/common/web_preferences.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" @@ -28,8 +32,10 @@ #include "net/test/embedded_test_server/request_handler_util.h" #include "services/network/public/cpp/cors/cors.h" #include "services/network/public/cpp/features.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" +#include "url/url_constants.h" namespace content { @@ -260,6 +266,43 @@ EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle()); } +// TODO(lukasza, nasko): https://crbug.com/981018: Enable this test on Macs +// after understanding what makes it flakily fail on the mac-rel trybot. +#if defined(OS_MACOSX) +#define MAYBE_UniversalAccessFromFileUrls DISABLED_UniversalAccessFromFileUrls +#else +#define MAYBE_UniversalAccessFromFileUrls UniversalAccessFromFileUrls +#endif +IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTest, + MAYBE_UniversalAccessFromFileUrls) { + const char* kScript = R"( + fetch($1) + .then(response => response.text()) + .then(text => "SUCCESS: " + text) + .catch(error => "ERROR: " + error) + )"; + std::string script = + JsReplace(kScript, embedded_test_server()->GetURL("/title2.html")); + + // Activate the preference to allow universal access from file URLs. + RenderViewHost* rvh = shell()->web_contents()->GetRenderViewHost(); + WebPreferences prefs = rvh->GetWebkitPreferences(); + prefs.allow_universal_access_from_file_urls = true; + rvh->UpdateWebkitPreferences(prefs); + + // Navigate to a file: test page. + GURL page_url = GetTestUrl(nullptr, "title1.html"); + EXPECT_EQ(url::kFileScheme, page_url.scheme()); + EXPECT_TRUE(NavigateToURL(shell(), page_url)); + + // Fetching http resources should be allowed by CORS when + // universal access from file URLs is requested. + std::string fetch_result = EvalJs(shell(), script).ExtractString(); + fetch_result = TrimWhitespaceASCII(fetch_result, base::TRIM_ALL).as_string(); + EXPECT_THAT(fetch_result, ::testing::HasSubstr("SUCCESS:")); + EXPECT_THAT(fetch_result, ::testing::HasSubstr("This page has a title")); +} + IN_PROC_BROWSER_TEST_P(CorsFileOriginBrowserTestWithAllowFileAccessFromFiles, AccessControlAllowOriginIsNull) { std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
diff --git a/content/browser/loader/cross_site_document_blocking_browsertest.cc b/content/browser/loader/cross_site_document_blocking_browsertest.cc index 86026502..0c95d9b 100644 --- a/content/browser/loader/cross_site_document_blocking_browsertest.cc +++ b/content/browser/loader/cross_site_document_blocking_browsertest.cc
@@ -10,6 +10,8 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/feature_list.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/macros.h" #include "base/strings/pattern.h" #include "base/strings/string_util.h" @@ -18,6 +20,7 @@ #include "base/task/post_task.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "content/browser/loader/cross_site_document_resource_handler.h" #include "content/browser/site_instance_impl.h" @@ -171,6 +174,15 @@ static_cast<int>(expected_action), 1); } +// Gets contents of a file at //content/test/data/<dir>/<file>. +std::string GetTestFileContents(const char* dir, const char* file) { + base::ScopedAllowBlockingForTesting allow_io; + base::FilePath path = GetTestFilePath(dir, file); + std::string result; + EXPECT_TRUE(ReadFileToString(path, &result)); + return result; +} + // Helper for intercepting a resource request to the given URL and capturing the // response headers and body. // @@ -236,7 +248,8 @@ return body_; } - void Verify(CorbExpectations expectations) { + void Verify(CorbExpectations expectations, + const std::string& expected_resource_body) { if (0 != (expectations & kShouldBeBlocked)) { ASSERT_EQ(net::OK, completion_status().error_code); @@ -253,7 +266,9 @@ // Verify that the console message would have been printed. EXPECT_TRUE(completion_status().should_report_corb_blocking); } else { + ASSERT_EQ(net::OK, completion_status().error_code); EXPECT_FALSE(completion_status().should_report_corb_blocking); + EXPECT_EQ(expected_resource_body, response_body()); } } @@ -452,13 +467,28 @@ } void VerifyImgRequest(std::string resource, CorbExpectations expectations) { - SCOPED_TRACE("... while testing via <img> tag"); + // Test from a http: origin. + VerifyImgRequest(resource, expectations, + GURL("http://foo.com/title1.html")); - // Navigate to the test page while request interceptor is active. + // Test from a file: origin. + VerifyImgRequest(resource, expectations, + GetTestUrl(nullptr, "title1.html")); + } + + void VerifyImgRequest(std::string resource, + CorbExpectations expectations, + GURL page_url) { GURL resource_url( std::string("http://cross-origin.com/site_isolation/" + resource)); + SCOPED_TRACE( + base::StringPrintf("... while testing via <img src='%s'> from %s", + resource_url.spec().c_str(), + url::Origin::Create(page_url).Serialize().c_str())); + + // Navigate to the test page while request interceptor is active. RequestInterceptor interceptor(resource_url); - EXPECT_TRUE(NavigateToURL(shell(), GURL("http://foo.com/title1.html"))); + EXPECT_TRUE(NavigateToURL(shell(), page_url)); // Make sure that base::HistogramTester below starts with a clean slate. FetchHistogramsFromChildProcesses(); @@ -474,7 +504,8 @@ // Verify... InspectHistograms(histograms, expectations, resource, ResourceType::kImage); - interceptor.Verify(expectations); + interceptor.Verify(expectations, + GetTestFileContents("site_isolation", resource.c_str())); } private: @@ -536,10 +567,8 @@ "json-prefixed-4.js", "nosniff.json.js", "nosniff.json-prefixed.js"}; - for (const char* resource : blocked_resources) { - SCOPED_TRACE(base::StringPrintf("... while testing page: %s", resource)); + for (const char* resource : blocked_resources) VerifyImgRequest(resource, kShouldBeSniffedAndBlocked); - } // These files should be disallowed without sniffing. // nosniff.* - Won't sniff correctly, but blocked because of nosniff. @@ -551,10 +580,8 @@ // ChromeContentBrowserClient::OnNetworkServiceCreated. const char* nosniff_blocked_resources[] = { "nosniff.html", "nosniff.xml", "nosniff.json", "nosniff.txt", "fake.zip"}; - for (const char* resource : nosniff_blocked_resources) { - SCOPED_TRACE(base::StringPrintf("... while testing page: %s", resource)); + for (const char* resource : nosniff_blocked_resources) VerifyImgRequest(resource, kShouldBeBlockedWithoutSniffing); - } // These files are allowed for XHR under the document blocking policy because // the sniffing logic determines they are not actually documents. @@ -581,10 +608,8 @@ "nosniff.json-list.js", "js-html-polyglot.html", "js-html-polyglot2.html"}; - for (const char* resource : sniff_allowed_resources) { - SCOPED_TRACE(base::StringPrintf("... while testing page: %s", resource)); + for (const char* resource : sniff_allowed_resources) VerifyImgRequest(resource, kShouldBeSniffedAndAllowed); - } } // This test covers an aspect of Cross-Origin-Resource-Policy (CORP, different @@ -828,7 +853,8 @@ // Verify that the response completed successfully, was blocked and was logged // as having initially a non-empty body. - interceptor.Verify(kShouldBeBlockedWithoutSniffing); + interceptor.Verify(kShouldBeBlockedWithoutSniffing, + "no resource body needed for blocking verification"); // Verify that most response headers have been removed by CORB. const std::string& headers = @@ -918,7 +944,8 @@ // only possible when NetworkService is enabled). if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { interceptor.WaitForRequestCompletion(); - interceptor.Verify(kShouldBeBlockedWithoutSniffing); + interceptor.Verify(kShouldBeBlockedWithoutSniffing, + "no resource body needed for blocking verification"); } // Wait for fetch result (really needed only without NetworkService, if no @@ -1007,7 +1034,8 @@ InspectHistograms(histograms, kShouldBeBlockedWithoutSniffing, "nosniff.json", ResourceType::kImage, special_request_initiator_origin_lock_check_for_appcache); - interceptor.Verify(kShouldBeBlockedWithoutSniffing); + interceptor.Verify(kShouldBeBlockedWithoutSniffing, + "no resource body needed for blocking verification"); } } @@ -1322,10 +1350,12 @@ // NetworkService enforices |request_initiator_site_lock| for CORB, // which means that legitimate fetches from HTML Imported scripts may get // incorrectly blocked. - interceptor.Verify(CorbExpectations::kShouldBeBlockedWithoutSniffing); + interceptor.Verify(CorbExpectations::kShouldBeBlockedWithoutSniffing, + "no resource body needed for blocking verification"); } else { // Without |request_initiator_site_lock| no CORB blocking is expected. - interceptor.Verify(CorbExpectations::kShouldBeAllowedWithoutSniffing); + interceptor.Verify(CorbExpectations::kShouldBeAllowedWithoutSniffing, + GetTestFileContents("site_isolation", "nosniff.json")); } } } @@ -1389,7 +1419,8 @@ // |request_initiator| is same-origin (foo.com), and so the fetch should not // be blocked by CORB. - interceptor.Verify(CorbExpectations::kShouldBeAllowedWithoutSniffing); + interceptor.Verify(CorbExpectations::kShouldBeAllowedWithoutSniffing, + GetTestFileContents("site_isolation", "nosniff.json")); std::string fetch_result; EXPECT_TRUE(msg_queue.WaitForMessage(&fetch_result)); EXPECT_THAT(fetch_result, ::testing::HasSubstr("BODY: runMe")); @@ -1455,7 +1486,8 @@ // |request_initiator| is same-origin (foo.com), and so the fetch should not // be blocked by CORB. - interceptor.Verify(CorbExpectations::kShouldBeAllowedWithoutSniffing); + interceptor.Verify(CorbExpectations::kShouldBeAllowedWithoutSniffing, + GetTestFileContents("site_isolation", "nosniff.json")); std::string fetch_result; EXPECT_TRUE(msg_queue.WaitForMessage(&fetch_result)); EXPECT_THAT(fetch_result, ::testing::HasSubstr("BODY: runMe"));
diff --git a/content/browser/loader/cross_site_document_resource_handler.cc b/content/browser/loader/cross_site_document_resource_handler.cc index b9bd89a..8bbfacaa 100644 --- a/content/browser/loader/cross_site_document_resource_handler.cc +++ b/content/browser/loader/cross_site_document_resource_handler.cc
@@ -572,6 +572,12 @@ return false; } + // Pre-NetworkService allows all requests from file: URLs (mostly as a crude + // way to account for WebPreferences::allow_universal_access_from_file_urls). + if (request()->initiator().has_value() && + request()->initiator()->scheme() == url::kFileScheme) + return false; + return true; }
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 8d406e4..092c679e 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -720,9 +720,8 @@ if (service_worker_navigation_handle_core) { std::unique_ptr<NavigationLoaderInterceptor> service_worker_interceptor = ServiceWorkerRequestHandler::CreateForNavigation( - resource_request_->url, resource_context_, - service_worker_navigation_handle_core, *request_info, - &service_worker_provider_host_); + resource_request_->url, service_worker_navigation_handle_core, + *request_info, &service_worker_provider_host_); // The interceptor for service worker may not be created for some // reasons (e.g. the origin is not secure). if (service_worker_interceptor) @@ -1164,15 +1163,10 @@ if (!head.intercepted_by_plugin && !must_download && !known_mime_type) { // No plugin throttles intercepted the response. Ask if the plugin // registered to PluginService wants to handle the request. - // TODO(http://crbug.com/824840): Convert PluginService to run on UI. - RunOrPostTaskIfNecessary( - FROM_HERE, BrowserThread::IO, - base::BindOnce(&URLLoaderRequestController:: - CheckPluginAndContinueOnReceiveResponse, - weak_factory_.GetWeakPtr(), head, - std::move(url_loader_client_endpoints), - true /* is_download_if_not_handled_by_plugin */, - std::vector<WebPluginInfo>())); + CheckPluginAndContinueOnReceiveResponse( + head, std::move(url_loader_client_endpoints), + true /* is_download_if_not_handled_by_plugin */, + std::vector<WebPluginInfo>()); return; } #endif
diff --git a/content/browser/media/session/media_session_android.cc b/content/browser/media/session/media_session_android.cc index 232d94a..93e7d90 100644 --- a/content/browser/media/session/media_session_android.cc +++ b/content/browser/media/session/media_session_android.cc
@@ -41,8 +41,8 @@ if (contents_android) contents_android->SetMediaSession(j_media_session); - media_session::mojom::MediaSessionObserverPtr observer; - observer_binding_.Bind(mojo::MakeRequest(&observer)); + mojo::PendingRemote<media_session::mojom::MediaSessionObserver> observer; + observer_binding_.Bind(observer.InitWithNewPipeAndPassReceiver()); session->AddObserver(std::move(observer)); }
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc index 0b78bac..e8a9ac3 100644 --- a/content/browser/media/session/media_session_impl.cc +++ b/content/browser/media/session/media_session_impl.cc
@@ -255,10 +255,8 @@ images_.insert_or_assign(MediaSessionImageType::kSourceIcon, icons); - observers_.ForAllPtrs( - [this](media_session::mojom::MediaSessionObserver* observer) { - observer->MediaSessionImagesChanged(this->images_); - }); + for (auto& observer : observers_) + observer->MediaSessionImagesChanged(this->images_); } bool MediaSessionImpl::AddPlayer(MediaSessionPlayerObserver* observer, @@ -835,16 +833,17 @@ } void MediaSessionImpl::AddObserver( - media_session::mojom::MediaSessionObserverPtr observer) { - observer->MediaSessionInfoChanged(GetMediaSessionInfoSync()); - observer->MediaSessionMetadataChanged(metadata_); - observer->MediaSessionImagesChanged(images_); + mojo::PendingRemote<media_session::mojom::MediaSessionObserver> observer) { + mojo::Remote<media_session::mojom::MediaSessionObserver> + media_session_observer(std::move(observer)); + media_session_observer->MediaSessionInfoChanged(GetMediaSessionInfoSync()); + media_session_observer->MediaSessionMetadataChanged(metadata_); + media_session_observer->MediaSessionImagesChanged(images_); std::vector<media_session::mojom::MediaSessionAction> actions( actions_.begin(), actions_.end()); - observer->MediaSessionActionsChanged(actions); - - observers_.AddPtr(std::move(observer)); + media_session_observer->MediaSessionActionsChanged(actions); + observers_.Add(std::move(media_session_observer)); } void MediaSessionImpl::FinishSystemAudioFocusRequest( @@ -967,10 +966,8 @@ if (current_info == session_info_) return; - observers_.ForAllPtrs( - [¤t_info](media_session::mojom::MediaSessionObserver* observer) { - observer->MediaSessionInfoChanged(current_info.Clone()); - }); + for (auto& observer : observers_) + observer->MediaSessionInfoChanged(current_info.Clone()); delegate_->MediaSessionInfoChanged(current_info.Clone()); @@ -1186,10 +1183,8 @@ std::vector<media_session::mojom::MediaSessionAction> actions_vec( actions.begin(), actions.end()); - observers_.ForAllPtrs( - [&actions_vec](media_session::mojom::MediaSessionObserver* observer) { - observer->MediaSessionActionsChanged(actions_vec); - }); + for (auto& observer : observers_) + observer->MediaSessionActionsChanged(actions_vec); } void MediaSessionImpl::RebuildAndNotifyMetadataChanged() { @@ -1235,16 +1230,13 @@ if (!images_changed && !metadata_changed) return; + for (auto& observer : observers_) { + if (metadata_changed) + observer->MediaSessionMetadataChanged(this->metadata_); - observers_.ForAllPtrs( - [this, metadata_changed, - images_changed](media_session::mojom::MediaSessionObserver* observer) { - if (metadata_changed) - observer->MediaSessionMetadataChanged(this->metadata_); - - if (images_changed) - observer->MediaSessionImagesChanged(this->images_); - }); + if (images_changed) + observer->MediaSessionImagesChanged(this->images_); + } } WEB_CONTENTS_USER_DATA_KEY_IMPL(MediaSessionImpl)
diff --git a/content/browser/media/session/media_session_impl.h b/content/browser/media/session/media_session_impl.h index abde0ac..bd082252 100644 --- a/content/browser/media/session/media_session_impl.h +++ b/content/browser/media/session/media_session_impl.h
@@ -27,6 +27,7 @@ #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h" +#include "mojo/public/cpp/bindings/remote_set.h" #include "services/media_session/public/mojom/audio_focus.mojom.h" #if defined(OS_ANDROID) @@ -221,7 +222,8 @@ // Adds a mojo based observer to listen to events related to this session. void AddObserver( - media_session::mojom::MediaSessionObserverPtr observer) override; + mojo::PendingRemote<media_session::mojom::MediaSessionObserver> observer) + override; // Called by |AudioFocusDelegate| when an async audio focus request is // completed. @@ -419,7 +421,7 @@ // Bindings for Mojo pointers to |this| held by media route providers. mojo::BindingSet<media_session::mojom::MediaSession> bindings_; - mojo::InterfacePtrSet<media_session::mojom::MediaSessionObserver> observers_; + mojo::RemoteSet<media_session::mojom::MediaSessionObserver> observers_; WEB_CONTENTS_USER_DATA_KEY_DECL();
diff --git a/content/browser/media/session/media_session_impl_unittest.cc b/content/browser/media/session/media_session_impl_unittest.cc index 4880f1e..11349c6 100644 --- a/content/browser/media/session/media_session_impl_unittest.cc +++ b/content/browser/media/session/media_session_impl_unittest.cc
@@ -125,7 +125,7 @@ } void ClearObservers(MediaSessionImpl* session) { - session->observers_.CloseAll(); + session->observers_.Clear(); } bool HasObservers(MediaSessionImpl* session) {
diff --git a/content/browser/plugin_service_impl.h b/content/browser/plugin_service_impl.h index cb19abc..c4c0ed5 100644 --- a/content/browser/plugin_service_impl.h +++ b/content/browser/plugin_service_impl.h
@@ -147,7 +147,7 @@ int max_ppapi_processes_per_profile_ = kDefaultMaxPpapiProcessesPerProfile; - // Weak pointer; outlives us. + // Weak pointer; set during the startup on UI thread and must outlive us. PluginServiceFilter* filter_; // Used to load plugins from disk.
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index f1ada24..10344f3 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -176,6 +176,7 @@ #include "content/public/common/sandboxed_process_launcher_delegate.h" #include "content/public/common/service_names.mojom.h" #include "content/public/common/url_constants.h" +#include "content/public/common/web_preferences.h" #include "device/gamepad/gamepad_haptics_manager.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/gpu_switches.h" @@ -219,6 +220,7 @@ #include "ui/display/display_switches.h" #include "ui/gl/gl_switches.h" #include "ui/native_theme/native_theme_features.h" +#include "url/url_constants.h" #if defined(OS_ANDROID) #include "content/public/browser/android/java_interfaces.h" @@ -2430,13 +2432,14 @@ // Since this function is about to get deprecated (crbug.com/891872), it // should be fine to not add support for network isolation thus sending empty // key. - CreateURLLoaderFactory(request_initiator_site_lock, + CreateURLLoaderFactory(request_initiator_site_lock, nullptr /* preferences */, net::NetworkIsolationKey(), nullptr /* header_client */, std::move(request)); } void RenderProcessHostImpl::CreateURLLoaderFactory( const base::Optional<url::Origin>& origin, + const WebPreferences* preferences, const net::NetworkIsolationKey& network_isolation_key, network::mojom::TrustedURLLoaderHeaderClientPtrInfo header_client, network::mojom::URLLoaderFactoryRequest request) { @@ -2475,8 +2478,23 @@ base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableWebSecurity); params->network_isolation_key = network_isolation_key; - SiteIsolationPolicy::PopulateURLLoaderFactoryParamsPtrForCORB(params.get()); params->header_client = std::move(header_client); + + if (params->disable_web_security) { + // --disable-web-security also disables Cross-Origin Read Blocking (CORB). + params->is_corb_enabled = false; + } else if (preferences && + preferences->allow_universal_access_from_file_urls && + origin.has_value() && origin->scheme() == url::kFileScheme) { + // allow_universal_access_from_file_urls disables CORB (via + // |is_corb_enabled|) and CORS (via |disable_web_security|) for requests + // made from a file: |origin|. + params->is_corb_enabled = false; + params->disable_web_security = true; + } else { + params->is_corb_enabled = true; + } + network_context->CreateURLLoaderFactory(std::move(request), std::move(params)); }
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index b95e993..9284ad76 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -218,6 +218,7 @@ mojom::Renderer* GetRendererInterface() override; void CreateURLLoaderFactory( const base::Optional<url::Origin>& origin, + const WebPreferences* preferences, const net::NetworkIsolationKey& network_isolation_key, network::mojom::TrustedURLLoaderHeaderClientPtrInfo header_client, network::mojom::URLLoaderFactoryRequest request) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 6053638..a798653 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1851,8 +1851,9 @@ } BrowserAccessibilityManager* - RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManager( - BrowserAccessibilityDelegate* delegate, bool for_root_frame) { +RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManager( + BrowserAccessibilityDelegate* delegate, + bool for_root_frame) { return new BrowserAccessibilityManagerAndroid( BrowserAccessibilityManagerAndroid::GetEmptyDocument(), for_root_frame && host() ? GetWebContentsAccessibilityAndroid() : nullptr,
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index 7089548..6c689f62 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -149,7 +149,8 @@ bool down) override; void FallbackCursorModeSetCursorVisibility(bool visible) override; BrowserAccessibilityManager* CreateBrowserAccessibilityManager( - BrowserAccessibilityDelegate* delegate, bool for_root_frame) override; + BrowserAccessibilityDelegate* delegate, + bool for_root_frame) override; bool LockMouse() override; void UnlockMouse() override; void DidCreateNewRendererCompositorFrameSink(
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 1befcdd..aec7d21 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1122,7 +1122,8 @@ BrowserAccessibilityManager* RenderWidgetHostViewAura::CreateBrowserAccessibilityManager( - BrowserAccessibilityDelegate* delegate, bool for_root_frame) { + BrowserAccessibilityDelegate* delegate, + bool for_root_frame) { BrowserAccessibilityManager* manager = nullptr; #if defined(OS_WIN) manager = new BrowserAccessibilityManagerWin(
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 50b2161..86a98b25 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -155,7 +155,8 @@ InputEventAckState FilterChildGestureEvent( const blink::WebGestureEvent& gesture_event) override; BrowserAccessibilityManager* CreateBrowserAccessibilityManager( - BrowserAccessibilityDelegate* delegate, bool for_root_frame) override; + BrowserAccessibilityDelegate* delegate, + bool for_root_frame) override; gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget() override; gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() override; void SetMainFrameAXTreeID(ui::AXTreeID id) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index 5a3b90ec..f960f6c 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -459,7 +459,8 @@ BrowserAccessibilityManager* RenderWidgetHostViewBase::CreateBrowserAccessibilityManager( - BrowserAccessibilityDelegate* delegate, bool for_root_frame) { + BrowserAccessibilityDelegate* delegate, + bool for_root_frame) { NOTREACHED(); return nullptr; }
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index a5f11d9..11cd489 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -270,7 +270,8 @@ // suitable for the root frame, which may be linked to its native // window container. virtual BrowserAccessibilityManager* CreateBrowserAccessibilityManager( - BrowserAccessibilityDelegate* delegate, bool for_root_frame); + BrowserAccessibilityDelegate* delegate, + bool for_root_frame); virtual void AccessibilityShowMenu(const gfx::Point& point); virtual gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget();
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index 21a19bd..0eeacea 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -159,7 +159,8 @@ void ResetFallbackToFirstNavigationSurface() override; bool RequestRepaintForTesting() override; BrowserAccessibilityManager* CreateBrowserAccessibilityManager( - BrowserAccessibilityDelegate* delegate, bool for_root_frame) override; + BrowserAccessibilityDelegate* delegate, + bool for_root_frame) override; gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() override; gfx::NativeViewAccessible AccessibilityGetNativeViewAccessibleForWindow() override;
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index 6845707..ac6ce63 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1382,8 +1382,9 @@ } BrowserAccessibilityManager* - RenderWidgetHostViewMac::CreateBrowserAccessibilityManager( - BrowserAccessibilityDelegate* delegate, bool for_root_frame) { +RenderWidgetHostViewMac::CreateBrowserAccessibilityManager( + BrowserAccessibilityDelegate* delegate, + bool for_root_frame) { return new BrowserAccessibilityManagerMac( BrowserAccessibilityManagerMac::GetEmptyDocument(), delegate); }
diff --git a/content/browser/renderer_interface_binders.cc b/content/browser/renderer_interface_binders.cc index 32e5aa4e..442280a2 100644 --- a/content/browser/renderer_interface_binders.cc +++ b/content/browser/renderer_interface_binders.cc
@@ -21,7 +21,7 @@ #include "content/browser/quota_dispatcher_host.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/storage_partition_impl.h" -#include "content/browser/websockets/websocket_manager.h" +#include "content/browser/websockets/websocket_connector_impl.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" @@ -31,6 +31,7 @@ #include "content/public/common/content_switches.h" #include "media/mojo/interfaces/video_decode_perf_history.mojom.h" #include "media/mojo/services/video_decode_perf_history.h" +#include "mojo/public/cpp/bindings/strong_binding.h" #include "services/device/public/mojom/constants.mojom.h" #include "services/device/public/mojom/vibration_manager.mojom.h" #include "services/service_manager/public/cpp/binder_registry.h" @@ -83,9 +84,10 @@ private: void InitializeParameterizedBinderRegistry(); - static void CreateWebSocket(network::mojom::WebSocketRequest request, - RenderProcessHost* host, - const url::Origin& origin); + static void CreateWebSocketConnector( + blink::mojom::WebSocketConnectorRequest request, + RenderProcessHost* host, + const url::Origin& origin); service_manager::BinderRegistryWithArgs<RenderProcessHost*, const url::Origin&> @@ -131,7 +133,7 @@ // TODO(nhiroki): Consider moving this into SharedWorkerHost and // ServiceWorkerProviderHost. parameterized_binder_registry_.AddInterface( - base::BindRepeating(CreateWebSocket)); + base::BindRepeating(CreateWebSocketConnector)); parameterized_binder_registry_.AddInterface( base::Bind([](payments::mojom::PaymentManagerRequest request, @@ -226,15 +228,15 @@ return *binders; } -void RendererInterfaceBinders::CreateWebSocket( - network::mojom::WebSocketRequest request, +void RendererInterfaceBinders::CreateWebSocketConnector( + blink::mojom::WebSocketConnectorRequest request, RenderProcessHost* host, const url::Origin& origin) { // TODO(jam): is it ok to not send extraHeaders for sockets created from // shared and service workers? - WebSocketManager::CreateWebSocket(host->GetID(), MSG_ROUTING_NONE, origin, - network::mojom::kWebSocketOptionNone, - nullptr, nullptr, std::move(request)); + mojo::MakeStrongBinding(std::make_unique<WebSocketConnectorImpl>( + host->GetID(), MSG_ROUTING_NONE, origin), + std::move(request)); } } // namespace
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc index e1f73390..0b9c5b7d 100644 --- a/content/browser/security_exploit_browsertest.cc +++ b/content/browser/security_exploit_browsertest.cc
@@ -313,8 +313,9 @@ network::mojom::URLLoaderClientPtrInfo client) { network::mojom::URLLoaderFactoryPtr factory; frame->GetProcess()->CreateURLLoaderFactory( - frame->GetLastCommittedOrigin(), net::NetworkIsolationKey(), - nullptr /* header_client */, mojo::MakeRequest(&factory)); + frame->GetLastCommittedOrigin(), nullptr /* preferences */, + net::NetworkIsolationKey(), nullptr /* header_client */, + mojo::MakeRequest(&factory)); factory->CreateLoaderAndStart( std::move(request), route_id, request_id, network::mojom::kURLLoadOptionNone, resource_request,
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc index 6558cc1..88b8aaa 100644 --- a/content/browser/service_worker/embedded_worker_instance.cc +++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -996,12 +996,12 @@ // script's origin. if (GetNetworkFactoryCallbackForTest().is_null()) { rph->CreateURLLoaderFactory( - origin, net::NetworkIsolationKey() /* network_isolation_key */, + origin, nullptr /* preferences */, net::NetworkIsolationKey(), std::move(default_header_client), std::move(default_factory_request)); } else { network::mojom::URLLoaderFactoryPtr original_factory; rph->CreateURLLoaderFactory( - origin, net::NetworkIsolationKey() /* network_isolation_key */, + origin, nullptr /* preferences */, net::NetworkIsolationKey(), std::move(default_header_client), mojo::MakeRequest(&original_factory)); GetNetworkFactoryCallbackForTest().Run(std::move(default_factory_request), rph->GetID(),
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.cc b/content/browser/service_worker/service_worker_controllee_request_handler.cc index 45f673e..2ac8aa45 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler.cc +++ b/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -91,24 +91,10 @@ ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler( base::WeakPtr<ServiceWorkerContextCore> context, base::WeakPtr<ServiceWorkerProviderHost> provider_host, - network::mojom::RequestMode request_mode, - network::mojom::CredentialsMode credentials_mode, - network::mojom::RedirectMode redirect_mode, - const std::string& integrity, - bool keepalive, - ResourceType resource_type, - blink::mojom::RequestContextType request_context_type, - scoped_refptr<network::ResourceRequestBody> body) + ResourceType resource_type) : context_(std::move(context)), provider_host_(std::move(provider_host)), resource_type_(resource_type), - request_mode_(request_mode), - credentials_mode_(credentials_mode), - redirect_mode_(redirect_mode), - integrity_(integrity), - keepalive_(keepalive), - request_context_type_(request_context_type), - body_(std::move(body)), force_update_started_(false), weak_factory_(this) { DCHECK(ServiceWorkerUtils::IsMainResourceType(resource_type));
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.h b/content/browser/service_worker/service_worker_controllee_request_handler.h index fb598361..3d819e6 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler.h +++ b/content/browser/service_worker/service_worker_controllee_request_handler.h
@@ -22,10 +22,6 @@ #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" #include "url/gurl.h" -namespace network { -class ResourceRequestBody; -} - namespace content { class ServiceWorkerContextCore; @@ -43,14 +39,7 @@ ServiceWorkerControlleeRequestHandler( base::WeakPtr<ServiceWorkerContextCore> context, base::WeakPtr<ServiceWorkerProviderHost> provider_host, - network::mojom::RequestMode request_mode, - network::mojom::CredentialsMode credentials_mode, - network::mojom::RedirectMode redirect_mode, - const std::string& integrity, - bool keepalive, - ResourceType resource_type, - blink::mojom::RequestContextType request_context_type, - scoped_refptr<network::ResourceRequestBody> body); + ResourceType resource_type); ~ServiceWorkerControlleeRequestHandler() override; // NavigationLoaderInterceptor overrides: @@ -124,13 +113,6 @@ const base::WeakPtr<ServiceWorkerProviderHost> provider_host_; const ResourceType resource_type_; std::unique_ptr<ServiceWorkerNavigationLoaderWrapper> loader_wrapper_; - network::mojom::RequestMode request_mode_; - network::mojom::CredentialsMode credentials_mode_; - network::mojom::RedirectMode redirect_mode_; - std::string integrity_; - const bool keepalive_; - blink::mojom::RequestContextType request_context_type_; - scoped_refptr<network::ResourceRequestBody> body_; ResourceContext* resource_context_; GURL stripped_url_; bool force_update_started_;
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc index 3858f0ec..1baf2c31 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc +++ b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
@@ -56,14 +56,7 @@ handler_(new ServiceWorkerControlleeRequestHandler( test->context()->AsWeakPtr(), test->provider_host_, - request_mode, - network::mojom::CredentialsMode::kOmit, - network::mojom::RedirectMode::kFollow, - std::string() /* integrity */, - false /* keepalive */, - type, - blink::mojom::RequestContextType::HYPERLINK, - scoped_refptr<network::ResourceRequestBody>())) {} + type)) {} ServiceWorkerNavigationLoader* MaybeCreateLoader() { network::ResourceRequest resource_request;
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index 0f28cbdc..01ced4dd 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -631,14 +631,7 @@ std::unique_ptr<NavigationLoaderInterceptor> ServiceWorkerProviderHost::CreateLoaderInterceptor( - network::mojom::RequestMode request_mode, - network::mojom::CredentialsMode credentials_mode, - network::mojom::RedirectMode redirect_mode, - const std::string& integrity, - bool keepalive, ResourceType resource_type, - blink::mojom::RequestContextType request_context_type, - scoped_refptr<network::ResourceRequestBody> body, bool skip_service_worker) { if (skip_service_worker) { // Use an interceptor that just observes redirects so the resulting @@ -647,9 +640,7 @@ } return std::make_unique<ServiceWorkerControlleeRequestHandler>( - context_, AsWeakPtr(), request_mode, credentials_mode, redirect_mode, - integrity, keepalive, resource_type, request_context_type, - std::move(body)); + context_, AsWeakPtr(), resource_type); } base::WeakPtr<ServiceWorkerObjectHost>
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index 7911b526..4f18627 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -36,10 +36,6 @@ #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom.h" -namespace network { -class ResourceRequestBody; -} - namespace service_worker_object_host_unittest { class ServiceWorkerObjectHostTest; } @@ -295,14 +291,7 @@ // Returns an interceptor for a main resource request. May return nullptr if // the request doesn't require interception. std::unique_ptr<NavigationLoaderInterceptor> CreateLoaderInterceptor( - network::mojom::RequestMode request_mode, - network::mojom::CredentialsMode credentials_mode, - network::mojom::RedirectMode redirect_mode, - const std::string& integrity, - bool keepalive, ResourceType resource_type, - blink::mojom::RequestContextType request_context_type, - scoped_refptr<network::ResourceRequestBody> body, bool skip_service_worker); // Returns an object info representing |registration|. The object info holds a
diff --git a/content/browser/service_worker/service_worker_request_handler.cc b/content/browser/service_worker/service_worker_request_handler.cc index d1ddad3e..3660410e 100644 --- a/content/browser/service_worker/service_worker_request_handler.cc +++ b/content/browser/service_worker/service_worker_request_handler.cc
@@ -10,17 +10,16 @@ #include "base/command_line.h" #include "base/macros.h" #include "content/browser/frame_host/navigation_request_info.h" -#include "content/browser/loader/navigation_loader_interceptor.h" #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_controllee_request_handler.h" #include "content/browser/service_worker/service_worker_navigation_handle_core.h" #include "content/browser/service_worker/service_worker_provider_host.h" -#include "content/public/browser/resource_context.h" #include "content/public/common/origin_util.h" #include "content/public/common/url_constants.h" #include "net/base/url_util.h" -#include "services/network/public/cpp/resource_request_body.h" +#include "services/network/public/cpp/resource_request.h" +#include "url/gurl.h" namespace content { @@ -40,7 +39,6 @@ std::unique_ptr<NavigationLoaderInterceptor> ServiceWorkerRequestHandler::CreateForNavigation( const GURL& url, - ResourceContext* resource_context, ServiceWorkerNavigationHandleCore* navigation_handle_core, const NavigationRequestInfo& request_info, base::WeakPtr<ServiceWorkerProviderHost>* out_provider_host) { @@ -72,13 +70,7 @@ ? ResourceType::kMainFrame : ResourceType::kSubFrame; return (*out_provider_host) - ->CreateLoaderInterceptor(network::mojom::RequestMode::kNavigate, - network::mojom::CredentialsMode::kInclude, - network::mojom::RedirectMode::kManual, - std::string() /* integrity */, - false /* keepalive */, resource_type, - request_info.begin_params->request_context_type, - request_info.common_params.post_data, + ->CreateLoaderInterceptor(resource_type, request_info.begin_params->skip_service_worker); } @@ -102,14 +94,8 @@ } return host->CreateLoaderInterceptor( - resource_request.mode, resource_request.credentials_mode, - resource_request.redirect_mode, resource_request.fetch_integrity, - resource_request.keepalive, static_cast<ResourceType>(resource_request.resource_type), - resource_request.resource_type == static_cast<int>(ResourceType::kWorker) - ? blink::mojom::RequestContextType::WORKER - : blink::mojom::RequestContextType::SHARED_WORKER, - resource_request.request_body, resource_request.skip_service_worker); + resource_request.skip_service_worker); } } // namespace content
diff --git a/content/browser/service_worker/service_worker_request_handler.h b/content/browser/service_worker/service_worker_request_handler.h index b7824f7..9327173 100644 --- a/content/browser/service_worker/service_worker_request_handler.h +++ b/content/browser/service_worker/service_worker_request_handler.h
@@ -7,17 +7,19 @@ #include <memory> -#include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "content/browser/loader/navigation_loader_interceptor.h" #include "content/common/content_export.h" -#include "content/common/service_worker/service_worker_types.h" -#include "content/public/common/resource_type.h" + +class GURL; + +namespace network { +struct ResourceRequest; +} // namespace network namespace content { -class ResourceContext; class ServiceWorkerNavigationHandleCore; class ServiceWorkerProviderHost; struct NavigationRequestInfo; @@ -32,7 +34,6 @@ // if the navigation cannot use service workers. static std::unique_ptr<NavigationLoaderInterceptor> CreateForNavigation( const GURL& url, - ResourceContext* resource_context, ServiceWorkerNavigationHandleCore* navigation_handle_core, const NavigationRequestInfo& request_info, base::WeakPtr<ServiceWorkerProviderHost>* out_provider_host);
diff --git a/content/browser/service_worker/service_worker_request_handler_unittest.cc b/content/browser/service_worker/service_worker_request_handler_unittest.cc index 39e4c6c..0884efc 100644 --- a/content/browser/service_worker/service_worker_request_handler_unittest.cc +++ b/content/browser/service_worker/service_worker_request_handler_unittest.cc
@@ -94,8 +94,7 @@ base::UnguessableToken::Create() /* devtools_frame_token */); std::unique_ptr<NavigationLoaderInterceptor> interceptor = ServiceWorkerRequestHandler::CreateForNavigation( - GURL(url), nullptr /* resource_context */, - navigation_handle_core.get(), request_info, + GURL(url), navigation_handle_core.get(), request_info, &service_worker_provider_host); EXPECT_EQ(expected_handler_created, !!interceptor.get()); }
diff --git a/content/browser/web_contents/javascript_dialog_navigation_deferrer.cc b/content/browser/web_contents/javascript_dialog_navigation_deferrer.cc new file mode 100644 index 0000000..edfb2c7 --- /dev/null +++ b/content/browser/web_contents/javascript_dialog_navigation_deferrer.cc
@@ -0,0 +1,69 @@ +// 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 "content/browser/web_contents/javascript_dialog_navigation_deferrer.h" + +#include "content/browser/frame_host/navigation_handle_impl.h" +#include "content/browser/web_contents/web_contents_impl.h" + +namespace content { + +// static +std::unique_ptr<NavigationThrottle> +JavaScriptDialogNavigationThrottle::MaybeCreateThrottleFor( + NavigationHandle* navigation_handle) { + // Don't prevent the user from navigating away from the page. + if (navigation_handle->IsInMainFrame() && + (!navigation_handle->IsRendererInitiated() || + navigation_handle->HasUserGesture())) { + return nullptr; + } + + return std::make_unique<JavaScriptDialogNavigationThrottle>( + navigation_handle); +} + +JavaScriptDialogNavigationThrottle::JavaScriptDialogNavigationThrottle( + NavigationHandle* navigation_handle) + : NavigationThrottle(navigation_handle) {} + +NavigationThrottle::ThrottleCheckResult +JavaScriptDialogNavigationThrottle::WillProcessResponse() { + // Don't defer downloads, which don't leave the page. + if (navigation_handle()->IsDownload()) + return PROCEED; + + JavaScriptDialogNavigationDeferrer* deferrer = + static_cast<WebContentsImpl*>(navigation_handle()->GetWebContents()) + ->GetJavaScriptDialogNavigationDeferrer(); + if (!deferrer) + return PROCEED; + + deferrer->AddThrottle(this); + return DEFER; +} + +void JavaScriptDialogNavigationThrottle::Resume() { + NavigationThrottle::Resume(); +} + +const char* JavaScriptDialogNavigationThrottle::GetNameForLogging() { + return "JavaScriptDialogNavigationThrottle"; +} + +JavaScriptDialogNavigationDeferrer::JavaScriptDialogNavigationDeferrer() {} + +JavaScriptDialogNavigationDeferrer::~JavaScriptDialogNavigationDeferrer() { + for (auto& throttle : throttles_) { + if (throttle) + throttle->Resume(); + } +} + +void JavaScriptDialogNavigationDeferrer::AddThrottle( + JavaScriptDialogNavigationThrottle* throttle) { + throttles_.push_back(throttle->AsWeakPtr()); +} + +} // namespace content
diff --git a/content/browser/web_contents/javascript_dialog_navigation_deferrer.h b/content/browser/web_contents/javascript_dialog_navigation_deferrer.h new file mode 100644 index 0000000..1e5e09de --- /dev/null +++ b/content/browser/web_contents/javascript_dialog_navigation_deferrer.h
@@ -0,0 +1,64 @@ +// 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 CONTENT_BROWSER_WEB_CONTENTS_JAVASCRIPT_DIALOG_NAVIGATION_DEFERRER_H_ +#define CONTENT_BROWSER_WEB_CONTENTS_JAVASCRIPT_DIALOG_NAVIGATION_DEFERRER_H_ + +#include <memory> +#include <vector> + +#include "base/memory/weak_ptr.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/navigation_throttle.h" + +namespace content { + +// Throttle registered for most navigations in a WebContents, so that they can +// be deferred during a dialog if a JavaScriptDialogNavigationDeferrer (below) +// exists at response time. +class JavaScriptDialogNavigationThrottle + : public NavigationThrottle, + public base::SupportsWeakPtr<JavaScriptDialogNavigationThrottle> { + public: + // Registers a throttle for most navigations in a tab, unless they target the + // main frame with a user gesture or will be a download. + static std::unique_ptr<NavigationThrottle> MaybeCreateThrottleFor( + NavigationHandle* navigation_handle); + explicit JavaScriptDialogNavigationThrottle( + NavigationHandle* navigation_handle); + ~JavaScriptDialogNavigationThrottle() override = default; + + // NavigationThrottle methods: + ThrottleCheckResult WillProcessResponse() override; + void Resume() override; + const char* GetNameForLogging() override; + + private: + DISALLOW_COPY_AND_ASSIGN(JavaScriptDialogNavigationThrottle); +}; + +// Prevents navigations in a WebContents that is showing a modal dialog, +// unless it is a user-initiated main frame navigation (in which case the dialog +// will be auto-dismissed when the navigation completes). +class JavaScriptDialogNavigationDeferrer { + public: + JavaScriptDialogNavigationDeferrer(); + ~JavaScriptDialogNavigationDeferrer(); + + private: + friend class JavaScriptDialogNavigationThrottle; + + // Only called by JavaScriptDialogNavigationThrottle::WillProcessResponse, in + // the case that a dialog is showing at response time. + void AddThrottle(JavaScriptDialogNavigationThrottle* throttle); + + // Stores a weak reference to a throttle for each deferred navigation. + std::vector<base::WeakPtr<JavaScriptDialogNavigationThrottle>> throttles_; + + DISALLOW_COPY_AND_ASSIGN(JavaScriptDialogNavigationDeferrer); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_WEB_CONTENTS_JAVASCRIPT_DIALOG_NAVIGATION_DEFERRER_H_
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index ba96482..37e9397c 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -84,6 +84,7 @@ #include "content/browser/renderer_host/text_input_manager.h" #include "content/browser/screen_orientation/screen_orientation_provider.h" #include "content/browser/site_instance_impl.h" +#include "content/browser/web_contents/javascript_dialog_navigation_deferrer.h" #include "content/browser/web_contents/web_contents_view_child_frame.h" #include "content/browser/web_contents/web_contents_view_guest.h" #include "content/browser/webui/generic_handler.h" @@ -4326,6 +4327,8 @@ display_cutout_host_impl_->DidFinishNavigation(navigation_handle); if (navigation_handle->HasCommitted()) { + // TODO(domfarolino, dmazzoni): Do this using WebContentsObserver. See + // https://crbug.com/981271. BrowserAccessibilityManager* manager = static_cast<RenderFrameHostImpl*>( navigation_handle->GetRenderFrameHost()) @@ -5365,6 +5368,10 @@ if (delegate_) dialog_manager_ = delegate_->GetJavaScriptDialogManager(this); + // While a JS message dialog is showing, defer commits in this WebContents. + javascript_dialog_navigation_deferrer_ = + std::make_unique<JavaScriptDialogNavigationDeferrer>(); + // Suppress JavaScript dialogs when requested. Also suppress messages when // showing an interstitial as it's shown over the previous page and we don't // want the hidden page's dialogs to interfere with the interstitial. @@ -5442,6 +5449,11 @@ if (delegate_) dialog_manager_ = delegate_->GetJavaScriptDialogManager(this); + // While a JS beforeunload dialog is showing, defer commits in this + // WebContents. + javascript_dialog_navigation_deferrer_ = + std::make_unique<JavaScriptDialogNavigationDeferrer>(); + bool should_suppress = ShowingInterstitialPage() || !rfhi->is_active() || (delegate_ && delegate_->ShouldSuppressDialogs(this)); bool has_non_devtools_handlers = delegate_ && dialog_manager_; @@ -5809,8 +5821,8 @@ // Notify accessibility that the user is navigating away from the // current document. - // - // TODO(dmazzoni): do this using a WebContentsObserver. + // TODO(domfarolino, dmazzoni): Do this using WebContentsObserver. See + // https://crbug.com/981271. BrowserAccessibilityManager* manager = frame_tree_node->current_frame_host()->browser_accessibility_manager(); if (manager) @@ -5881,8 +5893,22 @@ std::vector<std::unique_ptr<NavigationThrottle>> WebContentsImpl::CreateThrottlesForNavigation( NavigationHandle* navigation_handle) { - return GetContentClient()->browser()->CreateThrottlesForNavigation( + auto throttles = GetContentClient()->browser()->CreateThrottlesForNavigation( navigation_handle); + + // This is not a normal place to be adding a throttle. However, in the case + // javascript dialogs, related logic is present in the web_contents/ layer, + // and the purpose of the throttle is to ensure that navigation commits are + // deferred for the entire WebContents. Most throttles are either added by + // the embederrer outside of content/, or are per-frame and added by + // NavigationThrottleRunner. + std::unique_ptr<content::NavigationThrottle> dialog_throttle = + JavaScriptDialogNavigationThrottle::MaybeCreateThrottleFor( + navigation_handle); + if (dialog_throttle) + throttles.push_back(std::move(dialog_throttle)); + + return throttles; } std::unique_ptr<NavigationUIData> WebContentsImpl::GetNavigationUIData( @@ -6595,6 +6621,8 @@ render_frame_id); last_dialog_suppressed_ = dialog_was_suppressed; + javascript_dialog_navigation_deferrer_.reset(); + if (is_showing_before_unload_dialog_ && !success) { // It is possible for the current RenderFrameHost to have changed in the // meantime. Do not reset the navigation state in that case.
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index b82411c..210b672 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -88,6 +88,7 @@ class FindRequestManager; class InterstitialPageImpl; class JavaScriptDialogManager; +class JavaScriptDialogNavigationDeferrer; class LoaderIOThreadNotifier; class ManifestManagerHost; class MediaWebContentsObserver; @@ -1056,6 +1057,10 @@ // call this directly. void OnAppCacheAccessed(const GURL& manifest_url, bool blocked_by_policy); + JavaScriptDialogNavigationDeferrer* GetJavaScriptDialogNavigationDeferrer() { + return javascript_dialog_navigation_deferrer_.get(); + } + private: friend class WebContentsObserver; friend class WebContents; // To implement factory methods. @@ -1907,6 +1912,11 @@ // intervention to be disabled for pdfs (crbug.com/965434). bool had_inner_webcontents_; + // Prevents navigations in this contents while a javascript modal dialog is + // showing. + std::unique_ptr<JavaScriptDialogNavigationDeferrer> + javascript_dialog_navigation_deferrer_; + base::WeakPtrFactory<WebContentsImpl> loading_weak_factory_; base::WeakPtrFactory<WebContentsImpl> weak_factory_;
diff --git a/content/browser/websockets/websocket_connector_impl.cc b/content/browser/websockets/websocket_connector_impl.cc new file mode 100644 index 0000000..5527614 --- /dev/null +++ b/content/browser/websockets/websocket_connector_impl.cc
@@ -0,0 +1,102 @@ +// 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 "content/browser/websockets/websocket_connector_impl.h" + +#include "content/browser/frame_host/render_frame_host_impl.h" +#include "content/browser/renderer_host/render_process_host_impl.h" +#include "content/browser/websockets/websocket_manager.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/storage_partition.h" +#include "services/network/public/cpp/features.h" +#include "url/gurl.h" + +namespace content { + +WebSocketConnectorImpl::WebSocketConnectorImpl(int process_id, + int frame_id, + const url::Origin& origin) + : process_id_(process_id), frame_id_(frame_id), origin_(origin) {} + +WebSocketConnectorImpl::~WebSocketConnectorImpl() = default; + +void WebSocketConnectorImpl::Connect( + const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + network::mojom::WebSocketHandshakeClientPtr handshake_client, + network::mojom::WebSocketClientPtr websocket_client) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + RenderProcessHost* process = RenderProcessHost::FromID(process_id_); + if (!process) { + return; + } + RenderFrameHost* frame = RenderFrameHost::FromID(process_id_, frame_id_); + const uint32_t options = + GetContentClient()->browser()->GetWebSocketOptions(frame); + + if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) { + WebSocketManager::CreateWebSocket( + url, requested_protocols, site_for_cookies, user_agent, process, + frame_id_, origin_, options, std::move(handshake_client), + std::move(websocket_client)); + return; + } + if (GetContentClient()->browser()->WillInterceptWebSocket(frame)) { + GetContentClient()->browser()->CreateWebSocket( + frame, + base::BindOnce(ConnectCalledByContentBrowserClient, requested_protocols, + site_for_cookies, process_id_, frame_id_, origin_, + options, std::move(websocket_client)), + url, site_for_cookies, user_agent, std::move(handshake_client)); + return; + } + std::vector<network::mojom::HttpHeaderPtr> headers; + if (user_agent) { + headers.push_back(network::mojom::HttpHeader::New( + net::HttpRequestHeaders::kUserAgent, *user_agent)); + } + process->GetStoragePartition()->GetNetworkContext()->CreateWebSocket( + url, requested_protocols, site_for_cookies, std::move(headers), + process_id_, frame_id_, origin_, options, std::move(handshake_client), + std::move(websocket_client), nullptr, nullptr); +} + +void WebSocketConnectorImpl::ConnectCalledByContentBrowserClient( + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + int process_id, + int frame_id, + const url::Origin& origin, + uint32_t options, + network::mojom::WebSocketClientPtr websocket_client, + const GURL& url, + std::vector<network::mojom::HttpHeaderPtr> additional_headers, + network::mojom::WebSocketHandshakeClientPtr handshake_client, + network::mojom::AuthenticationHandlerPtr auth_handler, + network::mojom::TrustedHeaderClientPtr trusted_header_client) { + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::UI}, + base::BindOnce(ConnectCalledByContentBrowserClient, requested_protocols, + site_for_cookies, process_id, frame_id, origin, options, + std::move(websocket_client), url, + std::move(additional_headers), + std::move(handshake_client), std::move(auth_handler), + std::move(trusted_header_client))); + return; + } + + RenderProcessHost* process = RenderProcessHost::FromID(process_id); + if (!process) { + return; + } + process->GetStoragePartition()->GetNetworkContext()->CreateWebSocket( + url, requested_protocols, site_for_cookies, std::move(additional_headers), + process_id, frame_id, origin, options, std::move(handshake_client), + std::move(websocket_client), std::move(auth_handler), + std::move(trusted_header_client)); +} +} // namespace content
diff --git a/content/browser/websockets/websocket_connector_impl.h b/content/browser/websockets/websocket_connector_impl.h new file mode 100644 index 0000000..e57b4c30 --- /dev/null +++ b/content/browser/websockets/websocket_connector_impl.h
@@ -0,0 +1,66 @@ +// 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 CONTENT_BROWSER_WEBSOCKETS_WEBSOCKET_CONNECTOR_IMPL_H_ +#define CONTENT_BROWSER_WEBSOCKETS_WEBSOCKET_CONNECTOR_IMPL_H_ + +#include <string> +#include <vector> +#include "base/optional.h" +#include "content/public/browser/content_browser_client.h" +#include "services/network/public/mojom/network_context.mojom.h" +#include "services/network/public/mojom/websocket.mojom.h" +#include "third_party/blink/public/mojom/websockets/websocket_connector.mojom.h" +#include "url/origin.h" + +class GURL; + +namespace content { + +class WebSocketConnectorImpl final : public blink::mojom::WebSocketConnector { + public: + using WebSocketFactory = ContentBrowserClient::WebSocketFactory; + + // Called on the UI thread. + // - For frames, |frame_id| should be their own id. + // - For dedicated workers, |frame_id| should be its response document's + // frame's id. + // - For shared workers and service workers, |frame_id| should be + // MSG_ROUTING_NONE because they do not have a frame. + WebSocketConnectorImpl(int process_id, + int frame_id, + const url::Origin& origin); + ~WebSocketConnectorImpl() override; + + // WebSocketConnector implementation + void Connect(const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + network::mojom::WebSocketHandshakeClientPtr handshake_client, + network::mojom::WebSocketClientPtr websocket_client) override; + + private: + static void ConnectCalledByContentBrowserClient( + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + int process_id, + int frame_id, + const url::Origin& origin, + uint32_t options, + network::mojom::WebSocketClientPtr websocket_client, + const GURL& url, + std::vector<network::mojom::HttpHeaderPtr> additional_headers, + network::mojom::WebSocketHandshakeClientPtr handshake_client, + network::mojom::AuthenticationHandlerPtr auth_handler, + network::mojom::TrustedHeaderClientPtr trusted_header_client); + + const int process_id_; + const int frame_id_; + const url::Origin origin_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_WEBSOCKETS_WEBSOCKET_CONNECTOR_IMPL_H_
diff --git a/content/browser/websockets/websocket_manager.cc b/content/browser/websockets/websocket_manager.cc index ebe947e..3a2d411 100644 --- a/content/browser/websockets/websocket_manager.cc +++ b/content/browser/websockets/websocket_manager.cc
@@ -164,52 +164,39 @@ // static void WebSocketManager::CreateWebSocket( - int process_id, - int frame_id, - url::Origin origin, + const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + RenderProcessHost* process, + int32_t frame_id, + const url::Origin& origin, uint32_t options, - network::mojom::AuthenticationHandlerPtr auth_handler, - network::mojom::TrustedHeaderClientPtr header_client, - network::mojom::WebSocketRequest request) { + network::mojom::WebSocketHandshakeClientPtr handshake_client, + network::mojom::WebSocketClientPtr websocket_client) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + StoragePartition* storage_partition = process->GetStoragePartition(); + const int process_id = process->GetID(); - RenderProcessHost* host = RenderProcessHost::FromID(process_id); - DCHECK(host); - - if (base::FeatureList::IsEnabled(network::features::kNetworkService)) { - StoragePartition* storage_partition = host->GetStoragePartition(); - network::mojom::NetworkContext* network_context = - storage_partition->GetNetworkContext(); - network_context->CreateWebSocket(std::move(request), process_id, frame_id, - origin, options, std::move(auth_handler), - std::move(header_client)); - return; - } - // |auth_handler| and |header_client| are provided only for the network - // service path. - DCHECK(!auth_handler); - DCHECK(!header_client); - - // Maintain a WebSocketManager per RenderProcessHost. While the instance of - // WebSocketManager is allocated on the UI thread, it must only be used and - // deleted from the IO thread. - + // Maintain a WebSocketManager per RenderProcessHost. While the instance + // of WebSocketManager is allocated on the UI thread, it must only be used + // and deleted from the IO thread. Handle* handle = - static_cast<Handle*>(host->GetUserData(kWebSocketManagerKeyName)); + static_cast<Handle*>(process->GetUserData(kWebSocketManagerKeyName)); if (!handle) { - handle = new Handle( - new WebSocketManager(process_id, host->GetStoragePartition())); - host->SetUserData(kWebSocketManagerKeyName, base::WrapUnique(handle)); - host->AddObserver(handle); - } else { - DCHECK(handle->manager()); + handle = new Handle(new WebSocketManager(process_id, storage_partition)); + process->SetUserData(kWebSocketManagerKeyName, base::WrapUnique(handle)); + process->AddObserver(handle); } + DCHECK(handle->manager()); base::PostTaskWithTraits( FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&WebSocketManager::DoCreateWebSocket, - base::Unretained(handle->manager()), frame_id, - std::move(origin), options, std::move(request))); + base::BindOnce( + &WebSocketManager::DoCreateWebSocket, + base::Unretained(handle->manager()), url, requested_protocols, + site_for_cookies, user_agent, frame_id, origin, options, + handshake_client.PassInterface(), websocket_client.PassInterface())); } WebSocketManager::WebSocketManager(int process_id, @@ -240,34 +227,41 @@ } void WebSocketManager::DoCreateWebSocket( - int frame_id, - url::Origin origin, + const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + int32_t frame_id, + const url::Origin& origin, uint32_t options, - network::mojom::WebSocketRequest request) { + network::mojom::WebSocketHandshakeClientPtrInfo handshake_client_info, + network::mojom::WebSocketClientPtrInfo websocket_client_info) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + auto handshake_client = mojo::MakeProxy(std::move(handshake_client_info)); + auto websocket_client = mojo::MakeProxy(std::move(websocket_client_info)); + if (throttler_.HasTooManyPendingConnections()) { // Too many websockets! - request.ResetWithReason( + handshake_client.ResetWithReason( network::mojom::WebSocket::kInsufficientResources, "Error in connection establishment: net::ERR_INSUFFICIENT_RESOURCES"); return; } if (context_destroyed_) { - request.ResetWithReason( + handshake_client.ResetWithReason( network::mojom::WebSocket::kInsufficientResources, "Error in connection establishment: net::ERR_UNEXPECTED"); return; } - // Keep all network::WebSockets alive until either the client drops its // connection (see OnLostConnectionToClient) or we need to shutdown. - impls_.insert(DoCreateWebSocketInternal( - std::make_unique<Delegate>(this), std::move(request), - throttler_.IssuePendingConnectionTracker(), process_id_, frame_id, - std::move(origin), options, throttler_.CalculateDelay())); + std::make_unique<Delegate>(this), url, requested_protocols, + site_for_cookies, user_agent, frame_id, origin, options, + std::move(handshake_client), std::move(websocket_client), + throttler_.IssuePendingConnectionTracker(), throttler_.CalculateDelay())); if (!throttling_period_timer_.IsRunning()) { throttling_period_timer_.Start( @@ -286,17 +280,27 @@ std::unique_ptr<network::WebSocket> WebSocketManager::DoCreateWebSocketInternal( std::unique_ptr<network::WebSocket::Delegate> delegate, - network::mojom::WebSocketRequest request, - network::WebSocketThrottler::PendingConnection pending_connection_tracker, - int child_id, - int frame_id, - url::Origin origin, + const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + int32_t frame_id, + const url::Origin& origin, uint32_t options, + network::mojom::WebSocketHandshakeClientPtr handshake_client, + network::mojom::WebSocketClientPtr websocket_client, + network::WebSocketThrottler::PendingConnection pending_connection_tracker, base::TimeDelta delay) { + std::vector<network::mojom::HttpHeaderPtr> headers; + if (user_agent) { + headers.push_back(network::mojom::HttpHeader::New( + net::HttpRequestHeaders::kUserAgent, *user_agent)); + } return std::make_unique<network::WebSocket>( - std::move(delegate), std::move(request), nullptr, nullptr, - std::move(pending_connection_tracker), child_id, frame_id, - std::move(origin), options, delay); + std::move(delegate), url, requested_protocols, site_for_cookies, + std::move(headers), process_id_, frame_id, origin, options, + std::move(handshake_client), std::move(websocket_client), nullptr, + nullptr, std::move(pending_connection_tracker), delay); } net::URLRequestContext* WebSocketManager::GetURLRequestContext() {
diff --git a/content/browser/websockets/websocket_manager.h b/content/browser/websockets/websocket_manager.h index 1a0a9ced..d4b0c94 100644 --- a/content/browser/websockets/websocket_manager.h +++ b/content/browser/websockets/websocket_manager.h
@@ -21,6 +21,7 @@ namespace content { class StoragePartition; +class RenderProcessHost; // The WebSocketManager is a per child process instance that manages the // lifecycle of network::WebSocket objects. It is responsible for creating @@ -29,23 +30,23 @@ class CONTENT_EXPORT WebSocketManager : public net::URLRequestContextGetterObserver { public: - // Called on the UI thread: create a websocket. - // - For frames, |frame_id| should be their own id. - // - For dedicated workers, |frame_id| should be its parent frame's id. - // - For shared workers and service workers, |frame_id| should be - // MSG_ROUTING_NONE because they do not have a frame. static void CreateWebSocket( - int process_id, - int frame_id, - url::Origin origin, + const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + RenderProcessHost* process, + int32_t frame_id, + const url::Origin& origin, uint32_t options, - network::mojom::AuthenticationHandlerPtr auth_handler, - network::mojom::TrustedHeaderClientPtr header_client, - network::mojom::WebSocketRequest request); + network::mojom::WebSocketHandshakeClientPtr handshake_client, + network::mojom::WebSocketClientPtr client); // net::URLRequestContextGetterObserver implementation. void OnContextShuttingDown() override; + size_t num_sockets() const { return impls_.size(); } + protected: class Delegate; class Handle; @@ -55,23 +56,32 @@ WebSocketManager(int process_id, StoragePartition* storage_partition); // All other methods must run on the IO thread. - ~WebSocketManager() override; - void DoCreateWebSocket(int frame_id, - url::Origin origin, - uint32_t options, - network::mojom::WebSocketRequest request); + void DoCreateWebSocket( + const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + int32_t render_frame_id, + const url::Origin& origin, + uint32_t options, + network::mojom::WebSocketHandshakeClientPtrInfo handshake_client, + network::mojom::WebSocketClientPtrInfo websocket_client); void ThrottlingPeriodTimerCallback(); // This is virtual to support testing. virtual std::unique_ptr<network::WebSocket> DoCreateWebSocketInternal( std::unique_ptr<network::WebSocket::Delegate> delegate, - network::mojom::WebSocketRequest request, - network::WebSocketThrottler::PendingConnection pending_connection_tracker, - int child_id, - int frame_id, - url::Origin origin, + const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + int32_t frame_id, + const url::Origin& origin, uint32_t options, + network::mojom::WebSocketHandshakeClientPtr handshake_client, + network::mojom::WebSocketClientPtr websocket_client, + network::WebSocketThrottler::PendingConnection pending_connection_tracker, base::TimeDelta delay); net::URLRequestContext* GetURLRequestContext();
diff --git a/content/browser/websockets/websocket_manager_unittest.cc b/content/browser/websockets/websocket_manager_unittest.cc index 5a116bb7..dd9deb7 100644 --- a/content/browser/websockets/websocket_manager_unittest.cc +++ b/content/browser/websockets/websocket_manager_unittest.cc
@@ -23,30 +23,24 @@ public: TestWebSocketImpl( std::unique_ptr<Delegate> delegate, - network::mojom::WebSocketRequest request, - network::WebSocketThrottler::PendingConnection pending_connection_tracker, - - int process_id, - int frame_id, - url::Origin origin, - uint32_t options, - base::TimeDelta delay) + network::mojom::WebSocketHandshakeClientPtr handshake_client, + network::mojom::WebSocketClientPtr websocket_client, + network::WebSocketThrottler::PendingConnection pending_connection_tracker) : network::WebSocket(std::move(delegate), - std::move(request), + GURL(), + std::vector<std::string>(), + GURL(), + std::vector<network::mojom::HttpHeaderPtr>(), + kMagicRenderProcessId, + MSG_ROUTING_NONE, + url::Origin(), + network::mojom::kWebSocketOptionNone, + std::move(handshake_client), + std::move(websocket_client), nullptr, nullptr, std::move(pending_connection_tracker), - process_id, - frame_id, - std::move(origin), - options, - delay) {} - - base::TimeDelta delay() const { return delay_; } - - void SimulateConnectionError() { - OnConnectionError(); - } + base::TimeDelta::FromSeconds(1)) {} }; class TestWebSocketManager : public WebSocketManager { @@ -54,10 +48,6 @@ TestWebSocketManager() : WebSocketManager(kMagicRenderProcessId, nullptr) {} - const std::vector<TestWebSocketImpl*>& sockets() const { - return sockets_; - } - int64_t num_pending_connections() const { return throttler_.num_pending_connections(); } @@ -74,41 +64,42 @@ return throttler_.num_previous_failed_connections(); } - void DoCreateWebSocket(network::mojom::WebSocketRequest request) { - WebSocketManager::DoCreateWebSocket(MSG_ROUTING_NONE, url::Origin(), - network::mojom::kWebSocketOptionNone, - std::move(request)); + void DoCreateWebSocket() { + network::mojom::WebSocketHandshakeClientPtr handshake_client; + network::mojom::WebSocketClientPtr websocket_client; + + handshake_client_requests_.push_back(mojo::MakeRequest(&handshake_client)); + websocket_client_requests_.push_back(mojo::MakeRequest(&websocket_client)); + + WebSocketManager::DoCreateWebSocket( + GURL(), std::vector<std::string>(), GURL(), base::nullopt, + MSG_ROUTING_NONE, url::Origin(), network::mojom::kWebSocketOptionNone, + handshake_client.PassInterface(), websocket_client.PassInterface()); } private: std::unique_ptr<network::WebSocket> DoCreateWebSocketInternal( std::unique_ptr<network::WebSocket::Delegate> delegate, - network::mojom::WebSocketRequest request, - network::WebSocketThrottler::PendingConnection pending_connection_tracker, - int process_id, - int frame_id, - url::Origin origin, + const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + int32_t frame_id, + const url::Origin& origin, uint32_t options, + network::mojom::WebSocketHandshakeClientPtr handshake_client, + network::mojom::WebSocketClientPtr websocket_client, + network::WebSocketThrottler::PendingConnection pending_connection_tracker, base::TimeDelta delay) override { - auto impl = std::make_unique<TestWebSocketImpl>( - std::move(delegate), std::move(request), - std::move(pending_connection_tracker), process_id, frame_id, - std::move(origin), options, delay); - // We keep a vector of sockets here to track their creation order. - sockets_.push_back(impl.get()); - return impl; + return std::make_unique<TestWebSocketImpl>( + std::move(delegate), std::move(handshake_client), + std::move(websocket_client), std::move(pending_connection_tracker)); } - void OnLostConnectionToClient(network::WebSocket* impl) override { - auto it = std::find(sockets_.begin(), sockets_.end(), - static_cast<TestWebSocketImpl*>(impl)); - ASSERT_TRUE(it != sockets_.end()); - sockets_.erase(it); - - WebSocketManager::OnLostConnectionToClient(impl); - } - - std::vector<TestWebSocketImpl*> sockets_; + std::vector<network::mojom::WebSocketHandshakeClientRequest> + handshake_client_requests_; + std::vector<network::mojom::WebSocketClientRequest> + websocket_client_requests_; }; class WebSocketManagerTest : public ::testing::Test { @@ -118,21 +109,6 @@ websocket_manager_.reset(new TestWebSocketManager()); } - void AddMultipleChannels(int number_of_channels) { - for (int i = 0; i < number_of_channels; ++i) { - network::mojom::WebSocketPtr websocket; - websocket_manager_->DoCreateWebSocket(mojo::MakeRequest(&websocket)); - } - } - - void AddAndCancelMultipleChannels(int number_of_channels) { - for (int i = 0; i < number_of_channels; ++i) { - network::mojom::WebSocketPtr websocket; - websocket_manager_->DoCreateWebSocket(mojo::MakeRequest(&websocket)); - websocket_manager_->sockets().back()->SimulateConnectionError(); - } - } - TestWebSocketManager* websocket_manager() { return websocket_manager_.get(); } private: @@ -147,25 +123,17 @@ TEST_F(WebSocketManagerTest, CreateWebSocket) { network::mojom::WebSocketPtr websocket; - websocket_manager()->DoCreateWebSocket(mojo::MakeRequest(&websocket)); + websocket_manager()->DoCreateWebSocket(); - EXPECT_EQ(1U, websocket_manager()->sockets().size()); -} - -TEST_F(WebSocketManagerTest, SendFrameButNotConnectedYet) { - network::mojom::WebSocketPtr websocket; - - websocket_manager()->DoCreateWebSocket(mojo::MakeRequest(&websocket)); - - // This should not crash. - std::vector<uint8_t> data; - websocket->SendFrame(true, network::mojom::WebSocketMessageType::TEXT, data); + EXPECT_EQ(1U, websocket_manager()->num_sockets()); } // The 256th connection is rejected by per-renderer WebSocket throttling. // This is not counted as a failure. TEST_F(WebSocketManagerTest, Rejects256thPendingConnection) { - AddMultipleChannels(256); + for (int i = 0; i < 256; ++i) { + websocket_manager()->DoCreateWebSocket(); + } EXPECT_EQ(255, websocket_manager()->num_pending_connections()); EXPECT_EQ(0, websocket_manager()->num_current_succeeded_connections()); @@ -173,7 +141,7 @@ EXPECT_EQ(0, websocket_manager()->num_current_failed_connections()); EXPECT_EQ(0, websocket_manager()->num_previous_failed_connections()); - ASSERT_EQ(255U, websocket_manager()->sockets().size()); + EXPECT_EQ(255U, websocket_manager()->num_sockets()); } } // namespace
diff --git a/content/browser/worker_host/dedicated_worker_host.cc b/content/browser/worker_host/dedicated_worker_host.cc index e890924..bed3cddf 100644 --- a/content/browser/worker_host/dedicated_worker_host.cc +++ b/content/browser/worker_host/dedicated_worker_host.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 <memory> #include <string> #include <utility> @@ -14,7 +15,7 @@ #include "content/browser/interface_provider_filtering.h" #include "content/browser/renderer_interface_binders.h" #include "content/browser/storage_partition_impl.h" -#include "content/browser/websockets/websocket_manager.h" +#include "content/browser/websockets/websocket_connector_impl.h" #include "content/browser/worker_host/worker_script_fetch_initiator.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" @@ -120,8 +121,9 @@ private: void RegisterMojoInterfaces() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - registry_.AddInterface(base::BindRepeating( - &DedicatedWorkerHost::CreateWebSocket, base::Unretained(this))); + registry_.AddInterface( + base::BindRepeating(&DedicatedWorkerHost::CreateWebSocketConnector, + base::Unretained(this))); registry_.AddInterface(base::BindRepeating( &DedicatedWorkerHost::CreateWebUsbService, base::Unretained(this))); registry_.AddInterface(base::BindRepeating( @@ -224,7 +226,7 @@ // TODO(crbug.com/955476): Create network_isolation_key cache key using // worker script's origin. process->CreateURLLoaderFactory( - origin_, net::NetworkIsolationKey() /* network_isolation_key */, + origin_, nullptr /* preferences */, net::NetworkIsolationKey(), std::move(no_header_client), std::move(request)); } @@ -236,8 +238,10 @@ std::move(request)); } - void CreateWebSocket(network::mojom::WebSocketRequest request) { + void CreateWebSocketConnector( + blink::mojom::WebSocketConnectorRequest request) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + network::mojom::AuthenticationHandlerPtr auth_handler; auto* frame = RenderFrameHost::FromID(process_id_, ancestor_render_frame_id_); @@ -248,15 +252,10 @@ "The parent frame has already been gone."); return; } - - uint32_t options = network::mojom::kWebSocketOptionNone; - network::mojom::TrustedHeaderClientPtr header_client; - GetContentClient()->browser()->WillCreateWebSocket( - frame, &request, &auth_handler, &header_client, &options); - - WebSocketManager::CreateWebSocket( - process_id_, ancestor_render_frame_id_, origin_, options, - std::move(auth_handler), std::move(header_client), std::move(request)); + mojo::MakeStrongBinding( + std::make_unique<WebSocketConnectorImpl>( + process_id_, ancestor_render_frame_id_, origin_), + std::move(request)); } void CreateDedicatedWorker(
diff --git a/content/browser/worker_host/shared_worker_host.cc b/content/browser/worker_host/shared_worker_host.cc index 1756440d..9d408ab 100644 --- a/content/browser/worker_host/shared_worker_host.cc +++ b/content/browser/worker_host/shared_worker_host.cc
@@ -315,14 +315,14 @@ // TODO(crbug.com/955476): network_isolation_key to be created using worker // script's origin. if (GetCreateNetworkFactoryCallbackForSharedWorker().is_null()) { - process->CreateURLLoaderFactory(origin, net::NetworkIsolationKey(), - std::move(no_header_client), - std::move(request)); + process->CreateURLLoaderFactory( + origin, nullptr /* preferences */, net::NetworkIsolationKey(), + std::move(no_header_client), std::move(request)); } else { network::mojom::URLLoaderFactoryPtr original_factory; - process->CreateURLLoaderFactory(origin, net::NetworkIsolationKey(), - std::move(no_header_client), - mojo::MakeRequest(&original_factory)); + process->CreateURLLoaderFactory( + origin, nullptr /* preferences */, net::NetworkIsolationKey(), + std::move(no_header_client), mojo::MakeRequest(&original_factory)); GetCreateNetworkFactoryCallbackForSharedWorker().Run( std::move(request), process_id_, original_factory.PassInterface()); }
diff --git a/content/browser/worker_host/worker_script_fetch_initiator.cc b/content/browser/worker_host/worker_script_fetch_initiator.cc index 06cc8084..ed3c851f 100644 --- a/content/browser/worker_host/worker_script_fetch_initiator.cc +++ b/content/browser/worker_host/worker_script_fetch_initiator.cc
@@ -4,6 +4,9 @@ #include "content/browser/worker_host/worker_script_fetch_initiator.h" +#include <string> +#include <vector> + #include "base/bind.h" #include "base/callback.h" #include "base/feature_list.h" @@ -222,9 +225,9 @@ // TODO(crbug.com/955476): Populate the network isolation key. RenderProcessHost::FromID(process_id) - ->CreateURLLoaderFactory(kSafeOrigin, net::NetworkIsolationKey(), - nullptr /* header_client */, - mojo::MakeRequest(&default_factory)); + ->CreateURLLoaderFactory( + kSafeOrigin, nullptr /* preferences */, net::NetworkIsolationKey(), + nullptr /* header_client */, mojo::MakeRequest(&default_factory)); factory_bundle->default_factory_info() = default_factory.PassInterface(); }
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index bf3a9ee4..877bacd7 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -404,6 +404,10 @@ base::GetFieldTrialParamByFeatureAsBool( features::kLazyImageLoading, "restrict-lazy-load-images-to-data-saver-only", false)); + WebRuntimeFeatures::EnableLazyImageLoadingMetadataFetch( + base::GetFieldTrialParamByFeatureAsBool( + features::kLazyImageLoading, "enable-lazy-load-images-metadata-fetch", + true)); WebRuntimeFeatures::EnablePictureInPicture( base::FeatureList::IsEnabled(media::kPictureInPicture));
diff --git a/content/public/app/content_browser_manifest.cc b/content/public/app/content_browser_manifest.cc index acc8c75a..7e2221c5 100644 --- a/content/public/app/content_browser_manifest.cc +++ b/content/public/app/content_browser_manifest.cc
@@ -161,7 +161,8 @@ "blink.mojom.NativeFileSystemManager", "blink.mojom.NotificationService", "blink.mojom.PermissionService", - "blink.mojom.QuotaDispatcherHost", "network.mojom.WebSocket", + "blink.mojom.QuotaDispatcherHost", + "blink.mojom.WebSocketConnector", "media.mojom.VideoDecodePerfHistory", "payments.mojom.PaymentManager", "shape_detection.mojom.BarcodeDetectionProvider", @@ -179,7 +180,7 @@ "blink.mojom.PermissionService", "blink.mojom.QuotaDispatcherHost", "blink.mojom.SerialService", "blink.mojom.WebUsbService", - "blink.mojom.SmsReceiver", "network.mojom.WebSocket", + "blink.mojom.SmsReceiver", "blink.mojom.WebSocketConnector", "media.mojom.VideoDecodePerfHistory", "payments.mojom.PaymentManager", "shape_detection.mojom.BarcodeDetectionProvider", @@ -198,7 +199,8 @@ "blink.mojom.QuotaDispatcherHost", "media.mojom.VideoDecodePerfHistory", "network.mojom.RestrictedCookieManager", - "network.mojom.WebSocket", "payments.mojom.PaymentManager", + "blink.mojom.WebSocketConnector", + "payments.mojom.PaymentManager", "shape_detection.mojom.BarcodeDetectionProvider", "shape_detection.mojom.FaceDetectionProvider", "shape_detection.mojom.TextDetection"}) @@ -264,7 +266,7 @@ "media.mojom.VideoDecodePerfHistory", "mojom.ProcessInternalsHandler", "network.mojom.RestrictedCookieManager", - "network.mojom.WebSocket", + "blink.mojom.WebSocketConnector", "payments.mojom.PaymentManager", "payments.mojom.PaymentRequest", "resource_coordinator.mojom.DocumentCoordinationUnit",
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index fae53a9..d7d2b18d 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -756,12 +756,24 @@ return false; } -void ContentBrowserClient::WillCreateWebSocket( +bool ContentBrowserClient::WillInterceptWebSocket(RenderFrameHost*) { + return false; +} + +uint32_t ContentBrowserClient::GetWebSocketOptions(RenderFrameHost* frame) { + return network::mojom::kWebSocketOptionNone; +} + +void ContentBrowserClient::CreateWebSocket( RenderFrameHost* frame, - network::mojom::WebSocketRequest* request, - network::mojom::AuthenticationHandlerPtr* auth_handler, - network::mojom::TrustedHeaderClientPtr* header_client, - uint32_t* options) {} + WebSocketFactory factory, + const GURL& url, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + network::mojom::WebSocketHandshakeClientPtr handshake_client) { + // NOTREACHED because WillInterceptWebSocket returns false. + NOTREACHED(); +} void ContentBrowserClient::WillCreateRestrictedCookieManager( const url::Origin& origin,
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index d1d54b95..b422bbf7 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -1245,18 +1245,35 @@ network::mojom::TrustedURLLoaderHeaderClientPtrInfo* header_client, bool* bypass_redirect_checks); - // Allows the embedder to intercept a WebSocket connection. |*request| - // is always valid upon entry and MUST be valid upon return. The embedder - // may swap out the value of |*request| for its own. + // Returns true when the embedder wants to intercept a websocket connection. + virtual bool WillInterceptWebSocket(RenderFrameHost* frame); + + // Returns the WebSocket creation options. + virtual uint32_t GetWebSocketOptions(RenderFrameHost* frame); + + using WebSocketFactory = base::OnceCallback<void( + const GURL& /* url */, + std::vector<network::mojom::HttpHeaderPtr> /* additional_headers */, + network::mojom::WebSocketHandshakeClientPtr, + network::mojom::AuthenticationHandlerPtr, + network::mojom::TrustedHeaderClientPtr)>; + + // Allows the embedder to intercept a WebSocket connection. This is called + // only when WillInterceptWebSocket returns true. + // + // |factory| provides a way to create a usual WebSocket connection. |url|, + // |requested_protocols|, |user_agent|, |handshake_client| are arguments + // given from the renderer. // // Always called on the UI thread and only when the Network Service is // enabled. - virtual void WillCreateWebSocket( + virtual void CreateWebSocket( RenderFrameHost* frame, - network::mojom::WebSocketRequest* request, - network::mojom::AuthenticationHandlerPtr* authentication_handler, - network::mojom::TrustedHeaderClientPtr* header_client, - uint32_t* options); + WebSocketFactory factory, + const GURL& url, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + network::mojom::WebSocketHandshakeClientPtr handshake_client); // Allows the embedder to intercept the mojo object vended to renderer // processes for limited, origin-locked (to |origin|), access to
diff --git a/content/public/browser/media_session.h b/content/public/browser/media_session.h index e8e0207..d2b84451 100644 --- a/content/public/browser/media_session.h +++ b/content/public/browser/media_session.h
@@ -67,7 +67,8 @@ // Adds an observer to listen to events related to this MediaSession. void AddObserver( - media_session::mojom::MediaSessionObserverPtr observer) override = 0; + mojo::PendingRemote<media_session::mojom::MediaSessionObserver> observer) + override = 0; // Skip to the previous track. If there is no previous track then this will be // a no-op.
diff --git a/content/public/browser/plugin_service.h b/content/public/browser/plugin_service.h index aed3085c77..7646bda 100644 --- a/content/public/browser/plugin_service.h +++ b/content/public/browser/plugin_service.h
@@ -32,9 +32,10 @@ struct WebPluginInfo; // This must be created on the main thread but it's only called on the IO/file -// thread. This is an asynchronous wrapper around the PluginList interface for -// querying plugin information. This must be used instead of that to avoid -// doing expensive disk operations on the IO/UI threads. +// thread unless otherwise noted. This is an asynchronous wrapper around the +// PluginList interface for querying plugin information. This must be used +// instead of that to avoid doing expensive disk operations on the IO/UI +// threads. class CONTENT_EXPORT PluginService { public: using GetPluginsCallback = @@ -69,6 +70,7 @@ // Gets plugin info for an individual plugin and filters the plugins using // the |context| and renderer IDs. This will report whether the data is stale // via |is_stale| and returns whether or not the plugin can be found. + // This can be called from any thread. virtual bool GetPluginInfo(int render_process_id, int render_frame_id, ResourceContext* context, @@ -83,17 +85,20 @@ // Get plugin info by plugin path (including disabled plugins). Returns true // if the plugin is found and WebPluginInfo has been filled in |info|. This // will use cached data in the plugin list. + // This can be called from any thread. virtual bool GetPluginInfoByPath(const base::FilePath& plugin_path, WebPluginInfo* info) = 0; // Returns the display name for the plugin identified by the given path. If // the path doesn't identify a plugin, or the plugin has no display name, // this will attempt to generate a display name from the path. + // This can be called from any thread. virtual base::string16 GetPluginDisplayNameByPath( const base::FilePath& plugin_path) = 0; // Asynchronously loads plugins if necessary and then calls back to the // provided function on the calling sequence on completion. + // This can be called from any thread. virtual void GetPlugins(GetPluginsCallback callback) = 0; // Returns information about a pepper plugin if it exists, otherwise nullptr.
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h index 55248453..440cf1540 100644 --- a/content/public/browser/render_process_host.h +++ b/content/public/browser/render_process_host.h
@@ -58,7 +58,7 @@ class RenderProcessHostObserver; class RendererAudioOutputStreamFactoryContext; class StoragePartition; - +struct WebPreferences; #if defined(OS_ANDROID) enum class ChildProcessImportance; #endif @@ -402,6 +402,10 @@ // When NetworkService is not enabled, |request| will be bound with a // URLLoaderFactory which routes requests to ResourceDispatcherHost. // + // |preferences| is an optional argument that might be used to control some + // aspects of the URLLoaderFactory (e.g. via + // allow_universal_access_from_file_urls). + // // |header_client| will be used in URLLoaderFactoryParams when creating the // factory. // @@ -413,6 +417,7 @@ // TODO(lukasza, nasko): https://crbug.com/888079: Make |origin| mandatory. virtual void CreateURLLoaderFactory( const base::Optional<url::Origin>& origin, + const WebPreferences* preferences, const net::NetworkIsolationKey& network_isolation_key, network::mojom::TrustedURLLoaderHeaderClientPtrInfo header_client, network::mojom::URLLoaderFactoryRequest request) = 0;
diff --git a/content/public/browser/site_isolation_policy.cc b/content/public/browser/site_isolation_policy.cc index 8de0cf5..f88598c 100644 --- a/content/public/browser/site_isolation_policy.cc +++ b/content/public/browser/site_isolation_policy.cc
@@ -25,7 +25,6 @@ #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/resource_type.h" -#include "services/network/public/mojom/network_service.mojom.h" #include "url/gurl.h" namespace content { @@ -71,19 +70,6 @@ } // static -void SiteIsolationPolicy::PopulateURLLoaderFactoryParamsPtrForCORB( - network::mojom::URLLoaderFactoryParams* params) { - // --disable-web-security also disables Cross-Origin Read Blocking (CORB). - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableWebSecurity)) { - params->is_corb_enabled = false; - return; - } - - params->is_corb_enabled = true; -} - -// static bool SiteIsolationPolicy::AreIsolatedOriginsEnabled() { // NOTE: Because it is possible for --isolate-origins to be isolating origins // at a finer-than-site granularity, we do not suppress --isolate-origins when
diff --git a/content/public/browser/site_isolation_policy.h b/content/public/browser/site_isolation_policy.h index ea6ab4a..017f288 100644 --- a/content/public/browser/site_isolation_policy.h +++ b/content/public/browser/site_isolation_policy.h
@@ -14,12 +14,6 @@ #include "content/common/content_export.h" #include "url/origin.h" -namespace network { -namespace mojom { -class URLLoaderFactoryParams; -} -} // namespace network - namespace content { // A centralized place for making policy decisions about out-of-process iframes, @@ -34,11 +28,6 @@ // Returns true if every site should be placed in a dedicated process. static bool UseDedicatedProcessesForAllSites(); - // Populates CORB-related (Cross-Origin Read Blocking related) parts of the - // URLLoaderFactoryParams depending on the current Site Isolation policy. - static void PopulateURLLoaderFactoryParamsPtrForCORB( - network::mojom::URLLoaderFactoryParams* params); - // Returns true if isolated origins feature is enabled. static bool AreIsolatedOriginsEnabled();
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 5132c46..cf9ce9e 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -955,11 +955,6 @@ // Enable indication that browser is controlled by automation. const char kEnableAutomation[] = "enable-automation"; -#if defined(OS_CHROMEOS) -// Disables panel fitting (used for mirror mode). -const char kDisablePanelFitting[] = "disable-panel-fitting"; -#endif - #if defined(OS_LINUX) && !defined(OS_CHROMEOS) // Allows sending text-to-speech requests to speech-dispatcher, a common // Linux speech service. Because it's buggy, the user must explicitly
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 1c5ea6bb..e6954ad 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -267,10 +267,6 @@ CONTENT_EXPORT extern const char kRendererWaitForJavaDebugger[]; #endif -#if defined(OS_CHROMEOS) -CONTENT_EXPORT extern const char kDisablePanelFitting[]; -#endif - #if defined(OS_LINUX) && !defined(OS_CHROMEOS) CONTENT_EXPORT extern const char kEnableSpeechDispatcher[]; #endif
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc index 243750c..459d855 100644 --- a/content/public/test/mock_render_process_host.cc +++ b/content/public/test/mock_render_process_host.cc
@@ -391,6 +391,7 @@ void MockRenderProcessHost::CreateURLLoaderFactory( const base::Optional<url::Origin>& origin, + const WebPreferences* preferences, const net::NetworkIsolationKey& network_isolation_key, network::mojom::TrustedURLLoaderHeaderClientPtrInfo header_client, network::mojom::URLLoaderFactoryRequest request) {
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h index b58f97d..71120b2 100644 --- a/content/public/test/mock_render_process_host.h +++ b/content/public/test/mock_render_process_host.h
@@ -145,6 +145,7 @@ mojom::Renderer* GetRendererInterface() override; void CreateURLLoaderFactory( const base::Optional<url::Origin>& origin, + const WebPreferences* preferences, const net::NetworkIsolationKey& network_isolation_key, network::mojom::TrustedURLLoaderHeaderClientPtrInfo header_client, network::mojom::URLLoaderFactoryRequest request) override;
diff --git a/content/renderer/loader/code_cache_loader_impl.cc b/content/renderer/loader/code_cache_loader_impl.cc index 983fc82..2a79d65a 100644 --- a/content/renderer/loader/code_cache_loader_impl.cc +++ b/content/renderer/loader/code_cache_loader_impl.cc
@@ -21,7 +21,7 @@ void CodeCacheLoaderImpl::FetchFromCodeCacheSynchronously( const GURL& url, base::Time* response_time_out, - std::vector<uint8_t>* data_out) { + blink::WebVector<uint8_t>* data_out) { base::WaitableEvent fetch_code_cache_event( base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED);
diff --git a/content/renderer/loader/code_cache_loader_impl.h b/content/renderer/loader/code_cache_loader_impl.h index f9d7ad71..7fd7946 100644 --- a/content/renderer/loader/code_cache_loader_impl.h +++ b/content/renderer/loader/code_cache_loader_impl.h
@@ -28,9 +28,10 @@ // Fetches code cache corresponding to |url| and returns response in // |response_time_out| and |data_out|. |response_time_out| and |data_out| // cannot be nullptrs. This only fetches from the Javascript cache. - void FetchFromCodeCacheSynchronously(const GURL& url, - base::Time* response_time_out, - std::vector<uint8_t>* data_out) override; + void FetchFromCodeCacheSynchronously( + const GURL& url, + base::Time* response_time_out, + blink::WebVector<uint8_t>* data_out) override; void FetchFromCodeCache(blink::mojom::CodeCacheType cache_type, const GURL& url,
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 9ef6241..7b26dcde 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -1,8 +1,10 @@ # tags: [ d3d11 no-angle vulkan opengl ] # tags: [ win win7 highsierra mac linux sierra android mojave ] # tags: [ passthrough no-passthrough ] -# tags: [ intel amd-0x699f nvidia-0x1cb3 amd-0x6613 amd -# qualcomm nvidia-0xfe9 nvidia nvidia-0xf02 intel-0xa2e ] +# tags: [ intel intel-0xa2e +# amd amd-0x6613 amd-0x699f +# nvidia nvidia-0xf02 nvidia-0xfe9 nvidia-0x1cb3 +# qualcomm qualcomm-adreno-(tm)-540 ] # tags: [ debug ] # tags: [ intel_lt_25.20.100.6444 mesa_lt_17.3.9 mesa_lt_17.1.6 ] # results: [ Failure RetryOnFailure Skip ] @@ -746,6 +748,7 @@ # crbug.com/906739 [ android qualcomm ] conformance2/extensions/ovr_multiview2.html [ Failure ] crbug.com/906742 [ android qualcomm ] conformance2/glsl3/compare-structs-containing-arrays.html [ Failure ] crbug.com/906735 [ android qualcomm ] conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html [ Failure ] +crbug.com/981216 [ android qualcomm-adreno-(tm)-540 ] deqp/functional/gles3/fbocolorbuffer/tex2d_01.html [ RetryOnFailure ] crbug.com/949321 [ android qualcomm ] deqp/functional/gles3/framebufferblit/default_framebuffer_02.html [ RetryOnFailure ] # This test is failing on Android Pixel 2 and 3 (Qualcomm)
diff --git a/device/fido/bio/enrollment_handler.cc b/device/fido/bio/enrollment_handler.cc index 08cac2ba..c0180da 100644 --- a/device/fido/bio/enrollment_handler.cc +++ b/device/fido/bio/enrollment_handler.cc
@@ -5,6 +5,7 @@ #include "device/fido/bio/enrollment_handler.h" #include "base/bind.h" +#include "base/bind_helpers.h" #include "components/device_event_log/device_event_log.h" #include "device/fido/fido_authenticator.h" #include "device/fido/fido_constants.h" @@ -42,12 +43,14 @@ authenticator_->GetSensorInfo(std::move(callback)); } -void BioEnrollmentHandler::EnrollTemplate(ResponseCallback callback) { +void BioEnrollmentHandler::EnrollTemplate(SampleCallback sample_callback, + StatusCallback completion_callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); authenticator_->BioEnrollFingerprint( - *pin_token_response_, - base::BindOnce(&BioEnrollmentHandler::OnEnrollTemplate, - weak_factory_.GetWeakPtr(), std::move(callback))); + *pin_token_response_, std::move(sample_callback), + base::BindOnce(&BioEnrollmentHandler::OnEnrollTemplateFinished, + weak_factory_.GetWeakPtr(), + std::move(completion_callback))); } void BioEnrollmentHandler::Cancel(StatusCallback callback) { @@ -57,7 +60,7 @@ weak_factory_.GetWeakPtr(), std::move(callback))); } -void BioEnrollmentHandler::EnumerateTemplates(ResponseCallback callback) { +void BioEnrollmentHandler::EnumerateTemplates(EnumerationCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); authenticator_->BioEnrollEnumerate( *pin_token_response_, @@ -65,21 +68,21 @@ weak_factory_.GetWeakPtr(), std::move(callback))); } -void BioEnrollmentHandler::RenameTemplate(std::vector<uint8_t> id, +void BioEnrollmentHandler::RenameTemplate(std::vector<uint8_t> template_id, std::string name, StatusCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); authenticator_->BioEnrollRename( - *pin_token_response_, std::move(id), std::move(name), + *pin_token_response_, std::move(template_id), std::move(name), base::BindOnce(&BioEnrollmentHandler::OnRenameTemplate, weak_factory_.GetWeakPtr(), std::move(callback))); } -void BioEnrollmentHandler::DeleteTemplate(std::vector<uint8_t> id, +void BioEnrollmentHandler::DeleteTemplate(std::vector<uint8_t> template_id, StatusCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); authenticator_->BioEnrollDelete( - *pin_token_response_, std::move(id), + *pin_token_response_, std::move(template_id), base::BindOnce(&BioEnrollmentHandler::OnDeleteTemplate, weak_factory_.GetWeakPtr(), std::move(callback))); } @@ -210,23 +213,19 @@ std::move(ready_callback_).Run(); } -void BioEnrollmentHandler::OnEnrollTemplate( - ResponseCallback callback, +void BioEnrollmentHandler::OnEnrollTemplateFinished( + StatusCallback callback, CtapDeviceResponseCode code, base::Optional<BioEnrollmentResponse> response) { - if (code != CtapDeviceResponseCode::kSuccess) { - // Response is not valid if operation was not successful. - std::move(callback).Run(code, base::nullopt); - return; - } - if (!response || !response->last_status || !response->remaining_samples) { - std::move(callback).Run(CtapDeviceResponseCode::kCtap2ErrOther, - base::nullopt); + if (code == CtapDeviceResponseCode::kSuccess && + (!response || !response->last_status || !response->remaining_samples)) { + // Response is incomplete or invalid. + std::move(callback).Run(CtapDeviceResponseCode::kCtap2ErrOther); return; } FIDO_LOG(DEBUG) << "Finished bio enrollment with code " << static_cast<int>(code); - std::move(callback).Run(code, std::move(response)); + std::move(callback).Run(code); } void BioEnrollmentHandler::OnCancel(StatusCallback callback, @@ -236,7 +235,7 @@ } void BioEnrollmentHandler::OnEnumerateTemplates( - ResponseCallback callback, + EnumerationCallback callback, CtapDeviceResponseCode code, base::Optional<BioEnrollmentResponse> response) { if (code != CtapDeviceResponseCode::kSuccess) { @@ -251,7 +250,7 @@ base::nullopt); return; } - std::move(callback).Run(code, std::move(response)); + std::move(callback).Run(code, std::move(*response->template_infos)); } void BioEnrollmentHandler::OnRenameTemplate(
diff --git a/device/fido/bio/enrollment_handler.h b/device/fido/bio/enrollment_handler.h index 9383c5a..4a0680d 100644 --- a/device/fido/bio/enrollment_handler.h +++ b/device/fido/bio/enrollment_handler.h
@@ -30,6 +30,11 @@ base::OnceCallback<void(CtapDeviceResponseCode, base::Optional<BioEnrollmentResponse>)>; using StatusCallback = base::OnceCallback<void(CtapDeviceResponseCode)>; + using EnumerationCallback = base::OnceCallback<void( + CtapDeviceResponseCode, + base::Optional<std::map<std::vector<uint8_t>, std::string>>)>; + using SampleCallback = + base::RepeatingCallback<void(BioEnrollmentSampleStatus, uint8_t)>; BioEnrollmentHandler( service_manager::Connector* connector, @@ -41,15 +46,39 @@ std::make_unique<FidoDiscoveryFactory>().get()); ~BioEnrollmentHandler() override; + // Returns the modality of the authenticator's user verification. + // Currently, the only valid modality is fingerprint. void GetModality(ResponseCallback); + + // Returns fingerprint sensor info for the authenticator. + // This includes number of required samples to enroll and sensor type. void GetSensorInfo(ResponseCallback); - void EnrollTemplate(ResponseCallback); + + // Enrolls a new fingerprint template. The user must provide the required + // number of samples by touching the authenticator's sensor repeatedly. + // After each sample, or a timeout, |sample_callback| is invoked with the + // remaining number of samples. Once all samples have been collected or + // the operation has been cancelled, |completion_callback| is invoked + // with the operation status. + void EnrollTemplate(SampleCallback sample_callback, + StatusCallback completion_callback); + + // Cancels an ongoing enrollment, if any, and invokes the callback with + // |CtapDeviceResponseCode::kSuccess|. void Cancel(StatusCallback); - void EnumerateTemplates(ResponseCallback); - void RenameTemplate(std::vector<uint8_t> id, + + // Requests a map of current enrollments from the authenticator. On success, + // the callback is invoked with a map from template IDs to human-readable + // names. On failure, the callback is invoked with base::nullopt. + void EnumerateTemplates(EnumerationCallback); + + // Renames the enrollment identified by |template_id| to |name|. + void RenameTemplate(std::vector<uint8_t> template_id, std::string name, StatusCallback); - void DeleteTemplate(std::vector<uint8_t> id, StatusCallback); + + // Deletes the enrollment identified by |template_id|. + void DeleteTemplate(std::vector<uint8_t> template_id, StatusCallback); private: // FidoRequestHandlerBase: @@ -65,13 +94,13 @@ base::Optional<pin::KeyAgreementResponse>); void OnHavePINToken(CtapDeviceResponseCode, base::Optional<pin::TokenResponse>); - void OnEnrollTemplate(ResponseCallback, - CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>); + void OnEnrollTemplateFinished(StatusCallback, + CtapDeviceResponseCode, + base::Optional<BioEnrollmentResponse>); void OnCancel(StatusCallback, CtapDeviceResponseCode, base::Optional<BioEnrollmentResponse>); - void OnEnumerateTemplates(ResponseCallback, + void OnEnumerateTemplates(EnumerationCallback, CtapDeviceResponseCode, base::Optional<BioEnrollmentResponse>); void OnRenameTemplate(StatusCallback,
diff --git a/device/fido/bio/enrollment_handler_unittest.cc b/device/fido/bio/enrollment_handler_unittest.cc index 5b28726..479cc55 100644 --- a/device/fido/bio/enrollment_handler_unittest.cc +++ b/device/fido/bio/enrollment_handler_unittest.cc
@@ -27,6 +27,17 @@ virtual_device_factory_.mutable_state()->retries = 8; } + public: + void OnEnroll(BioEnrollmentSampleStatus status, uint8_t remaining_samples) { + EXPECT_EQ(status, BioEnrollmentSampleStatus::kGood); + if (sampling_) { + EXPECT_EQ(remaining_samples, --remaining_samples_); + } else { + sampling_ = true; + remaining_samples_ = remaining_samples; + } + } + protected: std::unique_ptr<BioEnrollmentHandler> MakeHandler() { return std::make_unique<BioEnrollmentHandler>( @@ -44,6 +55,15 @@ std::move(provide_pin).Run(kPIN); } + auto MakeStatusCallback() { + remaining_samples_ = 0; + sampling_ = false; + return base::BindRepeating(&BioEnrollmentHandlerTest::OnEnroll, + base::Unretained(this)); + } + + uint8_t remaining_samples_; + bool sampling_; base::test::ScopedTaskEnvironment scoped_task_environment_; test::TestCallbackReceiver<> ready_callback_; test::ValueCallbackReceiver<FidoReturnCode> error_callback_; @@ -156,18 +176,11 @@ auto handler = MakeHandler(); ready_callback_.WaitForCallback(); - test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>> - cb; - handler->EnrollTemplate(cb.callback()); + test::ValueCallbackReceiver<CtapDeviceResponseCode> cb; + handler->EnrollTemplate(MakeStatusCallback(), cb.callback()); cb.WaitForCallback(); - EXPECT_EQ(cb.status(), CtapDeviceResponseCode::kSuccess); - - BioEnrollmentResponse expected; - expected.last_status = BioEnrollmentSampleStatus::kGood; - expected.remaining_samples = 0; - EXPECT_EQ(cb.value(), expected); + EXPECT_EQ(cb.value(), CtapDeviceResponseCode::kSuccess); } // Tests enrolling multiple fingerprints. @@ -183,31 +196,25 @@ // Multiple enrollments for (auto i = 0; i < 4; i++) { - test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>> - cb; - handler->EnrollTemplate(cb.callback()); - + test::ValueCallbackReceiver<CtapDeviceResponseCode> cb; + handler->EnrollTemplate(MakeStatusCallback(), cb.callback()); cb.WaitForCallback(); - EXPECT_EQ(cb.status(), CtapDeviceResponseCode::kSuccess); + EXPECT_EQ(cb.value(), CtapDeviceResponseCode::kSuccess); } // Enumerate to check enrollments. - test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>> + test::StatusAndValueCallbackReceiver< + CtapDeviceResponseCode, + base::Optional<std::map<std::vector<uint8_t>, std::string>>> cb; handler->EnumerateTemplates(cb.callback()); - cb.WaitForCallback(); EXPECT_EQ(cb.status(), CtapDeviceResponseCode::kSuccess); - - BioEnrollmentResponse expected; - expected.template_infos = - std::map<std::vector<uint8_t>, std::string>{{{1}, "Template1"}, - {{2}, "Template2"}, - {{3}, "Template3"}, - {{4}, "Template4"}}; - EXPECT_EQ(cb.value(), expected); + EXPECT_EQ(cb.value(), + (std::map<std::vector<uint8_t>, std::string>{{{1}, "Template1"}, + {{2}, "Template2"}, + {{3}, "Template3"}, + {{4}, "Template4"}})); } // Tests enrolling beyond maximum capacity. @@ -224,13 +231,10 @@ // Enroll until full. auto status = CtapDeviceResponseCode::kSuccess; while (status == CtapDeviceResponseCode::kSuccess) { - test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>> - cb; - handler->EnrollTemplate(cb.callback()); - + test::ValueCallbackReceiver<CtapDeviceResponseCode> cb; + handler->EnrollTemplate(MakeStatusCallback(), cb.callback()); cb.WaitForCallback(); - status = cb.status(); + status = cb.value(); } EXPECT_EQ(status, CtapDeviceResponseCode::kCtap2ErrKeyStoreFull); @@ -265,13 +269,14 @@ auto handler = MakeHandler(); ready_callback_.WaitForCallback(); - test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>> + test::StatusAndValueCallbackReceiver< + CtapDeviceResponseCode, + base::Optional<std::map<std::vector<uint8_t>, std::string>>> cb; handler->EnumerateTemplates(cb.callback()); - cb.WaitForCallback(); EXPECT_EQ(cb.status(), CtapDeviceResponseCode::kCtap2ErrInvalidOption); + EXPECT_EQ(cb.value(), base::nullopt); } // Tests enumerating with one enrollment. @@ -286,27 +291,21 @@ ready_callback_.WaitForCallback(); // Enroll - skip response validation - test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>> - cb0; - handler->EnrollTemplate(cb0.callback()); - + test::ValueCallbackReceiver<CtapDeviceResponseCode> cb0; + handler->EnrollTemplate(MakeStatusCallback(), cb0.callback()); cb0.WaitForCallback(); - EXPECT_EQ(cb0.status(), CtapDeviceResponseCode::kSuccess); + EXPECT_EQ(cb0.value(), CtapDeviceResponseCode::kSuccess); // Enumerate - test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>> + test::StatusAndValueCallbackReceiver< + CtapDeviceResponseCode, + base::Optional<std::map<std::vector<uint8_t>, std::string>>> cb1; handler->EnumerateTemplates(cb1.callback()); - cb1.WaitForCallback(); EXPECT_EQ(cb1.status(), CtapDeviceResponseCode::kSuccess); - - BioEnrollmentResponse expected; - expected.template_infos = - std::map<std::vector<uint8_t>, std::string>{{{1}, "Template1"}}; - EXPECT_EQ(cb1.value(), expected); + EXPECT_EQ(cb1.value(), + (std::map<std::vector<uint8_t>, std::string>{{{1}, "Template1"}})); } // Tests renaming an enrollment (success and failure). @@ -323,39 +322,31 @@ // Rename non-existent enrollment. test::ValueCallbackReceiver<CtapDeviceResponseCode> cb0; handler->RenameTemplate({1}, "OtherFingerprint1", cb0.callback()); - cb0.WaitForCallback(); EXPECT_EQ(cb0.value(), CtapDeviceResponseCode::kCtap2ErrInvalidOption); // Enroll - skip response validation. - test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>> - cb1; - handler->EnrollTemplate(cb1.callback()); - + test::ValueCallbackReceiver<CtapDeviceResponseCode> cb1; + handler->EnrollTemplate(MakeStatusCallback(), cb1.callback()); cb1.WaitForCallback(); - EXPECT_EQ(cb1.status(), CtapDeviceResponseCode::kSuccess); + EXPECT_EQ(cb1.value(), CtapDeviceResponseCode::kSuccess); // Rename non-existent enrollment. test::ValueCallbackReceiver<CtapDeviceResponseCode> cb2; handler->RenameTemplate({1}, "OtherFingerprint1", cb2.callback()); - cb2.WaitForCallback(); EXPECT_EQ(cb2.value(), CtapDeviceResponseCode::kSuccess); // Enumerate to validate renaming. - test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>> + test::StatusAndValueCallbackReceiver< + CtapDeviceResponseCode, + base::Optional<std::map<std::vector<uint8_t>, std::string>>> cb3; handler->EnumerateTemplates(cb3.callback()); - cb3.WaitForCallback(); EXPECT_EQ(cb3.status(), CtapDeviceResponseCode::kSuccess); - - BioEnrollmentResponse expected; - expected.template_infos = - std::map<std::vector<uint8_t>, std::string>{{{1}, "OtherFingerprint1"}}; - EXPECT_EQ(cb3.value(), expected); + EXPECT_EQ(cb3.value(), (std::map<std::vector<uint8_t>, std::string>{ + {{1}, "OtherFingerprint1"}})); } // Tests deleting an enrollment (success and failure). @@ -372,30 +363,24 @@ // Delete non-existent enrollment. test::ValueCallbackReceiver<CtapDeviceResponseCode> cb0; handler->DeleteTemplate({1}, cb0.callback()); - cb0.WaitForCallback(); EXPECT_EQ(cb0.value(), CtapDeviceResponseCode::kCtap2ErrInvalidOption); // Enroll - skip response validation. - test::StatusAndValueCallbackReceiver<CtapDeviceResponseCode, - base::Optional<BioEnrollmentResponse>> - cb1; - handler->EnrollTemplate(cb1.callback()); - + test::ValueCallbackReceiver<CtapDeviceResponseCode> cb1; + handler->EnrollTemplate(MakeStatusCallback(), cb1.callback()); cb1.WaitForCallback(); - EXPECT_EQ(cb1.status(), CtapDeviceResponseCode::kSuccess); + EXPECT_EQ(cb1.value(), CtapDeviceResponseCode::kSuccess); // Delete existing enrollment. test::ValueCallbackReceiver<CtapDeviceResponseCode> cb2; handler->DeleteTemplate({1}, cb2.callback()); - cb2.WaitForCallback(); EXPECT_EQ(cb2.value(), CtapDeviceResponseCode::kSuccess); // Attempt to delete again to prove enrollment is gone. test::ValueCallbackReceiver<CtapDeviceResponseCode> cb3; handler->DeleteTemplate({1}, cb3.callback()); - cb3.WaitForCallback(); EXPECT_EQ(cb3.value(), CtapDeviceResponseCode::kCtap2ErrInvalidOption); }
diff --git a/device/fido/fido_authenticator.cc b/device/fido/fido_authenticator.cc index 9894c44..9574e87 100644 --- a/device/fido/fido_authenticator.cc +++ b/device/fido/fido_authenticator.cc
@@ -92,6 +92,7 @@ } void FidoAuthenticator::BioEnrollFingerprint(const pin::TokenResponse&, + BioEnrollmentSampleCallback, BioEnrollmentCallback) { NOTREACHED(); }
diff --git a/device/fido/fido_authenticator.h b/device/fido/fido_authenticator.h index d91d873..b0b201c1 100644 --- a/device/fido/fido_authenticator.h +++ b/device/fido/fido_authenticator.h
@@ -73,6 +73,8 @@ using BioEnrollmentCallback = base::OnceCallback<void(CtapDeviceResponseCode, base::Optional<BioEnrollmentResponse>)>; + using BioEnrollmentSampleCallback = + base::RepeatingCallback<void(BioEnrollmentSampleStatus, uint8_t)>; FidoAuthenticator() = default; virtual ~FidoAuthenticator() = default; @@ -173,6 +175,7 @@ virtual void GetModality(BioEnrollmentCallback callback); virtual void GetSensorInfo(BioEnrollmentCallback callback); virtual void BioEnrollFingerprint(const pin::TokenResponse&, + BioEnrollmentSampleCallback, BioEnrollmentCallback); virtual void BioEnrollCancel(BioEnrollmentCallback); virtual void BioEnrollEnumerate(const pin::TokenResponse&,
diff --git a/device/fido/fido_device_authenticator.cc b/device/fido/fido_device_authenticator.cc index a15be8e..1306fcb8 100644 --- a/device/fido/fido_device_authenticator.cc +++ b/device/fido/fido_device_authenticator.cc
@@ -518,13 +518,14 @@ void FidoDeviceAuthenticator::BioEnrollFingerprint( const pin::TokenResponse& response, - BioEnrollmentCallback callback) { + BioEnrollmentSampleCallback sample_callback, + BioEnrollmentCallback completion_callback) { RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>( BioEnrollmentRequest::ForEnrollBegin( GetBioEnrollmentRequestVersion(*Options()), response), base::BindOnce(&FidoDeviceAuthenticator::OnBioEnroll, weak_factory_.GetWeakPtr(), std::move(response), - std::move(callback), + std::move(sample_callback), std::move(completion_callback), /*current_template_id=*/base::nullopt), base::BindOnce(&BioEnrollmentResponse::Parse)); } @@ -554,25 +555,29 @@ void FidoDeviceAuthenticator::OnBioEnroll( pin::TokenResponse response, - BioEnrollmentCallback callback, + BioEnrollmentSampleCallback sample_callback, + BioEnrollmentCallback completion_callback, base::Optional<std::vector<uint8_t>> current_template_id, CtapDeviceResponseCode code, base::Optional<BioEnrollmentResponse> bio) { - if (code != CtapDeviceResponseCode::kSuccess || bio->remaining_samples == 0) { - std::move(callback).Run(code, std::move(bio)); + if (code != CtapDeviceResponseCode::kSuccess || !bio->last_status || + !bio->remaining_samples || bio->remaining_samples == 0) { + std::move(completion_callback).Run(code, std::move(bio)); return; } if (!current_template_id) { if (!bio->template_id) { // The templateId response field is required in the first response of each // enrollment. - std::move(callback).Run(CtapDeviceResponseCode::kCtap2ErrOther, - base::nullopt); + std::move(completion_callback) + .Run(CtapDeviceResponseCode::kCtap2ErrOther, base::nullopt); return; } current_template_id = *bio->template_id; } + sample_callback.Run(*bio->last_status, *bio->remaining_samples); + auto request = BioEnrollmentRequest::ForEnrollNextSample( GetBioEnrollmentRequestVersion(*Options()), response, *current_template_id); @@ -581,7 +586,8 @@ std::move(request), base::BindOnce(&FidoDeviceAuthenticator::OnBioEnroll, weak_factory_.GetWeakPtr(), std::move(response), - std::move(callback), std::move(current_template_id)), + std::move(sample_callback), std::move(completion_callback), + std::move(current_template_id)), base::BindOnce(&BioEnrollmentResponse::Parse)); }
diff --git a/device/fido/fido_device_authenticator.h b/device/fido/fido_device_authenticator.h index 6e54bdc8..df37df91 100644 --- a/device/fido/fido_device_authenticator.h +++ b/device/fido/fido_device_authenticator.h
@@ -82,6 +82,7 @@ void GetModality(BioEnrollmentCallback callback) override; void GetSensorInfo(BioEnrollmentCallback callback) override; void BioEnrollFingerprint(const pin::TokenResponse&, + BioEnrollmentSampleCallback, BioEnrollmentCallback) override; void BioEnrollCancel(BioEnrollmentCallback) override; void BioEnrollEnumerate(const pin::TokenResponse&, @@ -150,7 +151,8 @@ base::Optional<EnumerateCredentialsResponse> response); void OnBioEnroll(pin::TokenResponse, - BioEnrollmentCallback callback, + BioEnrollmentSampleCallback sample_callback, + BioEnrollmentCallback completion_callback, base::Optional<std::vector<uint8_t>> current_template_id, CtapDeviceResponseCode, base::Optional<BioEnrollmentResponse>);
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index efbe4ab..8edcd43b 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -771,38 +771,32 @@ return true; } -void WebRequestAPI::MaybeProxyWebSocket( +void WebRequestAPI::ProxyWebSocket( content::RenderFrameHost* frame, - network::mojom::WebSocketRequest* request, - network::mojom::AuthenticationHandlerPtr* auth_handler, - network::mojom::TrustedHeaderClientPtr* header_client) { + content::ContentBrowserClient::WebSocketFactory factory, + const GURL& url, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + network::mojom::WebSocketHandshakeClientPtr handshake_client) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!MayHaveProxies()) - return; + DCHECK(MayHaveProxies()); - network::mojom::WebSocketPtrInfo proxied_socket_ptr_info; - auto proxied_request = std::move(*request); - *request = mojo::MakeRequest(&proxied_socket_ptr_info); - auto authentication_request = mojo::MakeRequest(auth_handler); - - network::mojom::TrustedHeaderClientRequest header_client_request; - if (ExtensionWebRequestEventRouter::GetInstance() + const bool has_extra_headers = + ExtensionWebRequestEventRouter::GetInstance() ->HasAnyExtraHeadersListenerOnUI( - frame->GetProcess()->GetBrowserContext())) { - header_client_request = mojo::MakeRequest(header_client); - } + frame->GetProcess()->GetBrowserContext()); base::PostTaskWithTraits( FROM_HERE, {BrowserThread::IO}, base::BindOnce( - &WebRequestProxyingWebSocket::StartProxying, - frame->GetProcess()->GetID(), frame->GetRoutingID(), - request_id_generator_, frame->GetLastCommittedOrigin(), + &WebRequestProxyingWebSocket::StartProxying, std::move(factory), url, + site_for_cookies, user_agent, handshake_client.PassInterface(), + has_extra_headers, frame->GetProcess()->GetID(), + frame->GetRoutingID(), request_id_generator_, + frame->GetLastCommittedOrigin(), frame->GetProcess()->GetBrowserContext(), frame->GetProcess()->GetBrowserContext()->GetResourceContext(), - base::Unretained(info_map_), std::move(proxied_socket_ptr_info), - std::move(proxied_request), std::move(authentication_request), - std::move(header_client_request))); + base::Unretained(info_map_))); } void WebRequestAPI::ForceProxyForTesting() {
diff --git a/extensions/browser/api/web_request/web_request_api.h b/extensions/browser/api/web_request/web_request_api.h index eacca307..b729c23 100644 --- a/extensions/browser/api/web_request/web_request_api.h +++ b/extensions/browser/api/web_request/web_request_api.h
@@ -214,18 +214,22 @@ bool is_main_frame, AuthRequestCallback callback); - // If any WebRequest event listeners are currently active for this - // BrowserContext, |*request| is swapped out for a new request which proxies - // through an internal WebSocket implementation. This supports lifetime - // observation and control on behalf of the WebRequest API. - void MaybeProxyWebSocket( + // Starts proxying the connection with |factory|. This function can be called + // only when MayHaveProxies() returns true. + void ProxyWebSocket( content::RenderFrameHost* frame, - network::mojom::WebSocketRequest* request, - network::mojom::AuthenticationHandlerPtr* auth_handler, - network::mojom::TrustedHeaderClientPtr* header_client); + content::ContentBrowserClient::WebSocketFactory factory, + const GURL& url, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + network::mojom::WebSocketHandshakeClientPtr handshake_client); void ForceProxyForTesting(); + // Indicates whether or not the WebRequestAPI may have one or more proxies + // installed to support the API. + bool MayHaveProxies() const; + private: friend class BrowserContextKeyedAPIFactory<WebRequestAPI>; @@ -234,10 +238,6 @@ static const bool kServiceRedirectedInIncognito = true; static const bool kServiceIsNULLWhileTesting = true; - // Indicates whether or not the WebRequestAPI may have one or more proxies - // installed to support the API. - bool MayHaveProxies() const; - // Checks if |MayHaveProxies()| has changed from false to true, and resets // URLLoaderFactories if so. void UpdateMayHaveProxies();
diff --git a/extensions/browser/api/web_request/web_request_proxying_websocket.cc b/extensions/browser/api/web_request/web_request_proxying_websocket.cc index a468635d..7df5ec0c 100644 --- a/extensions/browser/api/web_request/web_request_proxying_websocket.cc +++ b/extensions/browser/api/web_request/web_request_proxying_websocket.cc
@@ -16,53 +16,42 @@ namespace extensions { WebRequestProxyingWebSocket::WebRequestProxyingWebSocket( + WebSocketFactory factory, + const network::ResourceRequest& request, + network::mojom::WebSocketHandshakeClientPtr handshake_client, + bool has_extra_headers, int process_id, int render_frame_id, - const url::Origin& origin, content::BrowserContext* browser_context, content::ResourceContext* resource_context, InfoMap* info_map, scoped_refptr<WebRequestAPI::RequestIDGenerator> request_id_generator, - network::mojom::WebSocketPtr proxied_socket, - network::mojom::WebSocketRequest proxied_request, - network::mojom::AuthenticationHandlerRequest auth_request, - network::mojom::TrustedHeaderClientRequest header_client_request, WebRequestAPI::ProxySet* proxies) - : process_id_(process_id), - render_frame_id_(render_frame_id), - origin_(origin), + : factory_(std::move(factory)), browser_context_(browser_context), - resource_context_(resource_context), info_map_(info_map), - request_id_generator_(std::move(request_id_generator)), - proxied_socket_(std::move(proxied_socket)), - binding_as_websocket_(this), - binding_as_client_(this), + forwarding_handshake_client_(std::move(handshake_client)), + binding_as_handshake_client_(this), binding_as_auth_handler_(this), - binding_as_header_client_(this), + binding_as_header_client_(has_extra_headers ? this : nullptr), + request_headers_(request.headers), + info_(WebRequestInfoInitParams(request_id_generator->Generate(), + process_id, + render_frame_id, + nullptr, + MSG_ROUTING_NONE, + resource_context, + request, + false /* is_download */, + true /* is_async */)), proxies_(proxies), - weak_factory_(this) { - binding_as_websocket_.Bind(std::move(proxied_request)); - binding_as_auth_handler_.Bind(std::move(auth_request)); - - binding_as_websocket_.set_connection_error_handler( - base::BindRepeating(&WebRequestProxyingWebSocket::OnError, - base::Unretained(this), net::ERR_FAILED)); - binding_as_auth_handler_.set_connection_error_handler( - base::BindRepeating(&WebRequestProxyingWebSocket::OnError, - base::Unretained(this), net::ERR_FAILED)); - - if (header_client_request) - binding_as_header_client_.Bind(std::move(header_client_request)); -} + weak_factory_(this) {} WebRequestProxyingWebSocket::~WebRequestProxyingWebSocket() { // This is important to ensure that no outstanding blocking requests continue // to reference state owned by this object. - if (info_) { - ExtensionWebRequestEventRouter::GetInstance()->OnRequestWillBeDestroyed( - browser_context_, &info_.value()); - } + ExtensionWebRequestEventRouter::GetInstance()->OnRequestWillBeDestroyed( + browser_context_, &info_); if (on_before_send_headers_callback_) { std::move(on_before_send_headers_callback_) .Run(net::ERR_ABORTED, base::nullopt); @@ -73,40 +62,12 @@ } } -void WebRequestProxyingWebSocket::AddChannelRequest( - const GURL& url, - const std::vector<std::string>& requested_protocols, - const GURL& site_for_cookies, - std::vector<network::mojom::HttpHeaderPtr> additional_headers, - network::mojom::WebSocketHandshakeClientPtr handshake_client, - network::mojom::WebSocketClientPtr client) { - if (binding_as_client_.is_bound() || !handshake_client || - forwarding_handshake_client_ || !client || forwarding_client_) { - // Illegal request. - proxied_socket_ = nullptr; - return; - } - - request_.url = url; - request_.site_for_cookies = site_for_cookies; - request_.request_initiator = origin_; - websocket_protocols_ = requested_protocols; - uint64_t request_id = request_id_generator_->Generate(); - int routing_id = MSG_ROUTING_NONE; - info_.emplace( - WebRequestInfoInitParams(request_id, process_id_, render_frame_id_, - nullptr, routing_id, resource_context_, request_, - false /* is_download */, true /* is_async */)); - - forwarding_handshake_client_ = std::move(handshake_client); - forwarding_client_ = std::move(client); - additional_headers_ = std::move(additional_headers); - +void WebRequestProxyingWebSocket::Start() { // If the header client will be used, we start the request immediately, and // OnBeforeSendHeaders and OnSendHeaders will be handled there. Otherwise, // send these events before the request starts. base::RepeatingCallback<void(int)> continuation; - if (binding_as_header_client_) { + if (binding_as_header_client_.impl()) { continuation = base::BindRepeating( &WebRequestProxyingWebSocket::ContinueToStartRequest, weak_factory_.GetWeakPtr()); @@ -120,7 +81,7 @@ // WebRequestProxyingURLLoaderFactory). bool should_collapse_initiator = false; int result = ExtensionWebRequestEventRouter::GetInstance()->OnBeforeRequest( - browser_context_, info_map_, &info_.value(), continuation, &redirect_url_, + browser_context_, info_map_, &info_, continuation, &redirect_url_, &should_collapse_initiator); // It doesn't make sense to collapse WebSocket requests since they won't be @@ -140,23 +101,6 @@ continuation.Run(net::OK); } -void WebRequestProxyingWebSocket::SendFrame( - bool fin, - network::mojom::WebSocketMessageType type, - const std::vector<uint8_t>& data) { - proxied_socket_->SendFrame(fin, type, data); -} - -void WebRequestProxyingWebSocket::AddReceiveFlowControlQuota(int64_t quota) { - proxied_socket_->AddReceiveFlowControlQuota(quota); -} - -void WebRequestProxyingWebSocket::StartClosingHandshake( - uint16_t code, - const std::string& reason) { - proxied_socket_->StartClosingHandshake(code, reason); -} - void WebRequestProxyingWebSocket::OnOpeningHandshakeStarted( network::mojom::WebSocketHandshakeRequestPtr request) { DCHECK(forwarding_handshake_client_); @@ -199,7 +143,7 @@ &WebRequestProxyingWebSocket::OnHeadersReceivedComplete, weak_factory_.GetWeakPtr()); int result = ExtensionWebRequestEventRouter::GetInstance()->OnHeadersReceived( - browser_context_, info_map_, &info_.value(), continuation, + browser_context_, info_map_, &info_, continuation, response_.headers.get(), &override_headers_, &redirect_url_); if (result == net::ERR_BLOCKED_BY_CLIENT) { @@ -216,6 +160,7 @@ } void WebRequestProxyingWebSocket::OnConnectionEstablished( + network::mojom::WebSocketPtr websocket, const std::string& selected_protocol, const std::string& extensions, uint64_t receive_quota_threshold) { @@ -223,10 +168,14 @@ DCHECK(!is_done_); is_done_ = true; ExtensionWebRequestEventRouter::GetInstance()->OnCompleted( - browser_context_, info_map_, &info_.value(), net::ERR_WS_UPGRADE); + browser_context_, info_map_, &info_, net::ERR_WS_UPGRADE); forwarding_handshake_client_->OnConnectionEstablished( - selected_protocol, extensions, receive_quota_threshold); + std::move(websocket), selected_protocol, extensions, + receive_quota_threshold); + + // Deletes |this|. + proxies_->RemoveProxy(this); } void WebRequestProxyingWebSocket::OnAuthRequired( @@ -247,7 +196,7 @@ &WebRequestProxyingWebSocket::OnHeadersReceivedCompleteForAuth, weak_factory_.GetWeakPtr(), auth_info); int result = ExtensionWebRequestEventRouter::GetInstance()->OnHeadersReceived( - browser_context_, info_map_, &info_.value(), continuation, + browser_context_, info_map_, &info_, continuation, response_.headers.get(), &override_headers_, &redirect_url_); if (result == net::ERR_BLOCKED_BY_CLIENT) { @@ -268,7 +217,7 @@ OnBeforeSendHeadersCallback callback) { DCHECK(binding_as_header_client_); - request_.headers = headers; + request_headers_ = headers; on_before_send_headers_callback_ = std::move(callback); OnBeforeRequestComplete(net::OK); } @@ -280,7 +229,7 @@ // Note: since there are different pipes used for WebSocketClient and // TrustedHeaderClient, there are no guarantees whether this or - // OnFinishOpeningHandshake are called first. + // OnResponseReceived are called first. on_headers_received_callback_ = std::move(callback); response_.headers = base::MakeRefCounted<net::HttpResponseHeaders>(headers); @@ -292,34 +241,44 @@ } void WebRequestProxyingWebSocket::StartProxying( + WebSocketFactory factory, + const GURL& url, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + network::mojom::WebSocketHandshakeClientPtrInfo handshake_client, + bool has_extra_headers, int process_id, int render_frame_id, scoped_refptr<WebRequestAPI::RequestIDGenerator> request_id_generator, const url::Origin& origin, content::BrowserContext* browser_context, content::ResourceContext* resource_context, - InfoMap* info_map, - network::mojom::WebSocketPtrInfo proxied_socket_ptr_info, - network::mojom::WebSocketRequest proxied_request, - network::mojom::AuthenticationHandlerRequest auth_request, - network::mojom::TrustedHeaderClientRequest header_client_request) { + InfoMap* info_map) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); auto* proxies = WebRequestAPI::ProxySet::GetFromResourceContext(resource_context); + network::ResourceRequest request; + request.url = url; + request.site_for_cookies = site_for_cookies; + if (user_agent) { + request.headers.SetHeader(net::HttpRequestHeaders::kUserAgent, *user_agent); + } + request.request_initiator = origin; auto proxy = std::make_unique<WebRequestProxyingWebSocket>( - process_id, render_frame_id, origin, browser_context, resource_context, - info_map, std::move(request_id_generator), - network::mojom::WebSocketPtr(std::move(proxied_socket_ptr_info)), - std::move(proxied_request), std::move(auth_request), - std::move(header_client_request), proxies); + std::move(factory), request, + network::mojom::WebSocketHandshakeClientPtr(std::move(handshake_client)), + has_extra_headers, process_id, render_frame_id, browser_context, + resource_context, info_map, std::move(request_id_generator), proxies); + auto* raw_proxy = proxy.get(); proxies->AddProxy(std::move(proxy)); + raw_proxy->Start(); } void WebRequestProxyingWebSocket::OnBeforeRequestComplete(int error_code) { - DCHECK(binding_as_header_client_ || !binding_as_client_.is_bound()); - DCHECK(request_.url.SchemeIsWSOrWSS()); + DCHECK(binding_as_header_client_ || !binding_as_handshake_client_.is_bound()); + DCHECK(info_.url.SchemeIsWSOrWSS()); if (error_code != net::OK) { OnError(error_code); return; @@ -331,8 +290,7 @@ int result = ExtensionWebRequestEventRouter::GetInstance()->OnBeforeSendHeaders( - browser_context_, info_map_, &info_.value(), continuation, - &request_.headers); + browser_context_, info_map_, &info_, continuation, &request_headers_); if (result == net::ERR_BLOCKED_BY_CLIENT) { OnError(result); @@ -351,7 +309,7 @@ const std::set<std::string>& removed_headers, const std::set<std::string>& set_headers, int error_code) { - DCHECK(binding_as_header_client_ || !binding_as_client_.is_bound()); + DCHECK(binding_as_header_client_ || !binding_as_handshake_client_.is_bound()); if (error_code != net::OK) { OnError(error_code); return; @@ -360,22 +318,20 @@ if (binding_as_header_client_) { DCHECK(on_before_send_headers_callback_); std::move(on_before_send_headers_callback_) - .Run(error_code, request_.headers); + .Run(error_code, request_headers_); } ExtensionWebRequestEventRouter::GetInstance()->OnSendHeaders( - browser_context_, info_map_, &info_.value(), request_.headers); + browser_context_, info_map_, &info_, request_headers_); if (!binding_as_header_client_) ContinueToStartRequest(net::OK); } void WebRequestProxyingWebSocket::ContinueToStartRequest(int error_code) { - network::mojom::WebSocketHandshakeClientPtr proxy; - base::flat_set<std::string> used_header_names; std::vector<network::mojom::HttpHeaderPtr> additional_headers; - for (net::HttpRequestHeaders::Iterator it(request_.headers); it.GetNext();) { + for (net::HttpRequestHeaders::Iterator it(request_headers_); it.GetNext();) { additional_headers.push_back( network::mojom::HttpHeader::New(it.name(), it.value())); used_header_names.insert(base::ToLowerASCII(it.name())); @@ -387,14 +343,29 @@ } } - binding_as_client_.Bind(mojo::MakeRequest(&proxy)); - binding_as_client_.set_connection_error_handler( + network::mojom::WebSocketHandshakeClientPtr handshake_client; + binding_as_handshake_client_.Bind(mojo::MakeRequest(&handshake_client)); + binding_as_handshake_client_.set_connection_error_handler( base::BindOnce(&WebRequestProxyingWebSocket::OnError, base::Unretained(this), net::ERR_FAILED)); - proxied_socket_->AddChannelRequest( - request_.url, websocket_protocols_, request_.site_for_cookies, - std::move(additional_headers), std::move(proxy), - std::move(forwarding_client_)); + + network::mojom::AuthenticationHandlerPtr auth_handler; + binding_as_auth_handler_.Bind(mojo::MakeRequest(&auth_handler)); + binding_as_auth_handler_.set_connection_error_handler( + base::BindOnce(&WebRequestProxyingWebSocket::OnError, + base::Unretained(this), net::ERR_FAILED)); + + network::mojom::TrustedHeaderClientPtr trusted_header_client; + if (binding_as_header_client_.impl()) { + binding_as_header_client_.Bind(mojo::MakeRequest(&trusted_header_client)); + binding_as_header_client_.set_connection_error_handler( + base::BindOnce(&WebRequestProxyingWebSocket::OnError, + base::Unretained(this), net::ERR_FAILED)); + } + + std::move(factory_).Run(info_.url, std::move(additional_headers), + std::move(handshake_client), std::move(auth_handler), + std::move(trusted_header_client)); } void WebRequestProxyingWebSocket::OnHeadersReceivedComplete(int error_code) { @@ -416,9 +387,9 @@ } ResumeIncomingMethodCallProcessing(); - info_->AddResponseInfoFromResourceResponse(response_); + info_.AddResponseInfoFromResourceResponse(response_); ExtensionWebRequestEventRouter::GetInstance()->OnResponseStarted( - browser_context_, info_map_, &info_.value(), net::OK); + browser_context_, info_map_, &info_, net::OK); } void WebRequestProxyingWebSocket::OnAuthRequiredComplete( @@ -448,14 +419,14 @@ return; } ResumeIncomingMethodCallProcessing(); - info_->AddResponseInfoFromResourceResponse(response_); + info_.AddResponseInfoFromResourceResponse(response_); auto continuation = base::BindRepeating(&WebRequestProxyingWebSocket::OnAuthRequiredComplete, weak_factory_.GetWeakPtr()); auto auth_rv = ExtensionWebRequestEventRouter::GetInstance()->OnAuthRequired( - browser_context_, info_map_, &info_.value(), auth_info, - std::move(continuation), &auth_credentials_); + browser_context_, info_map_, &info_, auth_info, std::move(continuation), + &auth_credentials_); PauseIncomingMethodCallProcessing(); if (auth_rv == net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_IO_PENDING) return; @@ -464,25 +435,24 @@ } void WebRequestProxyingWebSocket::PauseIncomingMethodCallProcessing() { - binding_as_client_.PauseIncomingMethodCallProcessing(); + binding_as_handshake_client_.PauseIncomingMethodCallProcessing(); binding_as_auth_handler_.PauseIncomingMethodCallProcessing(); if (binding_as_header_client_) binding_as_header_client_.PauseIncomingMethodCallProcessing(); } void WebRequestProxyingWebSocket::ResumeIncomingMethodCallProcessing() { - binding_as_client_.ResumeIncomingMethodCallProcessing(); + binding_as_handshake_client_.ResumeIncomingMethodCallProcessing(); binding_as_auth_handler_.ResumeIncomingMethodCallProcessing(); if (binding_as_header_client_) binding_as_header_client_.ResumeIncomingMethodCallProcessing(); } void WebRequestProxyingWebSocket::OnError(int error_code) { - if (!is_done_ && info_.has_value()) { + if (!is_done_) { is_done_ = true; ExtensionWebRequestEventRouter::GetInstance()->OnErrorOccurred( - browser_context_, info_map_, &info_.value(), true /* started */, - error_code); + browser_context_, info_map_, &info_, true /* started */, error_code); } // Deletes |this|.
diff --git a/extensions/browser/api/web_request/web_request_proxying_websocket.h b/extensions/browser/api/web_request/web_request_proxying_websocket.h index a896caf8..7fc166b 100644 --- a/extensions/browser/api/web_request/web_request_proxying_websocket.h +++ b/extensions/browser/api/web_request/web_request_proxying_websocket.h
@@ -35,50 +35,39 @@ // WebRequest API events. class WebRequestProxyingWebSocket : public WebRequestAPI::Proxy, - public network::mojom::WebSocket, public network::mojom::WebSocketHandshakeClient, public network::mojom::AuthenticationHandler, public network::mojom::TrustedHeaderClient { public: + using WebSocketFactory = content::ContentBrowserClient::WebSocketFactory; + WebRequestProxyingWebSocket( + WebSocketFactory factory, + const network::ResourceRequest& request, + network::mojom::WebSocketHandshakeClientPtr handshake_client, + bool has_extra_headers, int process_id, int render_frame_id, - const url::Origin& origin, content::BrowserContext* browser_context, content::ResourceContext* resource_context, InfoMap* info_map, scoped_refptr<WebRequestAPI::RequestIDGenerator> request_id_generator, - network::mojom::WebSocketPtr proxied_socket, - network::mojom::WebSocketRequest proxied_request, - network::mojom::AuthenticationHandlerRequest auth_request, - network::mojom::TrustedHeaderClientRequest header_client_request, WebRequestAPI::ProxySet* proxies); ~WebRequestProxyingWebSocket() override; - // mojom::WebSocket methods: - void AddChannelRequest( - const GURL& url, - const std::vector<std::string>& requested_protocols, - const GURL& site_for_cookies, - std::vector<network::mojom::HttpHeaderPtr> additional_headers, - network::mojom::WebSocketHandshakeClientPtr handshake_client, - network::mojom::WebSocketClientPtr client) override; - void SendFrame(bool fin, - network::mojom::WebSocketMessageType type, - const std::vector<uint8_t>& data) override; - void AddReceiveFlowControlQuota(int64_t quota) override; - void StartClosingHandshake(uint16_t code, const std::string& reason) override; + void Start(); - // mojom::WebSocketHandShakeClient methods: + // network::mojom::WebSocketHandshakeClient methods: void OnOpeningHandshakeStarted( network::mojom::WebSocketHandshakeRequestPtr request) override; void OnResponseReceived( network::mojom::WebSocketHandshakeResponsePtr response) override; - void OnConnectionEstablished(const std::string& selected_protocol, + void OnConnectionEstablished(network::mojom::WebSocketPtr websocket, + const std::string& selected_protocol, const std::string& extensions, uint64_t receive_quota_threshold) override; - // mojom::AuthenticationHandler method: + // network::mojom::AuthenticationHandler method: void OnAuthRequired(const net::AuthChallengeInfo& auth_info, const scoped_refptr<net::HttpResponseHeaders>& headers, const net::IPEndPoint& remote_endpoint, @@ -91,17 +80,19 @@ OnHeadersReceivedCallback callback) override; static void StartProxying( + WebSocketFactory factory, + const GURL& url, + const GURL& site_for_cookies, + const base::Optional<std::string>& user_agent, + network::mojom::WebSocketHandshakeClientPtrInfo handshake_client, + bool has_extra_headers, int process_id, int render_frame_id, scoped_refptr<WebRequestAPI::RequestIDGenerator> request_id_generator, const url::Origin& origin, content::BrowserContext* browser_context, content::ResourceContext* resource_context, - InfoMap* info_map, - network::mojom::WebSocketPtrInfo proxied_socket_ptr_info, - network::mojom::WebSocketRequest proxied_request, - network::mojom::AuthenticationHandlerRequest auth_request, - network::mojom::TrustedHeaderClientRequest header_client_request); + InfoMap* info_map); private: void OnBeforeRequestComplete(int error_code); @@ -119,27 +110,20 @@ void ResumeIncomingMethodCallProcessing(); void OnError(int result); - const int process_id_; - const int render_frame_id_; - const url::Origin origin_; + WebSocketFactory factory_; content::BrowserContext* const browser_context_; - content::ResourceContext* const resource_context_; InfoMap* const info_map_; - scoped_refptr<WebRequestAPI::RequestIDGenerator> request_id_generator_; - network::mojom::WebSocketPtr proxied_socket_; network::mojom::WebSocketHandshakeClientPtr forwarding_handshake_client_; - network::mojom::WebSocketClientPtr forwarding_client_; - mojo::Binding<network::mojom::WebSocket> binding_as_websocket_; - mojo::Binding<network::mojom::WebSocketHandshakeClient> binding_as_client_; + mojo::Binding<network::mojom::WebSocketHandshakeClient> + binding_as_handshake_client_; mojo::Binding<network::mojom::AuthenticationHandler> binding_as_auth_handler_; mojo::Binding<network::mojom::TrustedHeaderClient> binding_as_header_client_; - network::ResourceRequest request_; + net::HttpRequestHeaders request_headers_; network::ResourceResponseHead response_; net::AuthCredentials auth_credentials_; OnAuthRequiredCallback auth_required_callback_; scoped_refptr<net::HttpResponseHeaders> override_headers_; - std::vector<std::string> websocket_protocols_; std::vector<network::mojom::HttpHeaderPtr> additional_headers_; OnBeforeSendHeadersCallback on_before_send_headers_callback_; @@ -149,7 +133,7 @@ bool is_done_ = false; bool waiting_for_header_client_headers_received_ = false; - base::Optional<WebRequestInfo> info_; + WebRequestInfo info_; // Owns |this|. WebRequestAPI::ProxySet* const proxies_;
diff --git a/fuchsia/runners/web/sandbox_policy b/fuchsia/runners/web/sandbox_policy index 18ccaed..95de89a 100644 --- a/fuchsia/runners/web/sandbox_policy +++ b/fuchsia/runners/web/sandbox_policy
@@ -18,7 +18,6 @@ "fuchsia.ui.input.ImeService", "fuchsia.ui.input.ImeVisibilityService", "fuchsia.ui.scenic.Scenic", - "fuchsia.vulkan.loader.Loader", "fuchsia.web.ContextProvider" ] }
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index fe1e9b4..d6aefe5 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -531,6 +531,7 @@ "config/gpu_control_list_version_unittest.cc", "config/gpu_driver_bug_list_unittest.cc", "config/gpu_info_collector_unittest.cc", + "config/gpu_info_unittest.cc", "config/gpu_preferences_unittest.cc", "config/gpu_test_config_unittest.cc", "config/gpu_test_expectations_parser_unittest.cc",
diff --git a/gpu/config/gpu_info_unittest.cc b/gpu/config/gpu_info_unittest.cc new file mode 100644 index 0000000..e30e5b2 --- /dev/null +++ b/gpu/config/gpu_info_unittest.cc
@@ -0,0 +1,119 @@ +// Copyright (c) 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 "gpu/config/gpu_info.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace gpu { + +namespace { +// This overrides the base class to test behaviors of virtual functions. +class TestGPUInfoEnumerator : public gpu::GPUInfo::Enumerator { + public: + TestGPUInfoEnumerator() + : gpu_device_active_(false), + video_decode_accelerator_profile_active_(false), + video_encode_accelerator_profile_active_(false), + image_decode_accelerator_profile_active_(false), + dx12_vulkan_version_info_active_(false), + aux_attributes_active_(false) {} + + void AddInt64(const char* name, int64_t value) override {} + + void AddInt(const char* name, int value) override {} + + void AddString(const char* name, const std::string& value) override {} + + void AddBool(const char* name, bool value) override {} + + void AddTimeDeltaInSecondsF(const char* name, + const base::TimeDelta& value) override {} + + // Enumerator state mutator functions + void BeginGPUDevice() override { gpu_device_active_ = true; } + + void EndGPUDevice() override { gpu_device_active_ = false; } + + void BeginVideoDecodeAcceleratorSupportedProfile() override { + video_decode_accelerator_profile_active_ = true; + } + + void EndVideoDecodeAcceleratorSupportedProfile() override { + video_decode_accelerator_profile_active_ = false; + } + + void BeginVideoEncodeAcceleratorSupportedProfile() override { + video_encode_accelerator_profile_active_ = true; + } + + void EndVideoEncodeAcceleratorSupportedProfile() override { + video_encode_accelerator_profile_active_ = false; + } + + void BeginImageDecodeAcceleratorSupportedProfile() override { + image_decode_accelerator_profile_active_ = true; + } + + void EndImageDecodeAcceleratorSupportedProfile() override { + image_decode_accelerator_profile_active_ = false; + } + + void BeginDx12VulkanVersionInfo() override { + dx12_vulkan_version_info_active_ = true; + } + + void EndDx12VulkanVersionInfo() override { + dx12_vulkan_version_info_active_ = false; + } + + void BeginAuxAttributes() override { aux_attributes_active_ = true; } + + void EndAuxAttributes() override { aux_attributes_active_ = false; } + + // Accessor functions + bool gpu_device_active() const { return gpu_device_active_; } + + bool video_decode_accelerator_profile_active() const { + return video_decode_accelerator_profile_active_; + } + + bool video_encode_accelerator_profile_active() const { + return video_encode_accelerator_profile_active_; + } + + bool image_decode_accelerator_profile_active() const { + return image_decode_accelerator_profile_active_; + } + + bool dx12_vulkan_version_info_active() const { + return dx12_vulkan_version_info_active_; + } + + bool aux_attributes_active() const { return aux_attributes_active_; } + + private: + bool gpu_device_active_; + bool video_decode_accelerator_profile_active_; + bool video_encode_accelerator_profile_active_; + bool image_decode_accelerator_profile_active_; + bool dx12_vulkan_version_info_active_; + bool aux_attributes_active_; +}; +} // namespace + +// Makes sure that after EnumerateFields is called, the field edit states +// are inactive +TEST(GpuInfoTest, FieldEditStates) { + GPUInfo gpu_info; + TestGPUInfoEnumerator enumerator; + gpu_info.EnumerateFields(&enumerator); + EXPECT_FALSE(enumerator.gpu_device_active()); + EXPECT_FALSE(enumerator.video_decode_accelerator_profile_active()); + EXPECT_FALSE(enumerator.video_encode_accelerator_profile_active()); + EXPECT_FALSE(enumerator.image_decode_accelerator_profile_active()); + EXPECT_FALSE(enumerator.dx12_vulkan_version_info_active()); + EXPECT_FALSE(enumerator.aux_attributes_active()); +} + +} // namespace gpu
diff --git a/gpu/vulkan/vulkan_surface.cc b/gpu/vulkan/vulkan_surface.cc index a4a1e05..339a0b5 100644 --- a/gpu/vulkan/vulkan_surface.cc +++ b/gpu/vulkan/vulkan_surface.cc
@@ -113,13 +113,12 @@ void VulkanSurface::Destroy() { swap_chain_->Destroy(); - swap_chain_ = nullptr; vkDestroySurfaceKHR(vk_instance_, surface_, nullptr); surface_ = VK_NULL_HANDLE; } gfx::SwapResult VulkanSurface::SwapBuffers() { - return swap_chain_->PresentBuffer(); + return swap_chain_->SwapBuffers(); } VulkanSwapChain* VulkanSurface::GetSwapChain() { @@ -134,7 +133,7 @@ return CreateSwapChain(size); } -bool VulkanSurface::CreateSwapChain(const gfx::Size& new_size) { +bool VulkanSurface::CreateSwapChain(const gfx::Size& size) { // Get Surface Information. VkSurfaceCapabilitiesKHR surface_caps; VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR( @@ -145,19 +144,19 @@ return false; } - // For Android, the current vulkan surface size may not match the new_size - // (the current window size), in that case, we will create a swapchain with - // the requested new_size, and vulkan surface size should match the swapchain - // images size soon. - if (!new_size.IsEmpty()) { - DLOG_IF(ERROR, - base::checked_cast<int>(surface_caps.currentExtent.width) != - new_size.width() || - base::checked_cast<int>(surface_caps.currentExtent.height) != - new_size.height()) - << "Requested new size doesn't match vulkan surface size."; - surface_caps.currentExtent.width = new_size.width(); - surface_caps.currentExtent.height = new_size.height(); + // If width and height of the surface are 0xFFFFFFFF, it means the surface + // size will be determined by the extent of a swapchain targeting the surface. + // In that case, we will use the |size| which is the window size for the + // swapchain. Otherwise, we just use the current surface size for the + // swapchian. + const uint32_t kUndefinedExtent = 0xFFFFFFFF; + if (surface_caps.currentExtent.width == kUndefinedExtent && + surface_caps.currentExtent.height == kUndefinedExtent) { + surface_caps.currentExtent.width = std::max( + surface_caps.minImageExtent.width, static_cast<uint32_t>(size.width())); + surface_caps.currentExtent.height = + std::max(surface_caps.minImageExtent.height, + static_cast<uint32_t>(size.height())); } DCHECK_GE(surface_caps.currentExtent.width, @@ -171,12 +170,14 @@ DCHECK_GT(surface_caps.currentExtent.width, 0u); DCHECK_GT(surface_caps.currentExtent.height, 0u); + gfx::Size new_size( + base::checked_cast<int>(surface_caps.currentExtent.width), + base::checked_cast<int>(surface_caps.currentExtent.height)); if (size_ == new_size) return true; size_ = new_size; auto swap_chain = std::make_unique<VulkanSwapChain>(); - // Create Swapchain. if (!swap_chain->Initialize(device_queue_, surface_, surface_caps, surface_format_, std::move(swap_chain_))) { @@ -184,7 +185,6 @@ } swap_chain_ = std::move(swap_chain); - ++swap_chain_generation_; return true; }
diff --git a/gpu/vulkan/vulkan_surface.h b/gpu/vulkan/vulkan_surface.h index c33a7387..8bae0235 100644 --- a/gpu/vulkan/vulkan_surface.h +++ b/gpu/vulkan/vulkan_surface.h
@@ -42,7 +42,6 @@ gfx::SwapResult SwapBuffers(); VulkanSwapChain* GetSwapChain(); - uint32_t swap_chain_generation() const { return swap_chain_generation_; } void Finish(); @@ -52,17 +51,13 @@ VkSurfaceFormatKHR surface_format() const { return surface_format_; } private: - bool CreateSwapChain(const gfx::Size& new_size); + bool CreateSwapChain(const gfx::Size& size); const VkInstance vk_instance_; gfx::Size size_; VkSurfaceKHR surface_ = VK_NULL_HANDLE; VkSurfaceFormatKHR surface_format_ = {}; VulkanDeviceQueue* device_queue_ = nullptr; - - // The generation of |swap_chain_|, it will be increasted if a new - // |swap_chain_| is created due to resizing, etec. - uint32_t swap_chain_generation_ = 0u; std::unique_ptr<VulkanSwapChain> swap_chain_; DISALLOW_COPY_AND_ASSIGN(VulkanSurface);
diff --git a/gpu/vulkan/vulkan_swap_chain.cc b/gpu/vulkan/vulkan_swap_chain.cc index c73853c..552d892 100644 --- a/gpu/vulkan/vulkan_swap_chain.cc +++ b/gpu/vulkan/vulkan_swap_chain.cc
@@ -56,8 +56,7 @@ DestroySwapChain(); } -gfx::SwapResult VulkanSwapChain::PresentBuffer() { - DCHECK(acquired_image_); +gfx::SwapResult VulkanSwapChain::SwapBuffers() { DCHECK(end_write_semaphore_ != VK_NULL_HANDLE); VkResult result = VK_SUCCESS; @@ -65,7 +64,7 @@ VkQueue queue = device_queue_->GetVulkanQueue(); auto* fence_helper = device_queue_->GetFenceHelper(); - auto& current_image_data = images_[*acquired_image_]; + auto& current_image_data = images_[current_image_]; if (current_image_data.layout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) { { current_image_data.command_buffer->Clear(); @@ -97,17 +96,31 @@ present_info.pWaitSemaphores = &end_write_semaphore_; present_info.swapchainCount = 1; present_info.pSwapchains = &swap_chain_; - present_info.pImageIndices = &acquired_image_.value(); + present_info.pImageIndices = ¤t_image_; result = vkQueuePresentKHR(queue, &present_info); - if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) { - DLOG(ERROR) << "vkQueuePresentKHR() failed: " << result; + if (VK_SUCCESS != result) { return gfx::SwapResult::SWAP_FAILED; } - acquired_image_.reset(); fence_helper->EnqueueSemaphoreCleanupForSubmittedWork(end_write_semaphore_); end_write_semaphore_ = VK_NULL_HANDLE; + VkSemaphore vk_semaphore = CreateSemaphore(device); + DCHECK(vk_semaphore != VK_NULL_HANDLE); + + uint32_t next_image = 0; + // Acquire then next image. + result = vkAcquireNextImageKHR(device, swap_chain_, UINT64_MAX, vk_semaphore, + VK_NULL_HANDLE, &next_image); + if (VK_SUCCESS != result) { + vkDestroySemaphore(device, vk_semaphore, nullptr /* pAllocator */); + DLOG(ERROR) << "vkAcquireNextImageKHR() failed: " << result; + return gfx::SwapResult::SWAP_FAILED; + } + + current_image_ = next_image; + DCHECK(begin_write_semaphore_ == VK_NULL_HANDLE); + begin_write_semaphore_ = vk_semaphore; return gfx::SwapResult::SWAP_ACK; } @@ -130,14 +143,7 @@ swap_chain_create_info.imageArrayLayers = 1; swap_chain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; swap_chain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - // Always set preTransform to VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR (which is - // relative to the presentation engine's natural orientation), if it does not - // match the currentTransform value returned by - // vkGetPhysicalDeviceSurfaceCapabilitiesKHR, the presentation engine will - // transform the image content as part of the presentation operation. - // TODO(penghuang): Support preTransform for better performance. - // https://crbug.com/957485 - swap_chain_create_info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + swap_chain_create_info.preTransform = surface_caps.currentTransform; swap_chain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; swap_chain_create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR; swap_chain_create_info.clipped = true; @@ -206,10 +212,27 @@ // Initialize the command buffer for this buffer data. image_data.command_buffer = command_pool_->CreatePrimaryCommandBuffer(); } + + VkSemaphore vk_semaphore = CreateSemaphore(device); + DCHECK(vk_semaphore != VK_NULL_HANDLE); + + // Acquire the initial buffer. + result = vkAcquireNextImageKHR(device, swap_chain_, UINT64_MAX, vk_semaphore, + VK_NULL_HANDLE, ¤t_image_); + if (VK_SUCCESS != result) { + DLOG(ERROR) << "vkAcquireNextImageKHR() failed: " << result; + return false; + } + begin_write_semaphore_ = vk_semaphore; return true; } void VulkanSwapChain::DestroySwapImages() { + if (begin_write_semaphore_) + vkDestroySemaphore(device_queue_->GetVulkanDevice(), begin_write_semaphore_, + nullptr /* pAllocator */); + begin_write_semaphore_ = VK_NULL_HANDLE; + if (end_write_semaphore_) vkDestroySemaphore(device_queue_->GetVulkanDevice(), end_write_semaphore_, nullptr /* pAllocator */); @@ -227,7 +250,7 @@ command_pool_ = nullptr; } -bool VulkanSwapChain::BeginWriteCurrentImage(VkImage* image, +void VulkanSwapChain::BeginWriteCurrentImage(VkImage* image, uint32_t* image_index, VkImageLayout* image_layout, VkSemaphore* semaphore) { @@ -236,52 +259,25 @@ DCHECK(image_layout); DCHECK(semaphore); DCHECK(!is_writing_); + DCHECK(begin_write_semaphore_ != VK_NULL_HANDLE); + DCHECK(end_write_semaphore_ == VK_NULL_HANDLE); - VkSemaphore vk_semaphore = VK_NULL_HANDLE; - - if (!acquired_image_) { - DCHECK(end_write_semaphore_ == VK_NULL_HANDLE); - - VkDevice device = device_queue_->GetVulkanDevice(); - vk_semaphore = CreateSemaphore(device); - DCHECK(vk_semaphore != VK_NULL_HANDLE); - - uint32_t next_image = 0; - // Acquire then next image. - auto result = - vkAcquireNextImageKHR(device, swap_chain_, UINT64_MAX, vk_semaphore, - VK_NULL_HANDLE, &next_image); - if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) { - vkDestroySemaphore(device, vk_semaphore, nullptr /* pAllocator */); - DLOG(ERROR) << "vkAcquireNextImageKHR() failed: " << result; - return false; - } - acquired_image_.emplace(next_image); - } else { - // In this case, PresentBuffer() is not called after - // {Begin,End}WriteCurrentImage pairs, |end_write_semaphore_| should be - // waited on before writing the image again. - vk_semaphore = end_write_semaphore_; - end_write_semaphore_ = VK_NULL_HANDLE; - } - - auto& current_image_data = images_[*acquired_image_]; + auto& current_image_data = images_[current_image_]; *image = current_image_data.image; - *image_index = *acquired_image_; + *image_index = current_image_; *image_layout = current_image_data.layout; - *semaphore = vk_semaphore; + *semaphore = begin_write_semaphore_; + begin_write_semaphore_ = VK_NULL_HANDLE; is_writing_ = true; - - return true; } void VulkanSwapChain::EndWriteCurrentImage(VkImageLayout image_layout, VkSemaphore semaphore) { DCHECK(is_writing_); - DCHECK(acquired_image_); + DCHECK(begin_write_semaphore_ == VK_NULL_HANDLE); DCHECK(end_write_semaphore_ == VK_NULL_HANDLE); - auto& current_image_data = images_[*acquired_image_]; + auto& current_image_data = images_[current_image_]; current_image_data.layout = image_layout; end_write_semaphore_ = semaphore; is_writing_ = false; @@ -289,17 +285,17 @@ VulkanSwapChain::ScopedWrite::ScopedWrite(VulkanSwapChain* swap_chain) : swap_chain_(swap_chain) { - success_ = swap_chain_->BeginWriteCurrentImage( - &image_, &image_index_, &image_layout_, &begin_semaphore_); + swap_chain_->BeginWriteCurrentImage(&image_, &image_index_, &image_layout_, + &begin_semaphore_); } VulkanSwapChain::ScopedWrite::~ScopedWrite() { DCHECK(begin_semaphore_ == VK_NULL_HANDLE); - if (success_) - swap_chain_->EndWriteCurrentImage(image_layout_, end_semaphore_); + swap_chain_->EndWriteCurrentImage(image_layout_, end_semaphore_); } VkSemaphore VulkanSwapChain::ScopedWrite::TakeBeginSemaphore() { + DCHECK(begin_semaphore_ != VK_NULL_HANDLE); VkSemaphore semaphore = begin_semaphore_; begin_semaphore_ = VK_NULL_HANDLE; return semaphore;
diff --git a/gpu/vulkan/vulkan_swap_chain.h b/gpu/vulkan/vulkan_swap_chain.h index 11f8996a..c073c50 100644 --- a/gpu/vulkan/vulkan_swap_chain.h +++ b/gpu/vulkan/vulkan_swap_chain.h
@@ -10,7 +10,6 @@ #include <vulkan/vulkan.h> #include "base/logging.h" -#include "base/optional.h" #include "gpu/vulkan/vulkan_export.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/swap_result.h" @@ -28,7 +27,6 @@ explicit ScopedWrite(VulkanSwapChain* swap_chain); ~ScopedWrite(); - bool success() const { return success_; } VkImage image() const { return image_; } uint32_t image_index() const { return image_index_; } VkImageLayout image_layout() const { return image_layout_; } @@ -44,7 +42,6 @@ private: VulkanSwapChain* const swap_chain_; - bool success_ = false; VkImage image_ = VK_NULL_HANDLE; uint32_t image_index_ = 0; VkImageLayout image_layout_ = VK_IMAGE_LAYOUT_UNDEFINED; @@ -64,11 +61,10 @@ std::unique_ptr<VulkanSwapChain> old_swap_chain); // Destroy() should be called when all related GPU tasks have been finished. void Destroy(); - - // Present the current buffer. - gfx::SwapResult PresentBuffer(); + gfx::SwapResult SwapBuffers(); uint32_t num_images() const { return static_cast<uint32_t>(images_.size()); } + uint32_t current_image() const { return current_image_; } const gfx::Size& size() const { return size_; } private: @@ -81,7 +77,7 @@ bool InitializeSwapImages(const VkSurfaceCapabilitiesKHR& surface_caps, const VkSurfaceFormatKHR& surface_format); void DestroySwapImages(); - bool BeginWriteCurrentImage(VkImage* image, + void BeginWriteCurrentImage(VkImage* image, uint32_t* image_index, VkImageLayout* layout, VkSemaphore* semaphore); @@ -106,10 +102,9 @@ std::unique_ptr<VulkanCommandBuffer> command_buffer; }; std::vector<ImageData> images_; - - // Acquired image index. - base::Optional<uint32_t> acquired_image_; + uint32_t current_image_ = 0; bool is_writing_ = false; + VkSemaphore begin_write_semaphore_ = VK_NULL_HANDLE; VkSemaphore end_write_semaphore_ = VK_NULL_HANDLE; DISALLOW_COPY_AND_ASSIGN(VulkanSwapChain);
diff --git a/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm index 4064b41a..db41bfc 100644 --- a/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm +++ b/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm
@@ -209,10 +209,13 @@ - (void)animateFullscreenWithAnimator:(FullscreenAnimator*)animator { CGFloat finalProgress = animator.finalProgress; - [animator addAnimations:^{ - [self updateForFullscreenProgress:finalProgress]; - [self.view layoutIfNeeded]; - }]; + // Using the animator doesn't work as the animation doesn't trigger a relayout + // of the constraints (see crbug.com/978462, crbug.com/950994). + [UIView animateWithDuration:animator.duration + animations:^{ + [self updateForFullscreenProgress:finalProgress]; + [self.view layoutIfNeeded]; + }]; } #pragma mark - ToolbarAnimatee
diff --git a/ios/web/js_messaging/BUILD.gn b/ios/web/js_messaging/BUILD.gn index a86c192d..5bdcdbb 100644 --- a/ios/web/js_messaging/BUILD.gn +++ b/ios/web/js_messaging/BUILD.gn
@@ -14,6 +14,7 @@ "//ios/web/public/deprecated", "//ios/web/public/js_messaging", "//ios/web/web_state:web_state_impl_header", + "//ios/web/web_view:util", "//url", ]
diff --git a/ios/web/js_messaging/web_frames_manager_impl.h b/ios/web/js_messaging/web_frames_manager_impl.h index 17f6259..a48b7bf 100644 --- a/ios/web/js_messaging/web_frames_manager_impl.h +++ b/ios/web/js_messaging/web_frames_manager_impl.h
@@ -7,6 +7,10 @@ #import "ios/web/public/js_messaging/web_frames_manager.h" +#import <WebKit/WebKit.h> + +@class CRWWKScriptMessageRouter; + namespace web { class WebFrame; @@ -40,9 +44,25 @@ WebFrame* GetMainWebFrame() override; WebFrame* GetFrameWithId(const std::string& frame_id) override; + // Use |message_router| to unregister JS message handlers for |old_web_view| + // and register handlers for |new_web_view|. Owner of this class should call + // this method whenever associated WKWebView changes. + void OnWebViewUpdated(WKWebView* old_web_view, + WKWebView* new_web_view, + CRWWKScriptMessageRouter* message_router); + private: friend class web::WebStateUserData<WebFramesManagerImpl>; + // Handles FrameBecameAvailable JS message and creates new WebFrame based on + // frame info from the message (e.g. ID, encryption key, message counter, + // etc.). + void OnFrameBecameAvailable(WKScriptMessage* message); + + // Handles FrameBecameUnavailable JS message and removes the WebFrame with ID + // from the message. + void OnFrameBecameUnavailable(WKScriptMessage* message); + // List of pointers to all web frames associated with WebState. std::map<std::string, std::unique_ptr<WebFrame>> web_frames_;
diff --git a/ios/web/js_messaging/web_frames_manager_impl.mm b/ios/web/js_messaging/web_frames_manager_impl.mm index 869d7ec1..1c4a60e 100644 --- a/ios/web/js_messaging/web_frames_manager_impl.mm +++ b/ios/web/js_messaging/web_frames_manager_impl.mm
@@ -4,29 +4,24 @@ #include "ios/web/js_messaging/web_frames_manager_impl.h" +#include "base/base64.h" +#include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" -#include "ios/web/public/js_messaging/web_frame.h" -#import "ios/web/public/web_state/web_state.h" +#include "crypto/symmetric_key.h" +#import "ios/web/js_messaging/crw_wk_script_message_router.h" +#include "ios/web/js_messaging/web_frame_impl.h" +#import "ios/web/web_state/web_state_impl.h" +#import "ios/web/web_view/wk_security_origin_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif namespace { -// Matcher for finding a WebFrame object with the given |frame_id|. -struct FrameIdMatcher { - explicit FrameIdMatcher(const std::string& frame_id) : frame_id_(frame_id) {} - - // Returns true if the receiver was initialized with the same frame id as - // |web_frame|. - bool operator()(web::WebFrame* web_frame) { - return web_frame->GetFrameId() == frame_id_; - } - - private: - // The frame id to match against. - const std::string frame_id_; -}; +// Message command sent when a frame becomes available. +NSString* const kFrameBecameAvailableMessageName = @"FrameBecameAvailable"; +// Message command sent when a frame is unloading. +NSString* const kFrameBecameUnavailableMessageName = @"FrameBecameUnavailable"; } // namespace namespace web { @@ -115,6 +110,100 @@ base::UTF8ToUTF16("__gCrWeb.message.getExistingFrames();")); } +void WebFramesManagerImpl::OnWebViewUpdated( + WKWebView* old_web_view, + WKWebView* new_web_view, + CRWWKScriptMessageRouter* message_router) { + DCHECK(old_web_view != new_web_view); + if (old_web_view) { + [message_router + removeScriptMessageHandlerForName:kFrameBecameAvailableMessageName + webView:old_web_view]; + [message_router + removeScriptMessageHandlerForName:kFrameBecameUnavailableMessageName + webView:old_web_view]; + } + + // |this| is captured inside callbacks for JS messages, so the owner of + // WebFramesManagerImpl must call OnWebViewUpdated(last_web_view, nil) when + // being destroyed, so that WebFramesManagerImpl can unregister callbacks in + // time. This guarantees that when callbacks are invoked, |this| is always + // valid. + if (new_web_view) { + [message_router + setScriptMessageHandler:^(WKScriptMessage* message) { + this->OnFrameBecameAvailable(message); + } + name:kFrameBecameAvailableMessageName + webView:new_web_view]; + [message_router + setScriptMessageHandler:^(WKScriptMessage* message) { + DCHECK(!web_state_->IsBeingDestroyed()); + this->OnFrameBecameUnavailable(message); + } + name:kFrameBecameUnavailableMessageName + webView:new_web_view]; + } +} + +void WebFramesManagerImpl::OnFrameBecameAvailable(WKScriptMessage* message) { + DCHECK(!web_state_->IsBeingDestroyed()); + // Validate all expected message components because any frame could falsify + // this message. + if (![message.body isKindOfClass:[NSDictionary class]] || + ![message.body[@"crwFrameId"] isKindOfClass:[NSString class]]) { + return; + } + + std::string frame_id = base::SysNSStringToUTF8(message.body[@"crwFrameId"]); + if (!GetFrameWithId(frame_id)) { + GURL message_frame_origin = + web::GURLOriginWithWKSecurityOrigin(message.frameInfo.securityOrigin); + + std::unique_ptr<crypto::SymmetricKey> frame_key; + if ([message.body[@"crwFrameKey"] isKindOfClass:[NSString class]] && + [message.body[@"crwFrameKey"] length] > 0) { + std::string decoded_frame_key_string; + std::string encoded_frame_key_string = + base::SysNSStringToUTF8(message.body[@"crwFrameKey"]); + base::Base64Decode(encoded_frame_key_string, &decoded_frame_key_string); + frame_key = crypto::SymmetricKey::Import( + crypto::SymmetricKey::Algorithm::AES, decoded_frame_key_string); + } + + auto new_frame = std::make_unique<web::WebFrameImpl>( + frame_id, message.frameInfo.mainFrame, message_frame_origin, + web_state_); + if (frame_key) { + new_frame->SetEncryptionKey(std::move(frame_key)); + } + + NSNumber* last_sent_message_id = + message.body[@"crwFrameLastReceivedMessageId"]; + if ([last_sent_message_id isKindOfClass:[NSNumber class]]) { + int next_message_id = std::max(0, last_sent_message_id.intValue + 1); + new_frame->SetNextMessageId(next_message_id); + } + + AddFrame(std::move(new_frame)); + static_cast<WebStateImpl*>(web_state_) + ->OnWebFrameAvailable(GetFrameWithId(frame_id)); + } +} + +void WebFramesManagerImpl::OnFrameBecameUnavailable(WKScriptMessage* message) { + DCHECK(!web_state_->IsBeingDestroyed()); + if (![message.body isKindOfClass:[NSString class]]) { + // WebController is being destroyed or message is invalid. + return; + } + std::string frame_id = base::SysNSStringToUTF8(message.body); + WebFrame* frame = GetFrameWithId(frame_id); + if (frame) { + static_cast<WebStateImpl*>(web_state_)->OnWebFrameUnavailable(frame); + RemoveFrameWithId(frame_id); + } +} WEB_STATE_USER_DATA_KEY_IMPL(WebFramesManager) } // namespace
diff --git a/ios/web/js_messaging/web_frames_manager_impl_unittest.mm b/ios/web/js_messaging/web_frames_manager_impl_unittest.mm index 6117f09..2485ba98 100644 --- a/ios/web/js_messaging/web_frames_manager_impl_unittest.mm +++ b/ios/web/js_messaging/web_frames_manager_impl_unittest.mm
@@ -4,10 +4,12 @@ #include "ios/web/js_messaging/web_frames_manager_impl.h" +#import "ios/web/js_messaging/crw_wk_script_message_router.h" #include "ios/web/js_messaging/web_frame_impl.h" #import "ios/web/public/test/fakes/test_web_state.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" +#import "third_party/ocmock/OCMock/OCMock.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -15,6 +17,16 @@ namespace { +const char kFrameId[] = "1effd8f52a067c8d3a01762d3c41dfd8"; + +// A base64 encoded sample key. +const char kFrameKey[] = "R7lsXtR74c6R9A9k691gUQ8JAd0be+w//Lntgcbjwrc="; + +// Message command sent when a frame becomes available. +NSString* const kFrameBecameAvailableMessageName = @"FrameBecameAvailable"; +// Message command sent when a frame is unloading. +NSString* const kFrameBecameUnavailableMessageName = @"FrameBecameUnavailable"; + // Returns true if |web_frame| is contained in |frames|. bool ContainsWebFrame(std::set<web::WebFrame*> frames, web::WebFrame* web_frame) { @@ -171,4 +183,95 @@ EXPECT_EQ(nullptr, frames_manager_->GetFrameWithId("invalid_id")); } +// Tests that WebFramesManagerImpl will unregister callbacks for previous +// WKWebView and register callbacks for new WKWebView. Also tests that +// WebFramesManagerImpl creates new WebFrame when receiving +// "FrameBecameAvailable" message and removes WebFrame when receiving +// "FrameBecameUnavailable" message. +TEST_F(WebFramesManagerImplTest, OnWebViewUpdated) { + // Mock WKUserContentController. + WKUserContentController* user_content_controller = + OCMClassMock([WKUserContentController class]); + + // Set up CRWWKScriptMessageRouter. + CRWWKScriptMessageRouter* router = [[CRWWKScriptMessageRouter alloc] + initWithUserContentController:user_content_controller]; + + // Mock WKWebView. + WKWebView* web_view_1 = OCMClassMock([WKWebView class]); + WKWebView* web_view_2 = OCMClassMock([WKWebView class]); + + // Mock WKSecurityOrigin. + WKSecurityOrigin* security_origin = OCMClassMock([WKSecurityOrigin class]); + OCMStub([security_origin host]).andReturn(@"www.crw.com"); + OCMStub([security_origin port]).andReturn(443); + OCMStub([security_origin protocol]).andReturn(@"https"); + + // Mock WKFrameInfo. + WKFrameInfo* frame_info = OCMClassMock([WKFrameInfo class]); + OCMStub([frame_info isMainFrame]).andReturn(YES); + OCMStub([frame_info securityOrigin]).andReturn(security_origin); + + // Mock WKScriptMessage for "FrameBecameAvailable" message. + NSDictionary* body = @{ + @"crwFrameId" : [NSString stringWithUTF8String:kFrameId], + @"crwFrameKey" : [NSString stringWithUTF8String:kFrameKey], + @"crwFrameLastReceivedMessageId" : @-1, + }; + WKScriptMessage* available_message = OCMClassMock([WKScriptMessage class]); + OCMStub([available_message body]).andReturn(body); + OCMStub([available_message frameInfo]).andReturn(frame_info); + OCMStub([available_message name]).andReturn(kFrameBecameAvailableMessageName); + OCMStub([available_message webView]).andReturn(web_view_1); + + // Mock WKScriptMessage for "FrameBecameUnavailable" message. + WKScriptMessage* unavailable_message = OCMClassMock([WKScriptMessage class]); + OCMStub([unavailable_message body]) + .andReturn([NSString stringWithUTF8String:kFrameId]); + OCMStub([unavailable_message frameInfo]).andReturn(frame_info); + OCMStub([unavailable_message name]) + .andReturn(kFrameBecameUnavailableMessageName); + OCMStub([unavailable_message webView]).andReturn(web_view_1); + + // Test begin! + + // Tell the manager to change from nil to |web_view_1|. + frames_manager_->OnWebViewUpdated(nil, web_view_1, router); + + // Send the "FrameBecameAvailable" to |router|. + [(id<WKScriptMessageHandler>)router + userContentController:user_content_controller + didReceiveScriptMessage:available_message]; + + // Check that the WebFrame for main frame is created. + ASSERT_EQ(1UL, frames_manager_->GetAllWebFrames().size()); + WebFrame* main_frame = frames_manager_->GetMainWebFrame(); + ASSERT_TRUE(main_frame); + EXPECT_EQ(kFrameId, main_frame->GetFrameId()); + EXPECT_TRUE(main_frame->IsMainFrame()); + EXPECT_EQ(GURL("https://www.crw.com"), main_frame->GetSecurityOrigin()); + + // Send the "FrameBecameUnavailable" to |router|. + [(id<WKScriptMessageHandler>)router + userContentController:user_content_controller + didReceiveScriptMessage:unavailable_message]; + + // Check that the WebFrame for main frame is removed. + ASSERT_EQ(0UL, frames_manager_->GetAllWebFrames().size()); + ASSERT_FALSE(frames_manager_->GetMainWebFrame()); + + // Tell the manager to change from |web_view_1| to |web_view_2|. + frames_manager_->OnWebViewUpdated(web_view_1, web_view_2, router); + + // Send the "FrameBecameAvailable" of |web_view_1| to |router| again. + [(id<WKScriptMessageHandler>)router + userContentController:user_content_controller + didReceiveScriptMessage:available_message]; + + // Check that WebFramesManagerImpl doesn't reply JS messages from previous + // WKWebView. + ASSERT_EQ(0UL, frames_manager_->GetAllWebFrames().size()); + ASSERT_FALSE(frames_manager_->GetMainWebFrame()); +} + } // namespace web
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 58c117c..b6db826d 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -6,7 +6,6 @@ #import <WebKit/WebKit.h> -#include "base/base64.h" #import "base/ios/block_types.h" #include "base/ios/ios_util.h" #include "base/json/string_escape.h" @@ -15,7 +14,6 @@ #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" -#include "crypto/symmetric_key.h" #import "ios/web/browsing_data/browsing_data_remover.h" #import "ios/web/browsing_data/browsing_data_remover_observer.h" #import "ios/web/common/crw_web_view_content_view.h" @@ -26,7 +24,6 @@ #include "ios/web/history_state_util.h" #import "ios/web/js_messaging/crw_js_injector.h" #import "ios/web/js_messaging/crw_wk_script_message_router.h" -#import "ios/web/js_messaging/web_frame_impl.h" #import "ios/web/js_messaging/web_frames_manager_impl.h" #import "ios/web/js_messaging/web_view_js_utils.h" #import "ios/web/navigation/crw_js_navigation_handler.h" @@ -62,7 +59,6 @@ #import "ios/web/web_state/web_state_impl.h" #import "ios/web/web_state/web_view_internal_creation_util.h" #import "ios/web/web_view/content_type_util.h" -#import "ios/web/web_view/wk_security_origin_util.h" #import "ios/web/web_view/wk_web_view_util.h" #import "net/base/mac/url_conversions.h" #include "services/metrics/public/cpp/ukm_builders.h" @@ -92,11 +88,6 @@ // URL scheme for messages sent from javascript for asynchronous processing. NSString* const kScriptMessageName = @"crwebinvoke"; -// Message command sent when a frame becomes available. -NSString* const kFrameBecameAvailableMessageName = @"FrameBecameAvailable"; -// Message command sent when a frame is unloading. -NSString* const kFrameBecameUnavailableMessageName = @"FrameBecameUnavailable"; - } // namespace @interface CRWWebController () <BrowsingDataRemoverObserver, @@ -254,10 +245,6 @@ - (void)didReceiveScriptMessage:(WKScriptMessage*)message; // Attempts to handle a script message. Returns YES on success, NO otherwise. - (BOOL)respondToWKScriptMessage:(WKScriptMessage*)scriptMessage; -// Handles frame became available message. -- (void)frameBecameAvailableWithMessage:(WKScriptMessage*)message; -// Handles frame became unavailable message. -- (void)frameBecameUnavailableWithMessage:(WKScriptMessage*)message; // Restores the state for this page from session history. - (void)restoreStateFromHistory; @@ -429,11 +416,14 @@ DCHECK_NE(_webView, webView); // Unwind the old web view. - // TODO(crbug.com/543374): Remove CRWWKScriptMessageRouter once - // crbug.com/543374 is fixed. CRWWKScriptMessageRouter* messageRouter = [self webViewConfigurationProvider].GetScriptMessageRouter(); + web::WebFramesManagerImpl::FromWebState(self.webStateImpl) + ->OnWebViewUpdated(_webView, webView, messageRouter); if (_webView) { + // TODO(crbug.com/956516): Use removeScriptMessageHandlerForName:webView: + // for |kScriptMessageName| and let CRWContextMenuController unregister its + // own callback. [messageRouter removeAllScriptMessageHandlersForWebView:_webView]; } [_webView setNavigationDelegate:nil]; @@ -442,32 +432,19 @@ [_webView removeObserver:self forKeyPath:keyPath]; } + // Set up the new web view. _webView = webView; - // Set up the new web view. - if (webView) { + if (_webView) { __weak CRWWebController* weakSelf = self; [messageRouter setScriptMessageHandler:^(WKScriptMessage* message) { [weakSelf didReceiveScriptMessage:message]; } name:kScriptMessageName - webView:webView]; - - [messageRouter - setScriptMessageHandler:^(WKScriptMessage* message) { - [weakSelf frameBecameAvailableWithMessage:message]; - } - name:kFrameBecameAvailableMessageName - webView:webView]; - [messageRouter - setScriptMessageHandler:^(WKScriptMessage* message) { - [weakSelf frameBecameUnavailableWithMessage:message]; - } - name:kFrameBecameUnavailableMessageName - webView:webView]; + webView:_webView]; } - [_jsInjector setWebView:webView]; + [_jsInjector setWebView:_webView]; [_webView setNavigationDelegate:self.navigationHandler]; [_webView setUIDelegate:self.UIHandler]; for (NSString* keyPath in self.WKWebViewObservers) { @@ -1435,72 +1412,6 @@ return NO; } -#pragma mark - Web frames management - -- (void)frameBecameAvailableWithMessage:(WKScriptMessage*)message { - // Validate all expected message components because any frame could falsify - // this message. - // TODO(crbug.com/881816): Create a WebFrame even if key is empty. - if (_isBeingDestroyed || ![message.body isKindOfClass:[NSDictionary class]] || - ![message.body[@"crwFrameId"] isKindOfClass:[NSString class]]) { - // WebController is being destroyed or the message is invalid. - return; - } - - std::string frameID = base::SysNSStringToUTF8(message.body[@"crwFrameId"]); - web::WebFramesManagerImpl* framesManager = - web::WebFramesManagerImpl::FromWebState([self webState]); - if (!framesManager->GetFrameWithId(frameID)) { - GURL messageFrameOrigin = - web::GURLOriginWithWKSecurityOrigin(message.frameInfo.securityOrigin); - - std::unique_ptr<crypto::SymmetricKey> frameKey; - if ([message.body[@"crwFrameKey"] isKindOfClass:[NSString class]] && - [message.body[@"crwFrameKey"] length] > 0) { - std::string decodedFrameKeyString; - std::string encodedFrameKeyString = - base::SysNSStringToUTF8(message.body[@"crwFrameKey"]); - base::Base64Decode(encodedFrameKeyString, &decodedFrameKeyString); - frameKey = crypto::SymmetricKey::Import( - crypto::SymmetricKey::Algorithm::AES, decodedFrameKeyString); - } - - auto newFrame = std::make_unique<web::WebFrameImpl>( - frameID, message.frameInfo.mainFrame, messageFrameOrigin, - self.webState); - if (frameKey) { - newFrame->SetEncryptionKey(std::move(frameKey)); - } - - NSNumber* lastSentMessageID = - message.body[@"crwFrameLastReceivedMessageId"]; - if ([lastSentMessageID isKindOfClass:[NSNumber class]]) { - int nextMessageID = std::max(0, lastSentMessageID.intValue + 1); - newFrame->SetNextMessageId(nextMessageID); - } - - framesManager->AddFrame(std::move(newFrame)); - self.webStateImpl->OnWebFrameAvailable( - framesManager->GetFrameWithId(frameID)); - } -} - -- (void)frameBecameUnavailableWithMessage:(WKScriptMessage*)message { - if (_isBeingDestroyed || ![message.body isKindOfClass:[NSString class]]) { - // WebController is being destroyed or message is invalid. - return; - } - std::string frameID = base::SysNSStringToUTF8(message.body); - web::WebFramesManagerImpl* framesManager = - web::WebFramesManagerImpl::FromWebState([self webState]); - - if (framesManager->GetFrameWithId(frameID)) { - self.webStateImpl->OnWebFrameUnavailable( - framesManager->GetFrameWithId(frameID)); - framesManager->RemoveFrameWithId(frameID); - } -} - #pragma mark - WebUI // Sets up WebUI for URL.
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm index 9a6eccf..c6bd44f 100644 --- a/ios/web/web_state/web_state_impl.mm +++ b/ios/web/web_state/web_state_impl.mm
@@ -113,8 +113,8 @@ } WebStateImpl::~WebStateImpl() { - [web_controller_ close]; is_being_destroyed_ = true; + [web_controller_ close]; // WebUI depends on web state so it must be destroyed first in case any WebUI // implementations depends on accessing web state during destruction.
diff --git a/media/base/cdm_promise.h b/media/base/cdm_promise.h index 13740f5..771a6f0 100644 --- a/media/base/cdm_promise.h +++ b/media/base/cdm_promise.h
@@ -47,6 +47,19 @@ KEY_STATUS_TYPE }; + // These values are reported to UMA. Never change existing values. Only add + // new values at the bottom of the list. + // TODO(xhwang): Make SystemCode an enum class and pass |system_code| as + // SystemCode everywhere. + enum SystemCode : uint32_t { + kMinValue = 1000000, // To avoid conflict with system code reported by CDM. + kOk = kMinValue, + kFailure, + kAborted, + kConnectionError, + kMaxValue = kConnectionError, + }; + CdmPromise() = default; virtual ~CdmPromise() = default; @@ -125,7 +138,7 @@ std::string message = "Unfulfilled promise rejected automatically during destruction."; DVLOG(1) << message; - reject(Exception::INVALID_STATE_ERROR, 0, message); + reject(Exception::INVALID_STATE_ERROR, SystemCode::kAborted, message); DCHECK(is_settled_); }
diff --git a/media/base/cdm_promise_adapter.cc b/media/base/cdm_promise_adapter.cc index 4491246..af1b604 100644 --- a/media/base/cdm_promise_adapter.cc +++ b/media/base/cdm_promise_adapter.cc
@@ -65,9 +65,11 @@ void CdmPromiseAdapter::Clear() { // Reject all outstanding promises. DCHECK(thread_checker_.CalledOnValidThread()); - for (auto& promise : promises_) - promise.second->reject(CdmPromise::Exception::INVALID_STATE_ERROR, 0, + for (auto& promise : promises_) { + promise.second->reject(CdmPromise::Exception::INVALID_STATE_ERROR, + CdmPromise::SystemCode::kAborted, "Operation aborted."); + } promises_.clear(); }
diff --git a/media/mojo/clients/mojo_cdm.cc b/media/mojo/clients/mojo_cdm.cc index b883ecc2..0629b83 100644 --- a/media/mojo/clients/mojo_cdm.cc +++ b/media/mojo/clients/mojo_cdm.cc
@@ -151,7 +151,8 @@ // Handle initial connection error. if (pending_init_promise_) { DCHECK(!cdm_session_tracker_.HasRemainingSessions()); - pending_init_promise_->reject(CdmPromise::Exception::INVALID_STATE_ERROR, 0, + pending_init_promise_->reject(CdmPromise::Exception::INVALID_STATE_ERROR, + CdmPromise::SystemCode::kConnectionError, "Mojo CDM creation failed."); // Dropping the promise could cause |this| to be destructed. pending_init_promise_.reset(); @@ -170,7 +171,8 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!remote_cdm_) { - promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, 0, + promise->reject(media::CdmPromise::Exception::INVALID_STATE_ERROR, + CdmPromise::SystemCode::kConnectionError, "CDM connection lost."); return; }
diff --git a/media/muxers/webm_muxer.cc b/media/muxers/webm_muxer.cc index 815b477..7d01d26 100644 --- a/media/muxers/webm_muxer.cc +++ b/media/muxers/webm_muxer.cc
@@ -124,14 +124,14 @@ } bool WebmMuxer::OnEncodedVideo(const VideoParameters& params, - std::unique_ptr<std::string> encoded_data, - std::unique_ptr<std::string> encoded_alpha, + std::string encoded_data, + std::string encoded_alpha, base::TimeTicks timestamp, bool is_key_frame) { - DVLOG(1) << __func__ << " - " << encoded_data->size() << "B"; + DVLOG(1) << __func__ << " - " << encoded_data.size() << "B"; DCHECK(thread_checker_.CalledOnValidThread()); - if (encoded_data->size() == 0u) { + if (encoded_data.size() == 0u) { DLOG(WARNING) << __func__ << ": zero size encoded frame, skipping"; // Some encoders give sporadic zero-size data, see https://crbug.com/716451. return true; @@ -160,15 +160,14 @@ // Any saved encoded video frames must have been dumped in OnEncodedAudio(); DCHECK(encoded_frames_queue_.empty()); - return AddFrame(std::move(encoded_data), std::move(encoded_alpha), - video_track_index_, timestamp - first_frame_timestamp_video_, - is_key_frame); + return AddFrame(encoded_data, encoded_alpha, video_track_index_, + timestamp - first_frame_timestamp_video_, is_key_frame); } bool WebmMuxer::OnEncodedAudio(const media::AudioParameters& params, - std::unique_ptr<std::string> encoded_data, + std::string encoded_data, base::TimeTicks timestamp) { - DVLOG(2) << __func__ << " - " << encoded_data->size() << "B"; + DVLOG(2) << __func__ << " - " << encoded_data.size() << "B"; DCHECK(thread_checker_.CalledOnValidThread()); if (!audio_track_index_) { @@ -187,19 +186,15 @@ // Dump all saved encoded video frames if any. while (!encoded_frames_queue_.empty()) { const bool res = AddFrame( - std::make_unique<std::string>(*encoded_frames_queue_.front()->data), - encoded_frames_queue_.front()->alpha_data - ? std::make_unique<std::string>( - *encoded_frames_queue_.front()->alpha_data) - : nullptr, - video_track_index_, + encoded_frames_queue_.front()->data, + encoded_frames_queue_.front()->alpha_data, video_track_index_, encoded_frames_queue_.front()->timestamp - first_frame_timestamp_video_, encoded_frames_queue_.front()->is_keyframe); if (!res) return false; encoded_frames_queue_.pop_front(); } - return AddFrame(std::move(encoded_data), nullptr, audio_track_index_, + return AddFrame(encoded_data, std::string(), audio_track_index_, timestamp - first_frame_timestamp_audio_, true /* is_key_frame -- always true for audio */); } @@ -330,8 +325,8 @@ << "Can't go back in a live WebM stream."; } -bool WebmMuxer::AddFrame(std::unique_ptr<std::string> encoded_data, - std::unique_ptr<std::string> encoded_alpha, +bool WebmMuxer::AddFrame(const std::string& encoded_data, + const std::string& encoded_alpha, uint8_t track_index, base::TimeDelta timestamp, bool is_key_frame) { @@ -348,32 +343,31 @@ return false; } - DCHECK(encoded_data->data()); - if (!encoded_alpha || encoded_alpha->empty()) { + DCHECK(encoded_data.data()); + if (encoded_alpha.empty()) { return segment_.AddFrame( - reinterpret_cast<const uint8_t*>(encoded_data->data()), - encoded_data->size(), track_index, + reinterpret_cast<const uint8_t*>(encoded_data.data()), + encoded_data.size(), track_index, most_recent_timestamp_.InMicroseconds() * base::Time::kNanosecondsPerMicrosecond, is_key_frame); } - DCHECK(encoded_alpha->data()); + DCHECK(encoded_alpha.data()); return segment_.AddFrameWithAdditional( - reinterpret_cast<const uint8_t*>(encoded_data->data()), - encoded_data->size(), - reinterpret_cast<const uint8_t*>(encoded_alpha->data()), - encoded_alpha->size(), 1 /* add_id */, track_index, + reinterpret_cast<const uint8_t*>(encoded_data.data()), + encoded_data.size(), + reinterpret_cast<const uint8_t*>(encoded_alpha.data()), + encoded_alpha.size(), 1 /* add_id */, track_index, most_recent_timestamp_.InMicroseconds() * base::Time::kNanosecondsPerMicrosecond, is_key_frame); } -WebmMuxer::EncodedVideoFrame::EncodedVideoFrame( - std::unique_ptr<std::string> data, - std::unique_ptr<std::string> alpha_data, - base::TimeTicks timestamp, - bool is_keyframe) +WebmMuxer::EncodedVideoFrame::EncodedVideoFrame(std::string data, + std::string alpha_data, + base::TimeTicks timestamp, + bool is_keyframe) : data(std::move(data)), alpha_data(std::move(alpha_data)), timestamp(timestamp),
diff --git a/media/muxers/webm_muxer.h b/media/muxers/webm_muxer.h index 4cfcc7a..e2f9618 100644 --- a/media/muxers/webm_muxer.h +++ b/media/muxers/webm_muxer.h
@@ -72,12 +72,12 @@ // |encoded_alpha| represents the encode output of alpha channel when // available, can be nullptr otherwise. bool OnEncodedVideo(const VideoParameters& params, - std::unique_ptr<std::string> encoded_data, - std::unique_ptr<std::string> encoded_alpha, + std::string encoded_data, + std::string encoded_alpha, base::TimeTicks timestamp, bool is_key_frame); bool OnEncodedAudio(const media::AudioParameters& params, - std::unique_ptr<std::string> encoded_data, + std::string encoded_data, base::TimeTicks timestamp); void Pause(); @@ -105,8 +105,8 @@ mkvmuxer::int64 position) override; // Helper to simplify saving frames. Returns true on success. - bool AddFrame(std::unique_ptr<std::string> encoded_data, - std::unique_ptr<std::string> encoded_alpha_data, + bool AddFrame(const std::string& encoded_data, + const std::string& encoded_alpha_data, uint8_t track_index, base::TimeDelta timestamp, bool is_key_frame); @@ -151,14 +151,14 @@ // Hold on to all encoded video frames to dump them with and when audio is // received, if expected, since WebM headers can only be written once. struct EncodedVideoFrame { - EncodedVideoFrame(std::unique_ptr<std::string> data, - std::unique_ptr<std::string> alpha_data, + EncodedVideoFrame(std::string data, + std::string alpha_data, base::TimeTicks timestamp, bool is_keyframe); ~EncodedVideoFrame(); - std::unique_ptr<std::string> data; - std::unique_ptr<std::string> alpha_data; + std::string data; + std::string alpha_data; base::TimeTicks timestamp; bool is_keyframe;
diff --git a/media/muxers/webm_muxer_fuzzertest.cc b/media/muxers/webm_muxer_fuzzertest.cc index eff598f..d91472a8 100644 --- a/media/muxers/webm_muxer_fuzzertest.cc +++ b/media/muxers/webm_muxer_fuzzertest.cc
@@ -71,11 +71,9 @@ const auto video_frame = VideoFrame::CreateBlackFrame(visible_rect); const auto is_key_frame = rng() % 2; const auto has_alpha_frame = rng() % 4; - muxer.OnEncodedVideo( - WebmMuxer::VideoParameters(video_frame), - std::make_unique<std::string>(str), - has_alpha_frame ? std::make_unique<std::string>(str) : nullptr, - base::TimeTicks(), is_key_frame); + muxer.OnEncodedVideo(WebmMuxer::VideoParameters(video_frame), str, + has_alpha_frame ? str : std::string(), + base::TimeTicks(), is_key_frame); base::RunLoop run_loop; run_loop.RunUntilIdle(); } @@ -89,8 +87,7 @@ const AudioParameters params( media::AudioParameters::AUDIO_PCM_LOW_LATENCY, layout, sample_rate, 60 * sample_rate); - muxer.OnEncodedAudio(params, std::make_unique<std::string>(str), - base::TimeTicks()); + muxer.OnEncodedAudio(params, str, base::TimeTicks()); base::RunLoop run_loop; run_loop.RunUntilIdle(); }
diff --git a/media/muxers/webm_muxer_unittest.cc b/media/muxers/webm_muxer_unittest.cc index f819ecd48..7bf37ee 100644 --- a/media/muxers/webm_muxer_unittest.cc +++ b/media/muxers/webm_muxer_unittest.cc
@@ -115,8 +115,7 @@ .WillRepeatedly( WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); EXPECT_TRUE(webm_muxer_.OnEncodedVideo( - WebmMuxer::VideoParameters(video_frame), - base::WrapUnique(new std::string(encoded_data)), nullptr, + WebmMuxer::VideoParameters(video_frame), encoded_data, std::string(), base::TimeTicks::Now(), false /* keyframe */)); // First time around WriteCallback() is pinged a number of times to write the @@ -131,9 +130,9 @@ .Times(AtLeast(1)) .WillRepeatedly( WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); - EXPECT_TRUE(webm_muxer_.OnEncodedVideo( - video_frame, base::WrapUnique(new std::string(encoded_data)), nullptr, - base::TimeTicks::Now(), false /* keyframe */)); + EXPECT_TRUE(webm_muxer_.OnEncodedVideo(video_frame, encoded_data, + std::string(), base::TimeTicks::Now(), + false /* keyframe */)); // The second time around the callbacks should include a SimpleBlock header, // namely the track index, a timestamp and a flags byte, for a total of 6B. @@ -147,8 +146,7 @@ // Force an error in libwebm and expect OnEncodedVideo to fail. webm_muxer_.ForceOneLibWebmErrorForTesting(); EXPECT_FALSE(webm_muxer_.OnEncodedVideo( - WebmMuxer::VideoParameters(video_frame), - std::make_unique<std::string>(encoded_data), nullptr, + WebmMuxer::VideoParameters(video_frame), encoded_data, std::string(), base::TimeTicks::Now(), true /* keyframe */)); } @@ -170,9 +168,7 @@ .WillRepeatedly( WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); EXPECT_TRUE(webm_muxer_.OnEncodedVideo( - WebmMuxer::VideoParameters(video_frame), - base::WrapUnique(new std::string(encoded_data)), - base::WrapUnique(new std::string(alpha_encoded_data)), + WebmMuxer::VideoParameters(video_frame), encoded_data, alpha_encoded_data, base::TimeTicks::Now(), true /* keyframe */)); EXPECT_EQ(GetWebmMuxerPosition(), accumulated_position_); @@ -184,10 +180,9 @@ .Times(AtLeast(1)) .WillRepeatedly( WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); - EXPECT_TRUE(webm_muxer_.OnEncodedVideo( - video_frame, base::WrapUnique(new std::string(encoded_data)), - base::WrapUnique(new std::string(alpha_encoded_data)), - base::TimeTicks::Now(), false /* keyframe */)); + EXPECT_TRUE( + webm_muxer_.OnEncodedVideo(video_frame, encoded_data, alpha_encoded_data, + base::TimeTicks::Now(), false /* keyframe */)); EXPECT_EQ(GetWebmMuxerPosition(), accumulated_position_); // Alpha introduces additional elements to be written, see @@ -203,8 +198,7 @@ // Force an error in libwebm and expect OnEncodedVideo to fail. webm_muxer_.ForceOneLibWebmErrorForTesting(); EXPECT_FALSE(webm_muxer_.OnEncodedVideo( - WebmMuxer::VideoParameters(video_frame), - std::make_unique<std::string>(encoded_data), nullptr, + WebmMuxer::VideoParameters(video_frame), encoded_data, std::string(), base::TimeTicks::Now(), true /* keyframe */)); } @@ -224,9 +218,8 @@ .Times(AtLeast(1)) .WillRepeatedly( WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); - EXPECT_TRUE(webm_muxer_.OnEncodedAudio( - audio_params, std::make_unique<std::string>(encoded_data), - base::TimeTicks::Now())); + EXPECT_TRUE(webm_muxer_.OnEncodedAudio(audio_params, encoded_data, + base::TimeTicks::Now())); // First time around WriteCallback() is pinged a number of times to write the // Matroska header, but at the end it dumps |encoded_data|. @@ -240,9 +233,8 @@ .Times(AtLeast(1)) .WillRepeatedly( WithArgs<0>(Invoke(this, &WebmMuxerTest::SaveEncodedDataLen))); - EXPECT_TRUE(webm_muxer_.OnEncodedAudio( - audio_params, std::make_unique<std::string>(encoded_data), - base::TimeTicks::Now())); + EXPECT_TRUE(webm_muxer_.OnEncodedAudio(audio_params, encoded_data, + base::TimeTicks::Now())); // The second time around the callbacks should include a SimpleBlock header, // namely the track index, a timestamp and a flags byte, for a total of 6B. @@ -255,9 +247,8 @@ // Force an error in libwebm and expect OnEncodedAudio to fail. webm_muxer_.ForceOneLibWebmErrorForTesting(); - EXPECT_FALSE(webm_muxer_.OnEncodedAudio( - audio_params, std::make_unique<std::string>(encoded_data), - base::TimeTicks::Now())); + EXPECT_FALSE(webm_muxer_.OnEncodedAudio(audio_params, encoded_data, + base::TimeTicks::Now())); } // This test verifies that when video data comes before audio data, we save the @@ -273,15 +264,13 @@ VideoFrame::CreateBlackFrame(frame_size); const std::string encoded_video("thisisanencodedvideopacket"); EXPECT_TRUE(webm_muxer_.OnEncodedVideo( - WebmMuxer::VideoParameters(video_frame), - base::WrapUnique(new std::string(encoded_video)), nullptr, + WebmMuxer::VideoParameters(video_frame), encoded_video, std::string(), base::TimeTicks::Now(), true /* keyframe */)); // A few encoded non key frames. const int kNumNonKeyFrames = 2; for (int i = 0; i < kNumNonKeyFrames; ++i) { EXPECT_TRUE(webm_muxer_.OnEncodedVideo( - WebmMuxer::VideoParameters(video_frame), - base::WrapUnique(new std::string(encoded_video)), nullptr, + WebmMuxer::VideoParameters(video_frame), encoded_video, std::string(), base::TimeTicks::Now(), false /* keyframe */)); } @@ -294,9 +283,8 @@ // Force one libwebm error and verify OnEncodedAudio() fails. webm_muxer_.ForceOneLibWebmErrorForTesting(); - EXPECT_FALSE(webm_muxer_.OnEncodedAudio( - audio_params, base::WrapUnique(new std::string(encoded_audio)), - base::TimeTicks::Now())); + EXPECT_FALSE(webm_muxer_.OnEncodedAudio(audio_params, encoded_audio, + base::TimeTicks::Now())); // We should get the queued encoded video frames, then an encoded audio frame. Sequence s; @@ -308,9 +296,8 @@ EXPECT_CALL(*this, WriteCallback( AllOf(Not(Eq(encoded_video)), Not(Eq(encoded_audio))))) .Times(AnyNumber()); - EXPECT_TRUE(webm_muxer_.OnEncodedAudio( - audio_params, base::WrapUnique(new std::string(encoded_audio)), - base::TimeTicks::Now())); + EXPECT_TRUE(webm_muxer_.OnEncodedAudio(audio_params, encoded_audio, + base::TimeTicks::Now())); } const TestParams kTestCases[] = {
diff --git a/media/test/data/test-25fps.h264.md5 b/media/test/data/test-25fps.h264.md5 index 4abf0a7..98f5f97 100644 --- a/media/test/data/test-25fps.h264.md5 +++ b/media/test/data/test-25fps.h264.md5
@@ -18,5 +18,7 @@ b55cda7d10c37104d8c49d27c2699e40 # ARM - MediaTek af21b8aa5ea63c4e88f0472ee948d01a +# ARM - Cheza +e0ae5fbb0ef06922ae13b84e001f263c # AMD - Stoney Ridge 7ad287d048d6bdee63fbe37a3cd2c760
diff --git a/media/test/data/test-25fps.vp8.md5 b/media/test/data/test-25fps.vp8.md5 index c8dcdafa..6766ae0 100644 --- a/media/test/data/test-25fps.vp8.md5 +++ b/media/test/data/test-25fps.vp8.md5
@@ -4,6 +4,8 @@ cd355b553ce7660283c52675232e9227 # ARM - MediaTek 5acb8209d79c02ed9bc12048e07908e4 +# ARM - Cheza +d2e9b0e9bb703397f5cf896b4a19b041 # Intel - VA_FILTER_SCALING_DEFAULT 66f40a833b8b23dc52bbdfc0ef0e268f # Intel - go2001
diff --git a/media/test/data/test-25fps.vp9.md5 b/media/test/data/test-25fps.vp9.md5 index 02faefd..90280e9 100644 --- a/media/test/data/test-25fps.vp9.md5 +++ b/media/test/data/test-25fps.vp9.md5
@@ -4,6 +4,8 @@ 4db6e435d694180354a6d763afb27894 # ARM - RK3399 82647609e45a19f8e22fd1880a9edf3d +# ARM - Cheza +c2fcc7273c4fc882925b1d49ecf606eb # Intel - VA_FILTER_SCALING_DEFAULT 3533e744155fa94830151df0c15b8459 # Intel - VA decode to NV12, EGLImage CSC
diff --git a/mojo/public/cpp/bindings/remote_set.h b/mojo/public/cpp/bindings/remote_set.h index 4a09721..60091498 100644 --- a/mojo/public/cpp/bindings/remote_set.h +++ b/mojo/public/cpp/bindings/remote_set.h
@@ -118,12 +118,21 @@ disconnect_handler_ = std::move(handler); } + void Clear() { storage_.clear(); } + bool empty() const { return storage_.empty(); } Iterator begin() { return Iterator(storage_.begin()); } Iterator begin() const { return Iterator(storage_.begin()); } Iterator end() { return Iterator(storage_.end()); } Iterator end() const { return Iterator(storage_.end()); } + void FlushForTesting() { + for (auto& it : storage_) { + if (it.second) + it.second.FlushForTesting(); + } + } + private: RemoteSetElementId GenerateNextElementId() { return RemoteSetElementId::FromUnsafeValue(next_element_id_++);
diff --git a/net/quic/quic_chromium_client_session.h b/net/quic/quic_chromium_client_session.h index f944038..7f6b919 100644 --- a/net/quic/quic_chromium_client_session.h +++ b/net/quic/quic_chromium_client_session.h
@@ -562,6 +562,8 @@ return session_key_.server_id(); } + const QuicSessionKey& quic_session_key() const { return session_key_; } + // Attempts to migrate session when |writer| encounters a write error. // If |writer| is no longer actively used, abort migration. void MigrateSessionOnWriteError(int error_code,
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index cebd917..d118d1dd 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc
@@ -353,6 +353,7 @@ void OnResolveHostComplete(int rv); void OnConnectComplete(int rv); + void OnSessionClosed(QuicChromiumClientSession* session); const QuicSessionAliasKey& key() const { return key_; } @@ -595,6 +596,20 @@ return rv; } +void QuicStreamFactory::Job::OnSessionClosed( + QuicChromiumClientSession* session) { + // When dns racing experiment is on, the job needs to know that the stale + // session is closed so that it will start the fresh session without matching + // dns results. + if (io_state_ == STATE_HOST_VALIDATION && session_ == session) { + DCHECK(race_stale_dns_on_connection_); + DCHECK(fresh_resolve_host_request_); + resolve_host_request_ = std::move(fresh_resolve_host_request_); + session_ = nullptr; + io_state_ = STATE_RESOLVE_HOST_COMPLETE; + } +} + void QuicStreamFactory::Job::OnResolveHostComplete(int rv) { DCHECK(!host_resolution_finished_); @@ -1508,6 +1523,12 @@ void QuicStreamFactory::OnSessionClosed(QuicChromiumClientSession* session) { DCHECK_EQ(0u, session->GetNumActiveStreams()); OnSessionGoingAway(session); + + for (const auto& iter : active_jobs_) { + if (iter.first == session->quic_session_key()) { + iter.second->OnSessionClosed(session); + } + } delete session; all_sessions_.erase(session); }
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc index e9aa621b..1245878 100644 --- a/net/quic/quic_stream_factory_test.cc +++ b/net/quic/quic_stream_factory_test.cc
@@ -10954,6 +10954,151 @@ EXPECT_TRUE(quic_data.AllWriteDataConsumed()); } +// With stale dns and migration before handshake experiment on, migration failed +// after handshake confirmed, and then fresh resolve returns. +TEST_P(QuicStreamFactoryTest, StaleNetworkFailedAfterHandshake) { + test_params_.quic_race_stale_dns_on_connection = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + + InitializeConnectionMigrationV2Test( + {kDefaultNetworkForTests, kNewNetworkForTests}); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in resolver for asynchronous return. + host_resolver_->set_ondemand_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kNonCachedIPAddress, ""); + + // Set up the same address in the stale resolver cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->Invalidate(); + + MockQuicData quic_data(version_); + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + // Socket for the new connection. + client_maker_.Reset(); + MockQuicData quic_data2(version_); + quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data2.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), NetworkIsolationKey(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Check that the racing job is running. + EXPECT_TRUE(HasLiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // By disconnecting the network, the stale session will be killed. + scoped_mock_network_change_notifier_->mock_network_change_notifier() + ->NotifyNetworkDisconnected(kDefaultNetworkForTests); + + host_resolver_->ResolveAllPending(); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + + EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); + EXPECT_TRUE(quic_data2.AllReadDataConsumed()); + EXPECT_TRUE(quic_data2.AllWriteDataConsumed()); +} + +// With stale dns experiment on, the stale session is killed while waiting for +// handshake +TEST_P(QuicStreamFactoryTest, StaleNetworkFailedBeforeHandshake) { + test_params_.quic_race_stale_dns_on_connection = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + InitializeConnectionMigrationV2Test( + {kDefaultNetworkForTests, kNewNetworkForTests}); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in resolver for asynchronous return. + host_resolver_->set_ondemand_mode(true); + factory_->set_require_confirmation(true); + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::ZERO_RTT); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kNonCachedIPAddress, ""); + + // Set up a different address in the stale resolvercache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->Invalidate(); + + MockQuicData quic_data(version_); + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + client_maker_.Reset(); + MockQuicData quic_data2(version_); + quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data2.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), NetworkIsolationKey(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Check that the racing job is running. + EXPECT_TRUE(HasLiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // By disconnecting the network, the stale session will be killed. + scoped_mock_network_change_notifier_->mock_network_change_notifier() + ->NotifyNetworkDisconnected(kDefaultNetworkForTests); + + host_resolver_->ResolveAllPending(); + base::RunLoop().RunUntilIdle(); + // Make sure the fresh session is established. + crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( + quic::QuicSession::HANDSHAKE_CONFIRMED); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); + EXPECT_TRUE(quic_data2.AllReadDataConsumed()); + EXPECT_TRUE(quic_data2.AllWriteDataConsumed()); +} + TEST_P(QuicStreamFactoryTest, ConfigInitialRttForHandshake) { int kInitialRtt = 400; test_params_.quic_initial_rtt_for_handshake_milliseconds = kInitialRtt;
diff --git a/remoting/client/chromoting_client.cc b/remoting/client/chromoting_client.cc index 3088f00..df19de4 100644 --- a/remoting/client/chromoting_client.cc +++ b/remoting/client/chromoting_client.cc
@@ -252,7 +252,7 @@ VLOG(1) << "Signaling connection closed."; mouse_input_scaler_.set_input_stub(nullptr); connection_.reset(); - user_interface_->OnConnectionState(protocol::ConnectionToHost::CLOSED, + user_interface_->OnConnectionState(protocol::ConnectionToHost::FAILED, protocol::SIGNALING_ERROR); } }
diff --git a/services/media_session/media_controller.cc b/services/media_session/media_controller.cc index 5f267ba..2abadae3 100644 --- a/services/media_session/media_controller.cc +++ b/services/media_session/media_controller.cc
@@ -258,8 +258,8 @@ }); // Add |this| as an observer for |session|. - mojom::MediaSessionObserverPtr observer; - session_binding_.Bind(mojo::MakeRequest(&observer)); + mojo::PendingRemote<mojom::MediaSessionObserver> observer; + session_binding_.Bind(observer.InitWithNewPipeAndPassReceiver()); session->ipc()->AddObserver(std::move(observer)); }
diff --git a/services/media_session/public/cpp/test/mock_media_session.cc b/services/media_session/public/cpp/test/mock_media_session.cc index 7d774d6a..b601924 100644 --- a/services/media_session/public/cpp/test/mock_media_session.cc +++ b/services/media_session/public/cpp/test/mock_media_session.cc
@@ -15,8 +15,8 @@ MockMediaSessionMojoObserver::MockMediaSessionMojoObserver( mojom::MediaSession& media_session) : binding_(this) { - mojom::MediaSessionObserverPtr observer; - binding_.Bind(mojo::MakeRequest(&observer)); + mojo::PendingRemote<mojom::MediaSessionObserver> observer; + binding_.Bind(observer.InitWithNewPipeAndPassReceiver()); media_session.AddObserver(std::move(observer)); } @@ -184,17 +184,19 @@ std::move(callback).Run(GetMediaSessionInfoSync()); } -void MockMediaSession::AddObserver(mojom::MediaSessionObserverPtr observer) { +void MockMediaSession::AddObserver( + mojo::PendingRemote<mojom::MediaSessionObserver> observer) { ++add_observer_count_; + mojo::Remote<mojom::MediaSessionObserver> o(std::move(observer)); - observer->MediaSessionInfoChanged(GetMediaSessionInfoSync()); + o->MediaSessionInfoChanged(GetMediaSessionInfoSync()); std::vector<mojom::MediaSessionAction> actions(actions_.begin(), actions_.end()); - observer->MediaSessionActionsChanged(actions); - observer->MediaSessionImagesChanged(images_); + o->MediaSessionActionsChanged(actions); + o->MediaSessionImagesChanged(images_); - observers_.AddPtr(std::move(observer)); + observers_.Add(std::move(o)); } void MockMediaSession::GetDebugInfo(GetDebugInfoCallback callback) { @@ -326,26 +328,26 @@ void MockMediaSession::SimulateMetadataChanged( const base::Optional<MediaMetadata>& metadata) { - observers_.ForAllPtrs([&metadata](mojom::MediaSessionObserver* observer) { - observer->MediaSessionMetadataChanged(metadata); - }); + for (auto& o : observers_) { + o->MediaSessionMetadataChanged(metadata); + } } void MockMediaSession::ClearAllImages() { images_.clear(); - observers_.ForAllPtrs([this](mojom::MediaSessionObserver* observer) { - observer->MediaSessionImagesChanged(this->images_); - }); + for (auto& o : observers_) { + o->MediaSessionImagesChanged(this->images_); + } } void MockMediaSession::SetImagesOfType(mojom::MediaSessionImageType type, const std::vector<MediaImage>& images) { images_.insert_or_assign(type, images); - observers_.ForAllPtrs([this](mojom::MediaSessionObserver* observer) { - observer->MediaSessionImagesChanged(this->images_); - }); + for (auto& o : observers_) { + o->MediaSessionImagesChanged(this->images_); + } } void MockMediaSession::EnableAction(mojom::MediaSessionAction action) { @@ -375,9 +377,9 @@ if (afr_client_.is_bound()) afr_client_->MediaSessionInfoChanged(session_info.Clone()); - observers_.ForAllPtrs([&session_info](mojom::MediaSessionObserver* observer) { - observer->MediaSessionInfoChanged(session_info.Clone()); - }); + for (auto& o : observers_) { + o->MediaSessionInfoChanged(session_info.Clone()); + } } mojom::MediaSessionInfoPtr MockMediaSession::GetMediaSessionInfoSync() const { @@ -401,9 +403,9 @@ std::vector<mojom::MediaSessionAction> actions(actions_.begin(), actions_.end()); - observers_.ForAllPtrs([&actions](mojom::MediaSessionObserver* observer) { - observer->MediaSessionActionsChanged(actions); - }); + for (auto& o : observers_) { + o->MediaSessionActionsChanged(actions); + } } void MockMediaSession::RequestAudioFocusFromClient(
diff --git a/services/media_session/public/cpp/test/mock_media_session.h b/services/media_session/public/cpp/test/mock_media_session.h index e8a0b0b2..89cce53 100644 --- a/services/media_session/public/cpp/test/mock_media_session.h +++ b/services/media_session/public/cpp/test/mock_media_session.h
@@ -16,6 +16,7 @@ #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h" +#include "mojo/public/cpp/bindings/remote_set.h" #include "services/media_session/public/cpp/media_metadata.h" #include "services/media_session/public/mojom/audio_focus.mojom.h" #include "services/media_session/public/mojom/media_controller.mojom.h" @@ -114,7 +115,8 @@ void StartDucking() override; void StopDucking() override; void GetMediaSessionInfo(GetMediaSessionInfoCallback callback) override; - void AddObserver(mojom::MediaSessionObserverPtr observer) override; + void AddObserver( + mojo::PendingRemote<mojom::MediaSessionObserver> observer) override; void GetDebugInfo(GetDebugInfoCallback callback) override; void PreviousTrack() override; void NextTrack() override; @@ -197,7 +199,7 @@ mojo::BindingSet<mojom::MediaSession> bindings_; - mojo::InterfacePtrSet<mojom::MediaSessionObserver> observers_; + mojo::RemoteSet<mojom::MediaSessionObserver> observers_; DISALLOW_COPY_AND_ASSIGN(MockMediaSession); };
diff --git a/services/media_session/public/mojom/media_session.mojom b/services/media_session/public/mojom/media_session.mojom index fb0c2d6..937963b 100644 --- a/services/media_session/public/mojom/media_session.mojom +++ b/services/media_session/public/mojom/media_session.mojom
@@ -175,7 +175,7 @@ // |type| represents the origin of the request. Resume@5(SuspendType suspend_type); - AddObserver@6(MediaSessionObserver observer); + AddObserver@6(pending_remote<MediaSessionObserver> observer); // Skip to the previous track. If there is no previous track then this will // be a no-op.
diff --git a/services/network/cross_origin_read_blocking.cc b/services/network/cross_origin_read_blocking.cc index 117e6558..ab6c449 100644 --- a/services/network/cross_origin_read_blocking.cc +++ b/services/network/cross_origin_read_blocking.cc
@@ -693,12 +693,6 @@ if (!IsBlockableScheme(target_origin.GetURL())) return kAllow; - // Allow requests from file:// URLs for now. - // TODO(creis): Limit this to when the allow_universal_access_from_file_urls - // preference is set. See https://crbug.com/789781. - if (initiator.scheme() == url::kFileScheme) - return kAllow; - // Allow the response through if this is a CORS request and the response has // valid CORS headers. switch (request_mode) {
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 59306bf..d61991d8 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -1266,19 +1266,25 @@ } void NetworkContext::CreateWebSocket( - mojom::WebSocketRequest request, + const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + std::vector<mojom::HttpHeaderPtr> additional_headers, int32_t process_id, int32_t render_frame_id, const url::Origin& origin, uint32_t options, + mojom::WebSocketHandshakeClientPtr handshake_client, + mojom::WebSocketClientPtr client, mojom::AuthenticationHandlerPtr auth_handler, mojom::TrustedHeaderClientPtr header_client) { #if !defined(OS_IOS) if (!websocket_factory_) websocket_factory_ = std::make_unique<WebSocketFactory>(this); websocket_factory_->CreateWebSocket( - std::move(request), std::move(auth_handler), std::move(header_client), - process_id, render_frame_id, origin, options); + url, requested_protocols, site_for_cookies, std::move(additional_headers), + process_id, render_frame_id, origin, options, std::move(handshake_client), + std::move(client), std::move(auth_handler), std::move(header_client)); #endif // !defined(OS_IOS) }
diff --git a/services/network/network_context.h b/services/network/network_context.h index 704a2401..8b45ddce 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -271,11 +271,16 @@ mojom::ProxyLookupClientPtr proxy_lookup_client) override; void ForceReloadProxyConfig(ForceReloadProxyConfigCallback callback) override; void ClearBadProxiesCache(ClearBadProxiesCacheCallback callback) override; - void CreateWebSocket(mojom::WebSocketRequest request, + void CreateWebSocket(const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + std::vector<mojom::HttpHeaderPtr> additional_headers, int32_t process_id, int32_t render_frame_id, const url::Origin& origin, uint32_t options, + mojom::WebSocketHandshakeClientPtr handshake_client, + mojom::WebSocketClientPtr client, mojom::AuthenticationHandlerPtr auth_handler, mojom::TrustedHeaderClientPtr header_client) override; void CreateNetLogExporter(mojom::NetLogExporterRequest request) override;
diff --git a/services/network/public/cpp/data_element.h b/services/network/public/cpp/data_element.h index bad163b..4ed8762 100644 --- a/services/network/public/cpp/data_element.h +++ b/services/network/public/cpp/data_element.h
@@ -27,6 +27,12 @@ #include "services/network/public/mojom/url_loader.mojom-shared.h" #include "url/gurl.h" +namespace blink { +namespace mojom { +class FetchAPIDataElementDataView; +} // namespace mojom +} // namespace blink + namespace network { // Represents part of an upload body. This could be either one of bytes, file or @@ -179,6 +185,8 @@ friend void PrintTo(const DataElement& x, ::std::ostream* os); friend struct mojo::StructTraits<network::mojom::DataElementDataView, network::DataElement>; + friend struct mojo::StructTraits<blink::mojom::FetchAPIDataElementDataView, + network::DataElement>; mojom::DataElementType type_; // For TYPE_BYTES. std::vector<uint8_t> buf_;
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index d41870d7..52ed232f 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -827,20 +827,35 @@ // Clears the list of bad proxy servers that has been cached. ClearBadProxiesCache() => (); - // Creates a WebSocket connection. - // |options| may be a combination of the kWebSocketOption* flags. + // Creates a WebSocket connection to |url|. |requested_protocols| is a + // list of tokens identifying sub-protocols the renderer would like to use, + // as described in RFC6455 "Subprotocols Using the WebSocket Protocol". + // |additional_headers| are miscellaneous HTTP headers to be added to the + // request. Headers semantically relevant to the WebSocket handshake such + // as "sec-websocket-protocol" and "origin" are handled separately, (e.g., + // "sec-websocket-protocol" is constructed from |requested_protocols| in + // this message). |site_for_cookies| represents the first-party origin for + // the request. |options| may be a combination of the kWebSocketOption* flags. + // The connection will be shut down when |handshake_client| gets disconnected + // during the handshake phase, or |connection_client| gets disconnected. // If |header_client| is set, requests with the kURLLoadOptionUseHeaderClient // option will callback to the |header_client|, allowing the Cookie/Referrer // request headers and Cookie response headers to be modified. This has a // performance impact because of the extra process hops, so use should be // minimized. - CreateWebSocket(WebSocket& request, - int32 process_id, - int32 render_frame_id, - url.mojom.Origin origin, - uint32 options, - AuthenticationHandler? auth_handler, - TrustedHeaderClient? header_client); + CreateWebSocket( + url.mojom.Url url, + array<string> requested_protocols, + url.mojom.Url site_for_cookies, + array<HttpHeader> additional_headers, + int32 process_id, + int32 render_frame_id, + url.mojom.Origin origin, + uint32 options, + WebSocketHandshakeClient handshake_client, + WebSocketClient connection_client, + AuthenticationHandler? auth_handler, + TrustedHeaderClient? header_client); // Create a NetLogExporter, which helps export NetLog to an existing file. // Note that the log is generally global, including all NetworkContexts
diff --git a/services/network/public/mojom/websocket.mojom b/services/network/public/mojom/websocket.mojom index 6dd2579..651d27e 100644 --- a/services/network/public/mojom/websocket.mojom +++ b/services/network/public/mojom/websocket.mojom
@@ -67,7 +67,8 @@ // |receive_quota_threshold| is the value that the renderer calls // AddReceiveFlowControlQuota() to the browser per receiving this value // so that the browser can continue sending remaining data to the renderer. - OnConnectionEstablished(string selected_protocol, + OnConnectionEstablished(WebSocket socket, + string selected_protocol, string extensions, uint64 receive_quota_threshold); }; @@ -120,21 +121,6 @@ // service side: const uint32 kInsufficientResources = 1; - // Open new WebSocket connection to |socket_url|. |requested_protocols| is a - // list of tokens identifying sub-protocols the renderer would like to use, - // as described in RFC6455 "Subprotocols Using the WebSocket Protocol". - // |additional_headers| are miscellaneous HTTP headers to be added to the - // request. Headers semantically relevant to the WebSocket handshake such - // as "sec-websocket-protocol" and "origin" are handled separately, (e.g., - // "sec-websocket-protocol" is constructed from |requested_protocols| in - // this message). - AddChannelRequest(url.mojom.Url url, - array<string> requested_protocols, - url.mojom.Url first_party_for_cookies, - array<HttpHeader> additional_headers, - WebSocketHandshakeClient handshake_client, - WebSocketClient client); - // Send a non-control frame to the remote server. // - |fin| indicates that this frame is the last in the current message. // - |type| is the type of the message. On the first frame of a message, it
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h index 768a21c..b831ca06 100644 --- a/services/network/test/test_network_context.h +++ b/services/network/test/test_network_context.h
@@ -136,11 +136,16 @@ CreateTCPBoundSocketCallback callback) override {} void CreateProxyResolvingSocketFactory( mojom::ProxyResolvingSocketFactoryRequest request) override {} - void CreateWebSocket(mojom::WebSocketRequest request, + void CreateWebSocket(const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + std::vector<mojom::HttpHeaderPtr> additional_headers, int32_t process_id, int32_t render_frame_id, const url::Origin& origin, uint32_t options, + mojom::WebSocketHandshakeClientPtr handshake_client, + mojom::WebSocketClientPtr client, mojom::AuthenticationHandlerPtr auth_handler, mojom::TrustedHeaderClientPtr header_client) override {} void LookUpProxyForURL(
diff --git a/services/network/websocket.cc b/services/network/websocket.cc index ede3fc7..b1544bbf 100644 --- a/services/network/websocket.cc +++ b/services/network/websocket.cc
@@ -146,6 +146,11 @@ << selected_protocol << "\"" << " extensions=\"" << extensions << "\""; + mojom::WebSocketPtr websocket_to_pass; + impl_->binding_.Bind(mojo::MakeRequest(&websocket_to_pass)); + impl_->binding_.set_connection_error_handler( + base::BindOnce(&WebSocket::OnConnectionError, base::Unretained(impl_))); + impl_->handshake_succeeded_ = true; impl_->pending_connection_tracker_.OnCompleteHandshake(); @@ -162,7 +167,11 @@ } DVLOG(3) << "receive_quota_threshold is " << receive_quota_threshold; impl_->handshake_client_->OnConnectionEstablished( - selected_protocol, extensions, receive_quota_threshold); + std::move(websocket_to_pass), selected_protocol, extensions, + receive_quota_threshold); + impl_->handshake_client_ = nullptr; + impl_->auth_handler_ = nullptr; + impl_->header_client_ = nullptr; } void WebSocket::WebSocketEventHandler::OnDataFrame( @@ -205,6 +214,10 @@ << " code=" << code << " reason=\"" << reason << "\""; impl_->client_->OnDropChannel(was_clean, code, reason); + impl_->handshake_client_ = nullptr; + impl_->client_ = nullptr; + impl_->auth_handler_ = nullptr; + impl_->header_client_ = nullptr; // net::WebSocketChannel requires that we delete it at this point. impl_->channel_.reset(); @@ -216,6 +229,10 @@ << reinterpret_cast<void*>(this) << " message=\"" << message << "\""; impl_->client_->OnFailChannel(message); + impl_->handshake_client_ = nullptr; + impl_->client_ = nullptr; + impl_->auth_handler_ = nullptr; + impl_->header_client_ = nullptr; // net::WebSocketChannel requires that we delete it at this point. impl_->channel_.reset(); @@ -326,17 +343,24 @@ WebSocket::WebSocket( std::unique_ptr<Delegate> delegate, - mojom::WebSocketRequest request, + const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + std::vector<mojom::HttpHeaderPtr> additional_headers, + int32_t child_id, + int32_t frame_id, + const url::Origin& origin, + uint32_t options, + mojom::WebSocketHandshakeClientPtr handshake_client, + mojom::WebSocketClientPtr client, mojom::AuthenticationHandlerPtr auth_handler, mojom::TrustedHeaderClientPtr header_client, WebSocketThrottler::PendingConnection pending_connection_tracker, - int child_id, - int frame_id, - url::Origin origin, - uint32_t options, base::TimeDelta delay) : delegate_(std::move(delegate)), - binding_(this, std::move(request)), + binding_(this), + handshake_client_(std::move(handshake_client)), + client_(std::move(client)), auth_handler_(std::move(auth_handler)), header_client_(std::move(header_client)), pending_connection_tracker_(std::move(pending_connection_tracker)), @@ -348,15 +372,31 @@ origin_(std::move(origin)), handshake_succeeded_(false), weak_ptr_factory_(this) { - binding_.set_connection_error_handler( - base::BindOnce(&WebSocket::OnConnectionError, base::Unretained(this))); - + DCHECK(handshake_client_); + DCHECK(client_); + if (auth_handler_) { + // Make sure the request dies if |auth_handler_| has an error, otherwise + // requests can hang. + auth_handler_.set_connection_error_handler( + base::BindOnce(&WebSocket::OnConnectionError, base::Unretained(this))); + } if (header_client_) { // Make sure the request dies if |header_client_| has an error, otherwise // requests can hang. header_client_.set_connection_error_handler( base::BindOnce(&WebSocket::OnConnectionError, base::Unretained(this))); } + if (delay_ > base::TimeDelta()) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&WebSocket::AddChannel, weak_ptr_factory_.GetWeakPtr(), + url, requested_protocols, site_for_cookies, + std::move(additional_headers)), + delay_); + return; + } + AddChannel(url, requested_protocols, site_for_cookies, + std::move(additional_headers)); } WebSocket::~WebSocket() {} @@ -369,56 +409,13 @@ ""); } -void WebSocket::AddChannelRequest( - const GURL& socket_url, - const std::vector<std::string>& requested_protocols, - const GURL& site_for_cookies, - std::vector<mojom::HttpHeaderPtr> additional_headers, - mojom::WebSocketHandshakeClientPtr handshake_client, - mojom::WebSocketClientPtr client) { - DVLOG(3) << "WebSocket::AddChannelRequest @" << reinterpret_cast<void*>(this) - << " socket_url=\"" << socket_url << "\" requested_protocols=\"" - << base::JoinString(requested_protocols, ", ") << "\" origin=\"" - << origin_ << "\" site_for_cookies=\"" << site_for_cookies << "\""; - - if (client_ || !client) { - delegate_->ReportBadMessage( - Delegate::BadMessageReason::kUnexpectedAddChannelRequest, this); - return; - } - - handshake_client_ = std::move(handshake_client); - client_ = std::move(client); - - DCHECK(!channel_); - if (delay_ > base::TimeDelta()) { - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&WebSocket::AddChannel, weak_ptr_factory_.GetWeakPtr(), - socket_url, requested_protocols, site_for_cookies, - std::move(additional_headers)), - delay_); - } else { - AddChannel(socket_url, requested_protocols, site_for_cookies, - std::move(additional_headers)); - } -} - void WebSocket::SendFrame(bool fin, mojom::WebSocketMessageType type, const std::vector<uint8_t>& data) { + DCHECK(handshake_succeeded_); DVLOG(3) << "WebSocket::SendFrame @" << reinterpret_cast<void*>(this) << " fin=" << fin << " type=" << type << " data is " << data.size() << " bytes"; - - if (!handshake_succeeded_) { - // The client should not be sending us frames until after we've informed - // it that the channel has been opened (OnAddChannelResponse). - delegate_->ReportBadMessage( - Delegate::BadMessageReason::kUnexpectedSendFrame, this); - return; - } - if (!channel_) { DVLOG(1) << "Dropping frame sent to closed websocket"; return;
diff --git a/services/network/websocket.h b/services/network/websocket.h index 1ba34870..3712763 100644 --- a/services/network/websocket.h +++ b/services/network/websocket.h
@@ -64,14 +64,19 @@ }; WebSocket(std::unique_ptr<Delegate> delegate, - mojom::WebSocketRequest request, + const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + std::vector<mojom::HttpHeaderPtr> additional_headers, + int32_t process_id, + int32_t render_frame_id, + const url::Origin& origin, + uint32_t options, + mojom::WebSocketHandshakeClientPtr handshake_client, + mojom::WebSocketClientPtr client, mojom::AuthenticationHandlerPtr auth_handler, mojom::TrustedHeaderClientPtr header_client, WebSocketThrottler::PendingConnection pending_connection_tracker, - int child_id, - int frame_id, - url::Origin origin, - uint32_t options, base::TimeDelta delay); ~WebSocket() override; @@ -80,12 +85,6 @@ virtual void GoAway(); // mojom::WebSocket methods: - void AddChannelRequest(const GURL& url, - const std::vector<std::string>& requested_protocols, - const GURL& site_for_cookies, - std::vector<mojom::HttpHeaderPtr> additional_headers, - mojom::WebSocketHandshakeClientPtr handshake_client, - mojom::WebSocketClientPtr client) override; void SendFrame(bool fin, mojom::WebSocketMessageType type, const std::vector<uint8_t>& data) override; @@ -177,8 +176,8 @@ uint32_t options_; - int child_id_; - int frame_id_; + int32_t child_id_; + int32_t frame_id_; // The web origin to use for the WebSocket. const url::Origin origin_;
diff --git a/services/network/websocket_factory.cc b/services/network/websocket_factory.cc index f435776c..811cc7f 100644 --- a/services/network/websocket_factory.cc +++ b/services/network/websocket_factory.cc
@@ -92,25 +92,32 @@ WebSocketFactory::~WebSocketFactory() {} void WebSocketFactory::CreateWebSocket( - mojom::WebSocketRequest request, - mojom::AuthenticationHandlerPtr auth_handler, - mojom::TrustedHeaderClientPtr header_client, + const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + std::vector<mojom::HttpHeaderPtr> additional_headers, int32_t process_id, int32_t render_frame_id, const url::Origin& origin, - uint32_t options) { + uint32_t options, + mojom::WebSocketHandshakeClientPtr handshake_client, + mojom::WebSocketClientPtr client, + mojom::AuthenticationHandlerPtr auth_handler, + mojom::TrustedHeaderClientPtr header_client) { if (throttler_.HasTooManyPendingConnections(process_id)) { // Too many websockets! - request.ResetWithReason( + handshake_client.ResetWithReason( mojom::WebSocket::kInsufficientResources, "Error in connection establishment: net::ERR_INSUFFICIENT_RESOURCES"); return; } connections_.insert(std::make_unique<WebSocket>( - std::make_unique<Delegate>(this, process_id), std::move(request), - std::move(auth_handler), std::move(header_client), - throttler_.IssuePendingConnectionTracker(process_id), process_id, - render_frame_id, origin, options, throttler_.CalculateDelay(process_id))); + std::make_unique<Delegate>(this, process_id), url, requested_protocols, + site_for_cookies, std::move(additional_headers), process_id, + render_frame_id, origin, options, std::move(handshake_client), + std::move(client), std::move(auth_handler), std::move(header_client), + throttler_.IssuePendingConnectionTracker(process_id), + throttler_.CalculateDelay(process_id))); } void WebSocketFactory::OnLostConnectionToClient(WebSocket* impl) {
diff --git a/services/network/websocket_factory.h b/services/network/websocket_factory.h index 2601d227..c0a3785 100644 --- a/services/network/websocket_factory.h +++ b/services/network/websocket_factory.h
@@ -27,13 +27,18 @@ explicit WebSocketFactory(NetworkContext* context); ~WebSocketFactory(); - void CreateWebSocket(mojom::WebSocketRequest request, - mojom::AuthenticationHandlerPtr auth_handler, - mojom::TrustedHeaderClientPtr header_client, + void CreateWebSocket(const GURL& url, + const std::vector<std::string>& requested_protocols, + const GURL& site_for_cookies, + std::vector<mojom::HttpHeaderPtr> additional_headers, int32_t process_id, int32_t render_frame_id, const url::Origin& origin, - uint32_t options); + uint32_t options, + mojom::WebSocketHandshakeClientPtr handshake_client, + mojom::WebSocketClientPtr client, + mojom::AuthenticationHandlerPtr auth_handler, + mojom::TrustedHeaderClientPtr header_client); private: class Delegate;
diff --git a/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc b/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc index 83b4624c..54e267b 100644 --- a/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc +++ b/services/service_manager/sandbox/fuchsia/sandbox_policy_fuchsia.cc
@@ -78,9 +78,10 @@ }, { SANDBOX_TYPE_NETWORK, - base::make_span( - (const char* const[]){fuchsia::net::SocketProvider::Name_, - fuchsia::netstack::Netstack::Name_}), + base::make_span((const char* const[]){ + fuchsia::net::SocketProvider::Name_, + fuchsia::net::NameLookup::Name_, fuchsia::netstack::Netstack::Name_, + "fuchsia.posix.socket.Provider"}), kProvideSslConfig, }, {
diff --git a/third_party/blink/common/fetch/fetch_api_request_body_mojom_traits.cc b/third_party/blink/common/fetch/fetch_api_request_body_mojom_traits.cc index b4b4a6a..e744edb5 100644 --- a/third_party/blink/common/fetch/fetch_api_request_body_mojom_traits.cc +++ b/third_party/blink/common/fetch/fetch_api_request_body_mojom_traits.cc
@@ -21,4 +21,27 @@ return true; } +bool StructTraits< + blink::mojom::FetchAPIDataElementDataView, + network::DataElement>::Read(blink::mojom::FetchAPIDataElementDataView data, + network::DataElement* out) { + if (!data.ReadPath(&out->path_) || !data.ReadFile(&out->file_) || + !data.ReadBlobUuid(&out->blob_uuid_) || + !data.ReadExpectedModificationTime(&out->expected_modification_time_)) { + return false; + } + if (data.type() == network::mojom::DataElementType::kBytes) { + if (!data.ReadBuf(&out->buf_)) + return false; + } + out->type_ = data.type(); + out->data_pipe_getter_ = + data.TakeDataPipeGetter<network::mojom::DataPipeGetterPtrInfo>(); + out->chunked_data_pipe_getter_ = data.TakeChunkedDataPipeGetter< + network::mojom::ChunkedDataPipeGetterPtrInfo>(); + out->offset_ = data.offset(); + out->length_ = data.length(); + return true; +} + } // namespace mojo
diff --git a/third_party/blink/perf_tests/layout/flexbox_with_list_item.html b/third_party/blink/perf_tests/layout/flexbox_with_list_item.html new file mode 100644 index 0000000..d1980066 --- /dev/null +++ b/third_party/blink/perf_tests/layout/flexbox_with_list_item.html
@@ -0,0 +1,52 @@ +<!doctype html> +<head> +<script src="../resources/runner.js"></script> +<style> +#rootview { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + display: flex; + flex-direction: column; +} +#elements-content { color: gray; overflow: auto; } +.outline { outline: auto; } +</style> +</head> +<body> +<div id="rootview"> + <div id="elements-content"></div> +</div> +<script> +const container = document.getElementById('elements-content'); +const kItems = 100; +for (let i = 0; i < kItems; ++i) { + const child = document.createElement('li'); + container.appendChild(child); + child.innerHTML = `child ${i} - ` + `<span>= </span>`.repeat(200); +} + +PerfTestRunner.forceLayout(); + + const startAt = Date.now(); + +// For http://crbug.com/980399 +PerfTestRunner.measureRunsPerSecond({ + descritpion: 'Measuers performance of moving foucs around list item.', + run : () => { + let lastChild = null; + for (const child of container.childNodes) { + if (lastChild) lastChild.classList.toggle('outline'); + child.classList.toggle('outline'); + lastChild = child; + PerfTestRunner.forceLayout(); + } + }, + done: () => { + container.textContent = ''; + }, +}); +</script> +</body>
diff --git a/third_party/blink/public/common/DEPS b/third_party/blink/public/common/DEPS index 727f80b9..6a73e19 100644 --- a/third_party/blink/public/common/DEPS +++ b/third_party/blink/public/common/DEPS
@@ -13,6 +13,7 @@ "+mojo", "+services/network/public/cpp/resource_request_body.h", "+services/network/public/cpp/shared_url_loader_factory.h", + "+services/network/public/mojom/url_loader.mojom.h", "+services/network/public/mojom/url_loader_factory.mojom.h", "+skia/public/interfaces", "+third_party/blink/public/common",
diff --git a/third_party/blink/public/common/fetch/fetch_api_request_body.typemap b/third_party/blink/public/common/fetch/fetch_api_request_body.typemap index b57c723..5e9e926 100644 --- a/third_party/blink/public/common/fetch/fetch_api_request_body.typemap +++ b/third_party/blink/public/common/fetch/fetch_api_request_body.typemap
@@ -12,4 +12,7 @@ "//base", "//services/network/public/cpp:cpp_base", ] -type_mappings = [ "blink.mojom.FetchAPIRequestBody=scoped_refptr<network::ResourceRequestBody>[nullable_is_same_type,copyable_pass_by_value]" ] +type_mappings = [ + "blink.mojom.FetchAPIDataElement=network::DataElement[move_only]", + "blink.mojom.FetchAPIRequestBody=scoped_refptr<network::ResourceRequestBody>[nullable_is_same_type,copyable_pass_by_value]", +]
diff --git a/third_party/blink/public/common/fetch/fetch_api_request_body_mojom_traits.h b/third_party/blink/public/common/fetch/fetch_api_request_body_mojom_traits.h index e8b3d20..2a55afe 100644 --- a/third_party/blink/public/common/fetch/fetch_api_request_body_mojom_traits.h +++ b/third_party/blink/public/common/fetch/fetch_api_request_body_mojom_traits.h
@@ -9,6 +9,7 @@ #include "base/memory/scoped_refptr.h" #include "services/network/public/cpp/resource_request_body.h" +#include "services/network/public/mojom/url_loader.mojom.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" namespace mojo { @@ -43,6 +44,57 @@ scoped_refptr<network::ResourceRequestBody>* out); }; +template <> +struct StructTraits<blink::mojom::FetchAPIDataElementDataView, + network::DataElement> { + static const network::mojom::DataElementType& type( + const network::DataElement& element) { + return element.type_; + } + static std::vector<uint8_t> buf(const network::DataElement& element) { + if (element.bytes_) { + return std::vector<uint8_t>(element.bytes_, + element.bytes_ + element.length_); + } + return std::move(element.buf_); + } + static const base::FilePath& path(const network::DataElement& element) { + return element.path_; + } + static base::File file(const network::DataElement& element) { + return std::move(const_cast<network::DataElement&>(element).file_); + } + static const std::string& blob_uuid(const network::DataElement& element) { + return element.blob_uuid_; + } + static network::mojom::DataPipeGetterPtrInfo data_pipe_getter( + const network::DataElement& element) { + if (element.type_ != network::mojom::DataElementType::kDataPipe) + return nullptr; + return element.CloneDataPipeGetter().PassInterface(); + } + static network::mojom::ChunkedDataPipeGetterPtrInfo chunked_data_pipe_getter( + const network::DataElement& element) { + if (element.type_ != network::mojom::DataElementType::kChunkedDataPipe) + return nullptr; + return const_cast<network::DataElement&>(element) + .ReleaseChunkedDataPipeGetter(); + } + static uint64_t offset(const network::DataElement& element) { + return element.offset_; + } + static uint64_t length(const network::DataElement& element) { + return element.length_; + } + static const base::Time& expected_modification_time( + const network::DataElement& element) { + return element.expected_modification_time_; + } + + static bool Read(blink::mojom::FetchAPIDataElementDataView data, + network::DataElement* out); +}; + } // namespace mojo #endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_FETCH_FETCH_API_REQUEST_BODY_MOJOM_TRAITS_H_
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 9dc26628..f5c8579 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -128,6 +128,7 @@ "wake_lock/wake_lock.mojom", "webaudio/audio_context_manager.mojom", "webdatabase/web_database.mojom", + "websockets/websocket_connector.mojom", "window_features/window_features.mojom", "worker/shared_worker.mojom", "worker/shared_worker_client.mojom", @@ -158,6 +159,8 @@ "//mojo/public/mojom/base", "//services/device/public/mojom", "//services/network/public/mojom", + "//services/network/public/mojom:data_pipe_interfaces", + "//services/network/public/mojom:websocket_mojom", "//services/service_manager/public/mojom", "//services/viz/public/interfaces", "//skia/public/interfaces",
diff --git a/third_party/blink/public/mojom/fetch/fetch_api_request.mojom b/third_party/blink/public/mojom/fetch/fetch_api_request.mojom index 7f766b5..43e420e8 100644 --- a/third_party/blink/public/mojom/fetch/fetch_api_request.mojom +++ b/third_party/blink/public/mojom/fetch/fetch_api_request.mojom
@@ -4,7 +4,12 @@ module blink.mojom; +import "mojo/public/mojom/base/file.mojom"; +import "mojo/public/mojom/base/file_path.mojom"; +import "mojo/public/mojom/base/time.mojom"; import "mojo/public/mojom/base/unguessable_token.mojom"; +import "services/network/public/mojom/chunked_data_pipe_getter.mojom"; +import "services/network/public/mojom/data_pipe_getter.mojom"; import "services/network/public/mojom/fetch_api.mojom"; import "services/network/public/mojom/url_loader.mojom"; import "third_party/blink/public/mojom/blob/serialized_blob.mojom"; @@ -108,6 +113,29 @@ map<string, string> headers; }; +// Represents part of an upload body. This could be either one of bytes, file or +// a data pipe. +struct FetchAPIDataElement { + // The type of the internal contents of network::DataElement. + network.mojom.DataElementType type; + // For kBytes. + array<uint8> buf; + // For kFile and kRawFile + mojo_base.mojom.FilePath path; + // For kRawFile + mojo_base.mojom.File? file; + // For kBlob + string? blob_uuid; + // For kDataPipe + network.mojom.DataPipeGetter? data_pipe_getter; + // For kChunkedDataPipe + network.mojom.ChunkedDataPipeGetter? chunked_data_pipe_getter; + + uint64 offset; + uint64 length; + mojo_base.mojom.Time expected_modification_time; +}; + // Struct representing a Body for a Request: // https://fetch.spec.whatwg.org/#body // This has the same members definition with network.mojom.URLRequestBody, which @@ -119,7 +147,7 @@ // scoped_refptr<blink::EncodedFormData>. struct FetchAPIRequestBody { // Store upload bodies - array<network.mojom.DataElement> elements; + array<FetchAPIDataElement> elements; // Identifies a particular upload instance, which is used by the cache to // formulate a cache key.
diff --git a/third_party/blink/public/mojom/websockets/OWNERS b/third_party/blink/public/mojom/websockets/OWNERS new file mode 100644 index 0000000..6c91416 --- /dev/null +++ b/third_party/blink/public/mojom/websockets/OWNERS
@@ -0,0 +1,7 @@ +file://content/browser/worker_host/OWNERS + +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS + +# TEAM: blink-network-dev@chromium.org +# COMPONENT: Blink>Network>WebSockets
diff --git a/third_party/blink/public/mojom/websockets/README.md b/third_party/blink/public/mojom/websockets/README.md new file mode 100644 index 0000000..a6a22e2 --- /dev/null +++ b/third_party/blink/public/mojom/websockets/README.md
@@ -0,0 +1 @@ +Public mojom files that are referenced both from browser-side and renderer-side for WebSocket.
diff --git a/third_party/blink/public/mojom/websockets/websocket_connector.mojom b/third_party/blink/public/mojom/websockets/websocket_connector.mojom new file mode 100644 index 0000000..2859229 --- /dev/null +++ b/third_party/blink/public/mojom/websockets/websocket_connector.mojom
@@ -0,0 +1,22 @@ +// 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. + +module blink.mojom; + +import "services/network/public/mojom/websocket.mojom"; +import "url/mojom/url.mojom"; + +// An interface for creating a WebSocket connection from the renderer, +// implemented in the browser process. +interface WebSocketConnector { + // Starts an opening handshake. + // |user_agent| is a "user-agent" request header value. For other params, see + // CreateWebSocket in //services/network/public/mojom/network_context.mojom. + Connect(url.mojom.Url url, + array<string> requested_protocols, + url.mojom.Url site_for_cookies, + string? user_agent, + network.mojom.WebSocketHandshakeClient handshake_client, + network.mojom.WebSocketClient connection_client); +};
diff --git a/third_party/blink/public/platform/code_cache_loader.h b/third_party/blink/public/platform/code_cache_loader.h index 4d66d9b..652fd5a 100644 --- a/third_party/blink/public/platform/code_cache_loader.h +++ b/third_party/blink/public/platform/code_cache_loader.h
@@ -7,6 +7,7 @@ #include "base/callback.h" #include "third_party/blink/public/mojom/loader/code_cache.mojom-shared.h" +#include "third_party/blink/public/platform/web_vector.h" #include "url/gurl.h" namespace blink { @@ -25,7 +26,7 @@ virtual void FetchFromCodeCacheSynchronously( const GURL& url, base::Time* response_time_out, - std::vector<uint8_t>* data_out) = 0; + WebVector<uint8_t>* data_out) = 0; virtual void FetchFromCodeCache(blink::mojom::CodeCacheType cache_type, const GURL& url, FetchCodeCacheCallback) = 0;
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index 5a76012..a4787f6 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -167,6 +167,7 @@ EnableRestrictAutomaticLazyFrameLoadingToDataSaver(bool); BLINK_PLATFORM_EXPORT static void EnableRestrictAutomaticLazyImageLoadingToDataSaver(bool); + BLINK_PLATFORM_EXPORT static void EnableLazyImageLoadingMetadataFetch(bool); BLINK_PLATFORM_EXPORT static void EnableScriptedSpeechRecognition(bool); BLINK_PLATFORM_EXPORT static void EnableScriptedSpeechSynthesis(bool); BLINK_PLATFORM_EXPORT static void EnableScrollAnchorSerialization(bool);
diff --git a/third_party/blink/renderer/build/scripts/scripts.gni b/third_party/blink/renderer/build/scripts/scripts.gni index 790cbf8..55ade2a 100644 --- a/third_party/blink/renderer/build/scripts/scripts.gni +++ b/third_party/blink/renderer/build/scripts/scripts.gni
@@ -109,7 +109,7 @@ "-I", rebase_path("//third_party", root_build_dir), "-I", - rebase_path("//tools"), + rebase_path("//tools", root_build_dir), rebase_path(invoker.script, root_build_dir), ] + invoker.args if (defined(invoker.deps)) {
diff --git a/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc b/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc index 60fa9980..aa583d6 100644 --- a/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc +++ b/third_party/blink/renderer/core/accessibility/apply_dark_mode.cc
@@ -55,6 +55,8 @@ dark_mode_settings.image_policy = frame_settings.GetDarkModeImagePolicy(); dark_mode_settings.text_brightness_threshold = frame_settings.GetDarkModeTextBrightnessThreshold(); + dark_mode_settings.background_brightness_threshold = + frame_settings.GetDarkModeBackgroundBrightnessThreshold(); dark_mode_settings.image_grayscale_percent = frame_settings.GetDarkModeImageGrayscale(); return dark_mode_settings;
diff --git a/third_party/blink/renderer/core/css/css_numeric_literal_value.cc b/third_party/blink/renderer/core/css/css_numeric_literal_value.cc index f68eba3..c1e038b 100644 --- a/third_party/blink/renderer/core/css/css_numeric_literal_value.cc +++ b/third_party/blink/renderer/core/css/css_numeric_literal_value.cc
@@ -40,10 +40,8 @@ if (value != int_value) return MakeGarbageCollected<CSSNumericLiteralValue>(value, type); - // TODO(xiaochengh): Make |CSSValuePool| cache |CSSNumericLiteralValue| to - // avoid type casting. CSSValuePool& pool = CssValuePool(); - CSSPrimitiveValue* result = nullptr; + CSSNumericLiteralValue* result = nullptr; switch (type) { case CSSPrimitiveValue::UnitType::kPixels: result = pool.PixelCacheValue(int_value); @@ -52,7 +50,7 @@ int_value, MakeGarbageCollected<CSSNumericLiteralValue>(value, type)); } - return To<CSSNumericLiteralValue>(result); + return result; case CSSPrimitiveValue::UnitType::kPercentage: result = pool.PercentCacheValue(int_value); if (!result) { @@ -60,7 +58,7 @@ int_value, MakeGarbageCollected<CSSNumericLiteralValue>(value, type)); } - return To<CSSNumericLiteralValue>(result); + return result; case CSSPrimitiveValue::UnitType::kNumber: case CSSPrimitiveValue::UnitType::kInteger: result = pool.NumberCacheValue(int_value); @@ -69,7 +67,7 @@ int_value, MakeGarbageCollected<CSSNumericLiteralValue>( value, CSSPrimitiveValue::UnitType::kInteger)); } - return To<CSSNumericLiteralValue>(result); + return result; default: return MakeGarbageCollected<CSSNumericLiteralValue>(value, type); }
diff --git a/third_party/blink/renderer/core/css/css_value_pool.h b/third_party/blink/renderer/core/css/css_value_pool.h index 25a6c6d..6e2af58b 100644 --- a/third_party/blink/renderer/core/css/css_value_pool.h +++ b/third_party/blink/renderer/core/css/css_value_pool.h
@@ -36,7 +36,7 @@ #include "third_party/blink/renderer/core/css/css_inherited_value.h" #include "third_party/blink/renderer/core/css/css_initial_value.h" #include "third_party/blink/renderer/core/css/css_invalid_variable_value.h" -#include "third_party/blink/renderer/core/css/css_primitive_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css/css_unset_value.h" #include "third_party/blink/renderer/core/css/css_value_list.h" @@ -82,25 +82,28 @@ CSSIdentifierValue* css_value) { return identifier_value_cache_[static_cast<int>(ident)] = css_value; } - CSSPrimitiveValue* PixelCacheValue(int int_value) { + CSSNumericLiteralValue* PixelCacheValue(int int_value) { return pixel_value_cache_[int_value]; } - CSSPrimitiveValue* SetPixelCacheValue(int int_value, - CSSPrimitiveValue* css_value) { + CSSNumericLiteralValue* SetPixelCacheValue( + int int_value, + CSSNumericLiteralValue* css_value) { return pixel_value_cache_[int_value] = css_value; } - CSSPrimitiveValue* PercentCacheValue(int int_value) { + CSSNumericLiteralValue* PercentCacheValue(int int_value) { return percent_value_cache_[int_value]; } - CSSPrimitiveValue* SetPercentCacheValue(int int_value, - CSSPrimitiveValue* css_value) { + CSSNumericLiteralValue* SetPercentCacheValue( + int int_value, + CSSNumericLiteralValue* css_value) { return percent_value_cache_[int_value] = css_value; } - CSSPrimitiveValue* NumberCacheValue(int int_value) { + CSSNumericLiteralValue* NumberCacheValue(int int_value) { return number_value_cache_[int_value]; } - CSSPrimitiveValue* SetNumberCacheValue(int int_value, - CSSPrimitiveValue* css_value) { + CSSNumericLiteralValue* SetNumberCacheValue( + int int_value, + CSSNumericLiteralValue* css_value) { return number_value_cache_[int_value] = css_value; } @@ -138,11 +141,11 @@ // Vector caches. HeapVector<Member<CSSIdentifierValue>, numCSSValueKeywords> identifier_value_cache_; - HeapVector<Member<CSSPrimitiveValue>, kMaximumCacheableIntegerValue + 1> + HeapVector<Member<CSSNumericLiteralValue>, kMaximumCacheableIntegerValue + 1> pixel_value_cache_; - HeapVector<Member<CSSPrimitiveValue>, kMaximumCacheableIntegerValue + 1> + HeapVector<Member<CSSNumericLiteralValue>, kMaximumCacheableIntegerValue + 1> percent_value_cache_; - HeapVector<Member<CSSPrimitiveValue>, kMaximumCacheableIntegerValue + 1> + HeapVector<Member<CSSNumericLiteralValue>, kMaximumCacheableIntegerValue + 1> number_value_cache_; // Hash map caches.
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc index cd9d145f..aa6ab01b 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -930,10 +930,10 @@ // non-atomic inline-level box, layout containment has no effect. // (Note we're allowing display:none for display locked elements, and a bit // more restrictive on ruby - banning <ruby> elements entirely). + auto* html_element = DynamicTo<HTMLElement>(element_.Get()); if ((style->IsDisplayTableType() && style->Display() != EDisplay::kTableCell) || - (!element_->IsHTMLElement() || - IsHTMLRubyElement(ToHTMLElement(element_))) || + (!html_element || IsHTMLRubyElement(html_element)) || (style->IsDisplayInlineType() && !style->IsDisplayReplacedType())) { return rejection_names::kContainmentNotSatisfied; }
diff --git a/third_party/blink/renderer/core/dom/document.idl b/third_party/blink/renderer/core/dom/document.idl index 58daf6f..942785dc 100644 --- a/third_party/blink/renderer/core/dom/document.idl +++ b/third_party/blink/renderer/core/dom/document.idl
@@ -34,6 +34,7 @@ // https://html.spec.whatwg.org/C/#documents [ + Exposed=Window, Constructor(), ConstructorCallWith=Document ] interface Document : Node {
diff --git a/third_party/blink/renderer/core/dom/shadow_root.idl b/third_party/blink/renderer/core/dom/shadow_root.idl index 851c72e..ec004df 100644 --- a/third_party/blink/renderer/core/dom/shadow_root.idl +++ b/third_party/blink/renderer/core/dom/shadow_root.idl
@@ -24,8 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// https://w3c.github.io/webcomponents/spec/shadow/#the-shadowroot-interface +// https://dom.spec.whatwg.org/#interface-shadowroot +[Exposed=Window] interface ShadowRoot : DocumentFragment { readonly attribute ShadowRootMode mode; readonly attribute Element host;
diff --git a/third_party/blink/renderer/core/dom/slot_assignment_engine.cc b/third_party/blink/renderer/core/dom/slot_assignment_engine.cc index f62c791..30c4bb9 100644 --- a/third_party/blink/renderer/core/dom/slot_assignment_engine.cc +++ b/third_party/blink/renderer/core/dom/slot_assignment_engine.cc
@@ -40,8 +40,8 @@ } void SlotAssignmentEngine::RecalcSlotAssignments() { - TRACE_EVENT0("blink,benchmark", - "SlotAssignmentEngine::RecalcSlotAssignments"); + if (shadow_roots_needing_recalc_.IsEmpty()) + return; for (auto& shadow_root : HeapHashSet<WeakMember<ShadowRoot>>(shadow_roots_needing_recalc_)) { DCHECK(shadow_root->isConnected());
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc index cd6943b8..69746ec 100644 --- a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc +++ b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
@@ -337,7 +337,7 @@ } int ComputeAutocapitalizeFlags(const Element* element) { - const HTMLElement* const html_element = ToHTMLElementOrNull(element); + const auto* const html_element = DynamicTo<HTMLElement>(element); if (!html_element) return 0;
diff --git a/third_party/blink/renderer/core/events/pointer_event_factory_test.cc b/third_party/blink/renderer/core/events/pointer_event_factory_test.cc index c169f72..7e9e1db 100644 --- a/third_party/blink/renderer/core/events/pointer_event_factory_test.cc +++ b/third_party/blink/renderer/core/events/pointer_event_factory_test.cc
@@ -128,7 +128,7 @@ return pointer_event; } void CreateAndCheckPointerTransitionEvent(PointerEvent*, const AtomicString&); - void CheckNonHoveringPointers(const std::set<int>& expected); + void CheckNonHoveringPointers(const HashSet<int>& expected); PointerEventFactory pointer_event_factory_; int expected_mouse_id_; @@ -177,7 +177,7 @@ } void PointerEventFactoryTest::CheckNonHoveringPointers( - const std::set<int>& expected_pointers) { + const HashSet<int>& expected_pointers) { Vector<int> pointers = pointer_event_factory_.GetPointerIdsOfNonHoveringPointers(); EXPECT_EQ(pointers.size(), expected_pointers.size());
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc index a654d9b..720ae27 100644 --- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc +++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -966,8 +966,7 @@ WebCoalescedInputEvent WebPluginContainerImpl::TransformCoalescedTouchEvent( const WebCoalescedInputEvent& coalesced_event) { WebCoalescedInputEvent transformed_event( - TransformTouchEvent(coalesced_event.Event()), - std::vector<const WebInputEvent*>(), std::vector<const WebInputEvent*>()); + TransformTouchEvent(coalesced_event.Event()), {}, {}); for (size_t i = 0; i < coalesced_event.CoalescedEventSize(); ++i) { transformed_event.AddCoalescedEvent( TransformTouchEvent(coalesced_event.CoalescedEvent(i)));
diff --git a/third_party/blink/renderer/core/frame/settings.json5 b/third_party/blink/renderer/core/frame/settings.json5 index 7895029..3806cba0 100644 --- a/third_party/blink/renderer/core/frame/settings.json5 +++ b/third_party/blink/renderer/core/frame/settings.json5
@@ -919,6 +919,12 @@ invalidate: "Paint", }, { + name: "darkModeBackgroundBrightnessThreshold", + initial: "0", + type: "int", + invalidate: "Paint", + }, + { name: "darkModeImageGrayscale", initial: "0.0", type: "float",
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_registry.idl b/third_party/blink/renderer/core/html/custom/custom_element_registry.idl index ce51bc44..986991b7 100644 --- a/third_party/blink/renderer/core/html/custom/custom_element_registry.idl +++ b/third_party/blink/renderer/core/html/custom/custom_element_registry.idl
@@ -4,6 +4,7 @@ // https://html.spec.whatwg.org/C/custom-elements.html#customelementregistry +[Exposed=Window] interface CustomElementRegistry { [CallWith=ScriptState, CEReactions, CustomElementCallbacks, RaisesException, MeasureAs=CustomElementRegistryDefine] void define(DOMString name, CustomElementConstructor constructor, optional ElementDefinitionOptions options); any get(DOMString name);
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h b/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h index e4de6deb..af5cc43 100644 --- a/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h +++ b/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h
@@ -20,7 +20,6 @@ #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" #include <utility> -#include <vector> namespace blink {
diff --git a/third_party/blink/renderer/core/html/forms/html_label_element.cc b/third_party/blink/renderer/core/html/forms/html_label_element.cc index 5eab315..f1c4ab8 100644 --- a/third_party/blink/renderer/core/html/forms/html_label_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_label_element.cc
@@ -71,7 +71,7 @@ return nullptr; if (Element* element = GetTreeScope().getElementById(control_id)) { - if (auto* html_element = ToHTMLElementOrNull(*element)) { + if (auto* html_element = DynamicTo<HTMLElement>(*element)) { if (html_element->IsLabelable()) { if (!html_element->IsFormControlElement()) { UseCounter::Count(
diff --git a/third_party/blink/renderer/core/html/forms/listed_element.cc b/third_party/blink/renderer/core/html/forms/listed_element.cc index 49feeb2..ee187f76 100644 --- a/third_party/blink/renderer/core/html/forms/listed_element.cc +++ b/third_party/blink/renderer/core/html/forms/listed_element.cc
@@ -669,7 +669,7 @@ } ListedElement* ListedElement::From(Element& element) { - auto* html_element = ToHTMLElementOrNull(element); + auto* html_element = DynamicTo<HTMLElement>(element); if (!html_element) return nullptr; if (auto* form_control_element = DynamicTo<HTMLFormControlElement>(element))
diff --git a/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.js b/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.js index aa2477f..00b970f 100644 --- a/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.js +++ b/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.js
@@ -46,7 +46,7 @@ main.textContent = 'Internal error: ' + errorString; resizeWindow(main.offsetWidth, main.offsetHeight); } else - new ColorPicker(main, args); + new ColorSuggestionPicker(main, args); } // The DefaultColorPalette is used when the list of values are empty. @@ -74,7 +74,7 @@ return null; } -function ColorPicker(element, config) { +function ColorSuggestionPicker(element, config) { Picker.call(this, element, config); this._config = config; if (this._config.values.length === 0) @@ -85,14 +85,14 @@ this._element.addEventListener('mousemove', this._handleMouseMove.bind(this)); this._element.addEventListener('mousedown', this._handleMouseDown.bind(this)); } -ColorPicker.prototype = Object.create(Picker.prototype); +ColorSuggestionPicker.prototype = Object.create(Picker.prototype); var SwatchBorderBoxWidth = 24; // keep in sync with CSS var SwatchBorderBoxHeight = 24; // keep in sync with CSS var SwatchesPerRow = 5; var SwatchesMaxRow = 4; -ColorPicker.prototype._layout = function() { +ColorSuggestionPicker.prototype._layout = function() { var container = createElement('div', 'color-swatch-container'); container.addEventListener('click', this._handleSwatchClick.bind(this), false); for (var i = 0; i < this._config.values.length; ++i) { @@ -119,23 +119,23 @@ resizeWindow(elementWidth, elementHeight); }; -ColorPicker.prototype.selectColorAtIndex = function(index) { +ColorSuggestionPicker.prototype.selectColorAtIndex = function(index) { index = Math.max(Math.min(this._container.childNodes.length - 1, index), 0); this._container.childNodes[index].focus(); }; -ColorPicker.prototype._handleMouseMove = function(event) { +ColorSuggestionPicker.prototype._handleMouseMove = function(event) { if (event.target.classList.contains('color-swatch')) event.target.focus(); }; -ColorPicker.prototype._handleMouseDown = function(event) { +ColorSuggestionPicker.prototype._handleMouseDown = function(event) { // Prevent blur. if (event.target.classList.contains('color-swatch')) event.preventDefault(); }; -ColorPicker.prototype._handleKeyDown = function(event) { +ColorSuggestionPicker.prototype._handleKeyDown = function(event) { var key = event.key; if (key === 'Escape') this.handleCancel(); @@ -172,7 +172,7 @@ event.preventDefault(); }; -ColorPicker.prototype._handleSwatchClick = function(event) { +ColorSuggestionPicker.prototype._handleSwatchClick = function(event) { if (event.target.classList.contains('color-swatch')) this.submitValue(event.target.dataset.value); };
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc index 069431c..74b7bbd 100644 --- a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc +++ b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
@@ -53,7 +53,8 @@ protected: LazyLoadImagesSimTest() : scoped_lazy_image_loading_for_test_(GetParam()), - scoped_automatic_lazy_image_loading_for_test_(GetParam()) {} + scoped_automatic_lazy_image_loading_for_test_(GetParam()), + scoped_lazy_image_loading_metadata_fetch_for_test_(GetParam()) {} void SetLazyLoadEnabled(bool enabled) { WebView().GetPage()->GetSettings().SetLazyLoadEnabled(enabled); @@ -202,6 +203,8 @@ ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test_; ScopedAutomaticLazyImageLoadingForTest scoped_automatic_lazy_image_loading_for_test_; + ScopedLazyImageLoadingMetadataFetchForTest + scoped_lazy_image_loading_metadata_fetch_for_test_ = true; }; TEST_P(LazyLoadImagesSimTest, CSSBackgroundImage) { @@ -365,7 +368,9 @@ // LazyImageLoading is enabled, but AutomaticLazyImageLoading is disabled. kEnabledExplicit, // Both LazyImageLoading and AutomaticLazyImageLoading are enabled. + kEnabledExplicitMetadataFetchDisabled, // Metadata fetch feature disabled. kEnabledAutomatic, + kEnabledAutomaticMetadataFetchDisabled, // Metadata fetch feature disabled. // LazyImageLoading, AutomaticLazyImageLoading, and // RestrictAutomaticLazyImageLoadingToDataSaver are enabled, while data saver // is off. @@ -385,22 +390,31 @@ static constexpr int kViewportHeight = 600; LazyLoadImagesParamsTest() - : scoped_lazy_image_loading_for_test_( - std::get<LazyImageLoadingFeatureStatus>(GetParam()) != + : lazy_image_loading_feature_status_( + std::get<LazyImageLoadingFeatureStatus>(GetParam())), + scoped_lazy_image_loading_for_test_( + lazy_image_loading_feature_status_ != LazyImageLoadingFeatureStatus::kDisabled), scoped_automatic_lazy_image_loading_for_test_( - static_cast<int>( - std::get<LazyImageLoadingFeatureStatus>(GetParam())) >= + static_cast<int>(lazy_image_loading_feature_status_) >= static_cast<int>(LazyImageLoadingFeatureStatus::kEnabledAutomatic)), scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test_( - static_cast<int>( - std::get<LazyImageLoadingFeatureStatus>(GetParam())) >= + static_cast<int>(lazy_image_loading_feature_status_) >= static_cast<int>(LazyImageLoadingFeatureStatus:: kEnabledAutomaticRestrictedAndDataSaverOff)), scoped_data_saver_setting_( - std::get<LazyImageLoadingFeatureStatus>(GetParam()) == + lazy_image_loading_feature_status_ == LazyImageLoadingFeatureStatus:: - kEnabledAutomaticRestrictedAndDataSaverOn) {} + kEnabledAutomaticRestrictedAndDataSaverOn), + scoped_lazy_image_loading_metadata_fetch_for_test_( + lazy_image_loading_feature_status_ != + LazyImageLoadingFeatureStatus::kDisabled && + lazy_image_loading_feature_status_ != + LazyImageLoadingFeatureStatus:: + kEnabledExplicitMetadataFetchDisabled && + lazy_image_loading_feature_status_ != + LazyImageLoadingFeatureStatus:: + kEnabledAutomaticMetadataFetchDisabled) {} void SetUp() override { WebFrameClient().SetEffectiveConnectionTypeForTesting( @@ -432,28 +446,44 @@ } bool IsAutomaticLazyImageLoadingExpected() const { - switch (std::get<LazyImageLoadingFeatureStatus>(GetParam())) { + switch (lazy_image_loading_feature_status_) { case LazyImageLoadingFeatureStatus::kDisabled: case LazyImageLoadingFeatureStatus::kEnabledExplicit: case LazyImageLoadingFeatureStatus:: kEnabledAutomaticRestrictedAndDataSaverOff: + case LazyImageLoadingFeatureStatus::kEnabledExplicitMetadataFetchDisabled: return false; case LazyImageLoadingFeatureStatus::kEnabledAutomatic: case LazyImageLoadingFeatureStatus:: kEnabledAutomaticRestrictedAndDataSaverOn: + case LazyImageLoadingFeatureStatus:: + kEnabledAutomaticMetadataFetchDisabled: return true; } NOTREACHED(); return false; } + bool IsMetadataFetchExpected() { + switch (lazy_image_loading_feature_status_) { + case LazyImageLoadingFeatureStatus::kEnabledExplicitMetadataFetchDisabled: + case LazyImageLoadingFeatureStatus:: + kEnabledAutomaticMetadataFetchDisabled: + return false; + default: + return true; + } + } private: + LazyImageLoadingFeatureStatus lazy_image_loading_feature_status_; ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test_; ScopedAutomaticLazyImageLoadingForTest scoped_automatic_lazy_image_loading_for_test_; ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test_; ScopedDataSaverSetting scoped_data_saver_setting_; + ScopedLazyImageLoadingMetadataFetchForTest + scoped_lazy_image_loading_metadata_fetch_for_test_; }; TEST_P(LazyLoadImagesParamsTest, NearViewport) { @@ -463,22 +493,24 @@ SimSubresourceRequest eager_resource("https://example.com/eager.png", "image/png"); - base::Optional<SimSubresourceRequest> lazy_resource( - base::in_place, "https://example.com/lazy.png", "image/png", - RuntimeEnabledFeatures::LazyImageLoadingEnabled() - ? BuildRequestParamsForRangeResponse() - : SimRequestBase::Params()); - base::Optional<SimSubresourceRequest> auto_resource( - base::in_place, "https://example.com/auto.png", "image/png", - IsAutomaticLazyImageLoadingExpected() - ? BuildRequestParamsForRangeResponse() - : SimRequestBase::Params()); - base::Optional<SimSubresourceRequest> unset_resource( - base::in_place, "https://example.com/unset.png", "image/png", - IsAutomaticLazyImageLoadingExpected() - ? BuildRequestParamsForRangeResponse() - : SimRequestBase::Params()); - + base::Optional<SimSubresourceRequest> lazy_resource, auto_resource, + unset_resource; + if (RuntimeEnabledFeatures::LazyImageLoadingEnabled() && + IsMetadataFetchExpected()) { + lazy_resource.emplace("https://example.com/lazy.png", "image/png", + BuildRequestParamsForRangeResponse()); + } else { + lazy_resource.emplace("https://example.com/lazy.png", "image/png"); + } + if (IsAutomaticLazyImageLoadingExpected() && IsMetadataFetchExpected()) { + auto_resource.emplace("https://example.com/auto.png", "image/png", + BuildRequestParamsForRangeResponse()); + unset_resource.emplace("https://example.com/unset.png", "image/png", + BuildRequestParamsForRangeResponse()); + } else { + auto_resource.emplace("https://example.com/auto.png", "image/png"); + unset_resource.emplace("https://example.com/unset.png", "image/png"); + } LoadURL("https://example.com/"); main_resource.Complete(String::Format( @@ -506,7 +538,8 @@ Vector<char> partial_image; partial_image.Append(full_image.data(), 2048U); - if (RuntimeEnabledFeatures::LazyImageLoadingEnabled()) { + if (RuntimeEnabledFeatures::LazyImageLoadingEnabled() && + IsMetadataFetchExpected()) { lazy_resource->Complete(partial_image); ExpectResourceIsLazyImagePlaceholder( GetDocument().Fetcher()->CachedResource( @@ -514,7 +547,7 @@ lazy_resource.emplace("https://example.com/lazy.png", "image/png"); } - if (IsAutomaticLazyImageLoadingExpected()) { + if (IsAutomaticLazyImageLoadingExpected() && IsMetadataFetchExpected()) { auto_resource->Complete(partial_image); ExpectResourceIsLazyImagePlaceholder( GetDocument().Fetcher()->CachedResource( @@ -592,21 +625,24 @@ SimSubresourceRequest eager_resource("https://example.com/eager.png", "image/png"); - base::Optional<SimSubresourceRequest> lazy_resource( - base::in_place, "https://example.com/lazy.png", "image/png", - RuntimeEnabledFeatures::LazyImageLoadingEnabled() - ? BuildRequestParamsForRangeResponse() - : SimRequestBase::Params()); - base::Optional<SimSubresourceRequest> auto_resource( - base::in_place, "https://example.com/auto.png", "image/png", - IsAutomaticLazyImageLoadingExpected() - ? BuildRequestParamsForRangeResponse() - : SimRequestBase::Params()); - base::Optional<SimSubresourceRequest> unset_resource( - base::in_place, "https://example.com/unset.png", "image/png", - IsAutomaticLazyImageLoadingExpected() - ? BuildRequestParamsForRangeResponse() - : SimRequestBase::Params()); + base::Optional<SimSubresourceRequest> lazy_resource, auto_resource, + unset_resource; + if (RuntimeEnabledFeatures::LazyImageLoadingEnabled() && + IsMetadataFetchExpected()) { + lazy_resource.emplace("https://example.com/lazy.png", "image/png", + BuildRequestParamsForRangeResponse()); + } else { + lazy_resource.emplace("https://example.com/lazy.png", "image/png"); + } + if (IsAutomaticLazyImageLoadingExpected() && IsMetadataFetchExpected()) { + auto_resource.emplace("https://example.com/auto.png", "image/png", + BuildRequestParamsForRangeResponse()); + unset_resource.emplace("https://example.com/unset.png", "image/png", + BuildRequestParamsForRangeResponse()); + } else { + auto_resource.emplace("https://example.com/auto.png", "image/png"); + unset_resource.emplace("https://example.com/unset.png", "image/png"); + } LoadURL("https://example.com/"); @@ -651,17 +687,23 @@ Compositor().BeginFrame(); test::RunPendingTasks(); - EXPECT_FALSE(ConsoleMessages().Contains("main body onload")); + if (std::get<LazyImageLoadingFeatureStatus>(GetParam()) != + LazyImageLoadingFeatureStatus::kEnabledAutomaticMetadataFetchDisabled) { + EXPECT_FALSE(ConsoleMessages().Contains("main body onload")); + } EXPECT_TRUE(ConsoleMessages().Contains("eager onload")); EXPECT_FALSE(ConsoleMessages().Contains("lazy onload")); EXPECT_FALSE(ConsoleMessages().Contains("auto onload")); EXPECT_FALSE(ConsoleMessages().Contains("unset onload")); if (RuntimeEnabledFeatures::LazyImageLoadingEnabled()) { - lazy_resource->Complete(partial_image); - ExpectResourceIsLazyImagePlaceholder( - GetDocument().Fetcher()->CachedResource( - KURL("https://example.com/lazy.png"))); + if (IsMetadataFetchExpected()) { + lazy_resource->Complete(partial_image); + ExpectResourceIsLazyImagePlaceholder( + GetDocument().Fetcher()->CachedResource( + KURL("https://example.com/lazy.png"))); + lazy_resource.emplace("https://example.com/lazy.png", "image/png"); + } } else { lazy_resource->Complete(full_image); ExpectResourceIsFullImage(GetDocument().Fetcher()->CachedResource( @@ -669,15 +711,19 @@ } if (IsAutomaticLazyImageLoadingExpected()) { - auto_resource->Complete(partial_image); - ExpectResourceIsLazyImagePlaceholder( - GetDocument().Fetcher()->CachedResource( - KURL("https://example.com/auto.png"))); + if (IsMetadataFetchExpected()) { + auto_resource->Complete(partial_image); + ExpectResourceIsLazyImagePlaceholder( + GetDocument().Fetcher()->CachedResource( + KURL("https://example.com/auto.png"))); - unset_resource->Complete(partial_image); - ExpectResourceIsLazyImagePlaceholder( - GetDocument().Fetcher()->CachedResource( - KURL("https://example.com/unset.png"))); + unset_resource->Complete(partial_image); + ExpectResourceIsLazyImagePlaceholder( + GetDocument().Fetcher()->CachedResource( + KURL("https://example.com/unset.png"))); + auto_resource.emplace("https://example.com/auto.png", "image/png"); + unset_resource.emplace("https://example.com/unset.png", "image/png"); + } } else { auto_resource->Complete(full_image); ExpectResourceIsFullImage(GetDocument().Fetcher()->CachedResource( @@ -688,19 +734,15 @@ KURL("https://example.com/unset.png"))); } - Compositor().BeginFrame(); - test::RunPendingTasks(); - + if (std::get<LazyImageLoadingFeatureStatus>(GetParam()) != + LazyImageLoadingFeatureStatus::kEnabledAutomaticMetadataFetchDisabled) { + Compositor().BeginFrame(); + test::RunPendingTasks(); + } EXPECT_TRUE(ConsoleMessages().Contains("main body onload")); EXPECT_TRUE(ConsoleMessages().Contains("eager onload")); if (RuntimeEnabledFeatures::LazyImageLoadingEnabled()) { - lazy_resource.emplace("https://example.com/lazy.png", "image/png"); - if (IsAutomaticLazyImageLoadingExpected()) { - auto_resource.emplace("https://example.com/auto.png", "image/png"); - unset_resource.emplace("https://example.com/unset.png", "image/png"); - } - // Scroll down so that the images are near the viewport. GetDocument().View()->LayoutViewport()->SetScrollOffset( ScrollOffset(0, 150), kProgrammaticScroll); @@ -761,7 +803,11 @@ LazyImageLoadingFeatureStatus:: kEnabledAutomaticRestrictedAndDataSaverOff, LazyImageLoadingFeatureStatus:: - kEnabledAutomaticRestrictedAndDataSaverOn), + kEnabledAutomaticRestrictedAndDataSaverOn, + LazyImageLoadingFeatureStatus:: + kEnabledExplicitMetadataFetchDisabled, + LazyImageLoadingFeatureStatus:: + kEnabledAutomaticMetadataFetchDisabled), ::testing::Values(WebEffectiveConnectionType::kTypeUnknown, WebEffectiveConnectionType::kTypeOffline, WebEffectiveConnectionType::kTypeSlow2G, @@ -907,6 +953,8 @@ scoped_automatic_lazy_image_loading_for_test_; ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test_; + ScopedLazyImageLoadingMetadataFetchForTest + scoped_lazy_image_loading_metadata_fetch_for_test_ = true; }; TEST_F(LazyLoadAutomaticImagesTest, AttributeChangedFromLazyToEager) {
diff --git a/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc b/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc index 33cfa4b..212ab4246 100644 --- a/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc +++ b/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc
@@ -87,7 +87,7 @@ ("Media.Video.Autoplay.Muted.Blocked", kAutoplayBlockedReasonMax)); // Autoplay already initiated - if (sources_.count(source)) + if (sources_.Contains(source)) return; sources_.insert(source); @@ -207,7 +207,7 @@ if (sources_.size() == static_cast<size_t>(AutoplaySource::kNumberOfSources)) { source = static_cast<int>(AutoplaySource::kDualSource); - } else if (sources_.count(AutoplaySource::kMethod)) { + } else if (sources_.Contains(AutoplaySource::kMethod)) { source = static_cast<int>(AutoplaySource::kAttribute); } @@ -294,7 +294,7 @@ } void AutoplayUmaHelper::MaybeStartRecordingMutedVideoPlayMethodBecomeVisible() { - if (!sources_.count(AutoplaySource::kMethod) || + if (!sources_.Contains(AutoplaySource::kMethod) || !element_->IsHTMLVideoElement() || !element_->muted()) return; @@ -324,7 +324,7 @@ void AutoplayUmaHelper::MaybeStartRecordingMutedVideoOffscreenDuration() { if (!element_->IsHTMLVideoElement() || !element_->muted() || - !sources_.count(AutoplaySource::kMethod)) + !sources_.Contains(AutoplaySource::kMethod)) return; // Start recording muted video playing offscreen duration. @@ -352,7 +352,7 @@ CurrentTimeTicks() - muted_video_autoplay_offscreen_start_time_; } - DCHECK(sources_.count(AutoplaySource::kMethod)); + DCHECK(sources_.Contains(AutoplaySource::kMethod)); UMA_HISTOGRAM_CUSTOM_TIMES( "Media.Video.Autoplay.Muted.PlayMethod.OffscreenDuration",
diff --git a/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h b/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h index 152ee9c..293eefe 100644 --- a/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h +++ b/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h
@@ -12,8 +12,6 @@ #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/time.h" -#include <set> - namespace blink { // These values are used for histograms. Do not reorder. @@ -70,7 +68,7 @@ bool IsVisible() const { return is_visible_; } - bool HasSource() const { return !sources_.empty(); } + bool HasSource() const { return !sources_.IsEmpty(); } void Invoke(ExecutionContext*, Event*) override; @@ -103,7 +101,7 @@ bool ShouldListenToContextDestroyed() const; // The autoplay sources. - std::set<AutoplaySource> sources_; + HashSet<AutoplaySource> sources_; // The media element this UMA helper is attached to. |element| owns |this|. Member<HTMLMediaElement> element_;
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc index 624f5e4..d33ce94 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -324,6 +324,11 @@ } break; } + // Do not preload if lazyload is possible but metadata fetch is disabled. + if (is_lazy_load_image_enabled && + !RuntimeEnabledFeatures::LazyImageLoadingMetadataFetchEnabled()) { + return nullptr; + } // LazyLoad: Do not preload if absolute dimensions are mentioned in width // and height attributes or in the inline style, and the dimensions are not // small enough.
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc index 666bc1bb..b2c1495c 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/html/parser/html_preload_scanner.h" #include <memory> +#include "base/strings/stringprintf.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_client_hints_type.h" @@ -1213,6 +1214,8 @@ ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); ScopedAutomaticLazyImageLoadingForTest scoped_automatic_lazy_image_loading_for_test(true); + ScopedLazyImageLoadingMetadataFetchForTest + scoped_lazy_image_loading_metadata_fetch_for_test(true); GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { @@ -1249,6 +1252,8 @@ ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); ScopedAutomaticLazyImageLoadingForTest scoped_automatic_lazy_image_loading_for_test(true); + ScopedLazyImageLoadingMetadataFetchForTest + scoped_lazy_image_loading_metadata_fetch_for_test(true); GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { @@ -1267,6 +1272,8 @@ TEST_F(HTMLPreloadScannerTest, LazyLoadImage_FeatureExplicitEnabledWithAttribute) { ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); + ScopedLazyImageLoadingMetadataFetchForTest + scoped_lazy_image_loading_metadata_fetch_for_test(true); GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { @@ -1284,6 +1291,8 @@ ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); ScopedAutomaticLazyImageLoadingForTest scoped_automatic_lazy_image_loading_for_test(true); + ScopedLazyImageLoadingMetadataFetchForTest + scoped_lazy_image_loading_metadata_fetch_for_test(true); GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); PreloadScannerTestCase test_cases[] = { @@ -1322,6 +1331,8 @@ LazyLoadImage_FeatureExplicitPreloadForLargeImages) { // Large images should not be preloaded, when loading is lazy. ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); + ScopedLazyImageLoadingMetadataFetchForTest + scoped_lazy_image_loading_metadata_fetch_for_test(true); GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); PreloadScannerTestCase test_cases[] = { @@ -1348,4 +1359,59 @@ Test(test_case); } +TEST_F(HTMLPreloadScannerTest, LazyLoadImage_DisableMetadataFetch) { + GetDocument().GetSettings()->SetLazyLoadEnabled(true); + struct TestCase { + bool metadata_fetch_feature_enabled; + bool automatic_lazy_image_loading_enabled; + const char* loading_attr_value; + bool expected_is_preload; + // If preload happens, whether it is a fetch of placeholder or full image. + bool expected_is_placeholder_fetch; + }; + const TestCase test_cases[] = { + // The lazyload eligible cases should not trigger any preload when + // metadata fetch feature disabled, and trigger placeholder fetch if + // metadata fetch feature is active. + {false, false, "lazy", false, false}, + {false, true, "lazy", false, false}, + {false, true, "auto", false, false}, + {true, false, "lazy", true, true}, + {true, true, "lazy", true, true}, + {true, true, "auto", true, true}, + + // Lazyload ineligible case. + {false, false, "auto", true, false}, + {true, false, "auto", true, false}, + + // Full image should be fetched when loading='eager' irrespective of + // automatic lazyload or metadata fetch feature states. + {false, false, "eager", true, false}, + {false, true, "eager", true, false}, + {true, false, "eager", true, false}, + {true, true, "eager", true, false}, + }; + for (const auto& test_case : test_cases) { + ScopedLazyImageLoadingMetadataFetchForTest + scoped_lazy_image_loading_metadata_fetch_for_test( + test_case.metadata_fetch_feature_enabled); + ScopedAutomaticLazyImageLoadingForTest + scoped_automatic_lazy_image_loading_for_test( + test_case.automatic_lazy_image_loading_enabled); + RunSetUp(kViewportEnabled); + const std::string img_html = base::StringPrintf( + "<img src='foo.jpg' loading='%s'>", test_case.loading_attr_value); + if (test_case.expected_is_preload) { + LazyLoadImageTestCase test_preload = { + img_html.c_str(), test_case.expected_is_placeholder_fetch}; + Test(test_preload); + } else { + PreloadScannerTestCase test_no_preload = { + "http://example.test", img_html.c_str(), nullptr, + "http://example.test/", ResourceType::kImage, 0}; + Test(test_no_preload); + } + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc index 675c620..1bfde5a 100644 --- a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc +++ b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc
@@ -338,17 +338,23 @@ } else { // Create a LayoutText in it. LayoutText* text = nullptr; + // |text_style| should be as same as style propagated in + // |LayoutObject::PropagateStyleToAnonymousChildren()| to avoid unexpected + // full layout due by style difference. See http://crbug.com/980399 + scoped_refptr<ComputedStyle> text_style = + ComputedStyle::CreateAnonymousStyleWithDisplay( + marker_->StyleRef(), marker_->StyleRef().Display()); if (child) { if (child->IsText()) { text = ToLayoutText(child); - text->SetStyle(marker_->Style()); + text->SetStyle(text_style); } else { child->Destroy(); child = nullptr; } } if (!child) { - text = LayoutText::CreateEmptyAnonymous(GetDocument(), marker_->Style(), + text = LayoutText::CreateEmptyAnonymous(GetDocument(), text_style, LegacyLayout::kAuto); marker_->AddChild(text); is_marker_text_updated_ = false;
diff --git a/third_party/blink/renderer/core/layout/scroll_anchor.cc b/third_party/blink/renderer/core/layout/scroll_anchor.cc index 22e1232b..25d5eda 100644 --- a/third_party/blink/renderer/core/layout/scroll_anchor.cc +++ b/third_party/blink/renderer/core/layout/scroll_anchor.cc
@@ -230,7 +230,7 @@ SCOPED_BLINK_UMA_HISTOGRAM_TIMER( "Layout.ScrollAnchor.TimeToComputeAnchorNodeSelector"); - std::vector<String> selector_list; + Vector<String> selector_list; for (Element* element = ElementTraversal::FirstAncestorOrSelf(*anchor_node); element; element = ElementTraversal::FirstAncestor(*element)) { selector_list.push_back(UniqueSimpleSelectorAmongSiblings(element));
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc index b173bbe..abb548d 100644 --- a/third_party/blink/renderer/core/loader/image_loader.cc +++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -504,11 +504,12 @@ if (auto* html_image = ToHTMLImageElementOrNull(GetElement())) { using DeferralMessage = LazyLoadImageObserver::DeferralMessage; LoadingAttrValue loading_attr = GetLoadingAttrValue(*html_image); - DCHECK(loading_attr != LoadingAttrValue::kEager); + DCHECK_NE(loading_attr, LoadingAttrValue::kEager); auto deferral_message = DeferralMessage::kNone; if (loading_attr == LoadingAttrValue::kAuto) { deferral_message = DeferralMessage::kLoadEventsDeferred; - } else if (!was_fully_deferred_) { + } else if (!IsDimensionAbsoluteLarge(*html_image)) { + DCHECK_EQ(loading_attr, LoadingAttrValue::kLazy); deferral_message = DeferralMessage::kMissingDimensionForLazy; } LazyLoadImageObserver::StartMonitoring(html_image, deferral_message); @@ -608,7 +609,10 @@ LazyLoadImageEligibility::kEnabledAutomatic && lazy_load_image_setting == LocalFrame::LazyLoadImageSetting::kEnabledAutomatic)) { - if ((was_fully_deferred_ = IsDimensionAbsoluteLarge(*html_image))) { + if ((was_fully_deferred_ = + !RuntimeEnabledFeatures:: + LazyImageLoadingMetadataFetchEnabled() || + IsDimensionAbsoluteLarge(*html_image))) { params.SetLazyImageDeferred(); if (frame->Client()) { frame->Client()->DidObserveLazyLoadBehavior(
diff --git a/third_party/blink/renderer/core/script/BUILD.gn b/third_party/blink/renderer/core/script/BUILD.gn index 1346b025..83dd22d7 100644 --- a/third_party/blink/renderer/core/script/BUILD.gn +++ b/third_party/blink/renderer/core/script/BUILD.gn
@@ -58,6 +58,8 @@ "script_runner.cc", "script_runner.h", "script_scheduling_type.h", + "value_wrapper_synthetic_module_script.cc", + "value_wrapper_synthetic_module_script.h", "worker_modulator_impl.cc", "worker_modulator_impl.h", "worklet_modulator_impl.cc",
diff --git a/third_party/blink/renderer/core/script/js_module_script.cc b/third_party/blink/renderer/core/script/js_module_script.cc index 777d84d..8b12c6ac 100644 --- a/third_party/blink/renderer/core/script/js_module_script.cc +++ b/third_party/blink/renderer/core/script/js_module_script.cc
@@ -6,8 +6,6 @@ #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/core/script/module_record_resolver.h" -#include "third_party/blink/renderer/core/workers/worker_global_scope.h" -#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "v8/include/v8.h" @@ -166,21 +164,6 @@ start_position_(start_position), produce_cache_data_(produce_cache_data) {} -void JSModuleScript::RunScriptOnWorker(WorkerGlobalScope& worker_global_scope) { - DCHECK(worker_global_scope.IsContextThread()); - - WorkerReportingProxy& worker_reporting_proxy = - worker_global_scope.ReportingProxy(); - - worker_reporting_proxy.WillEvaluateModuleScript(); - // This |error| is always null because the second argument is |kReport|. - // TODO(nhiroki): Catch an error when an evaluation error happens. - // (https://crbug.com/680046) - ScriptValue error = SettingsObject()->ExecuteModule( - this, Modulator::CaptureEvalErrorFlag::kReport); - worker_reporting_proxy.DidEvaluateModuleScript(error.IsEmpty()); -} - String JSModuleScript::InlineSourceTextForCSP() const { return source_text_.ToString(); }
diff --git a/third_party/blink/renderer/core/script/js_module_script.h b/third_party/blink/renderer/core/script/js_module_script.h index 3084b9a..61089f8 100644 --- a/third_party/blink/renderer/core/script/js_module_script.h +++ b/third_party/blink/renderer/core/script/js_module_script.h
@@ -74,7 +74,6 @@ ModuleRecordProduceCacheData* produce_cache_data); const TextPosition& StartPosition() const { return start_position_; } - void RunScriptOnWorker(WorkerGlobalScope&) override; String InlineSourceTextForCSP() const override; // For CSP check.
diff --git a/third_party/blink/renderer/core/script/module_script.cc b/third_party/blink/renderer/core/script/module_script.cc index 96c2f891..16fbb403 100644 --- a/third_party/blink/renderer/core/script/module_script.cc +++ b/third_party/blink/renderer/core/script/module_script.cc
@@ -6,6 +6,8 @@ #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/core/script/module_record_resolver.h" +#include "third_party/blink/renderer/core/workers/worker_global_scope.h" +#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "v8/include/v8.h" @@ -104,6 +106,21 @@ Modulator::CaptureEvalErrorFlag::kReport); } +void ModuleScript::RunScriptOnWorker(WorkerGlobalScope& worker_global_scope) { + DCHECK(worker_global_scope.IsContextThread()); + + WorkerReportingProxy& worker_reporting_proxy = + worker_global_scope.ReportingProxy(); + + worker_reporting_proxy.WillEvaluateModuleScript(); + // This |error| is always null because the second argument is |kReport|. + // TODO(nhiroki): Catch an error when an evaluation error happens. + // (https://crbug.com/680046) + ScriptValue error = SettingsObject()->ExecuteModule( + this, Modulator::CaptureEvalErrorFlag::kReport); + worker_reporting_proxy.DidEvaluateModuleScript(error.IsEmpty()); +} + std::ostream& operator<<(std::ostream& stream, const ModuleScript& module_script) { stream << "ModuleScript[" << &module_script;
diff --git a/third_party/blink/renderer/core/script/module_script.h b/third_party/blink/renderer/core/script/module_script.h index 1fa24de..50d32f0e 100644 --- a/third_party/blink/renderer/core/script/module_script.h +++ b/third_party/blink/renderer/core/script/module_script.h
@@ -67,6 +67,7 @@ return mojom::ScriptType::kModule; } void RunScript(LocalFrame*, const SecurityOrigin*) override; + void RunScriptOnWorker(WorkerGlobalScope&) override; friend class ModuleTreeLinkerTestModulator;
diff --git a/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc b/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc new file mode 100644 index 0000000..5860f7622 --- /dev/null +++ b/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.cc
@@ -0,0 +1,45 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.h" + +#include "third_party/blink/renderer/core/script/modulator.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/wtf/text/text_position.h" +#include "v8/include/v8.h" + +namespace blink { + +ValueWrapperSyntheticModuleScript::ValueWrapperSyntheticModuleScript( + Modulator* settings_object, + ModuleRecord record, + const KURL& source_url, + const KURL& base_url, + const ScriptFetchOptions& fetch_options, + v8::Local<v8::Value> value, + const TextPosition& start_position) + : ModuleScript(settings_object, + record, + source_url, + base_url, + fetch_options), + export_value_(v8::Isolate::GetCurrent(), value) {} + +String ValueWrapperSyntheticModuleScript::InlineSourceTextForCSP() const { + // We don't construct a ValueWrapperSyntheticModuleScript with the original + // source, but instead construct it from the originally parsed + // text. If a need arises for the original module source to be used later, + // ValueWrapperSyntheticModuleScript will need to be modified such that its + // constructor takes this source text as an additional parameter and stashes + // it on the ValueWrapperSyntheticModuleScript. + NOTREACHED(); + return ""; +} + +void ValueWrapperSyntheticModuleScript::Trace(Visitor* visitor) { + visitor->Trace(export_value_); + ModuleScript::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.h b/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.h new file mode 100644 index 0000000..9ee73357 --- /dev/null +++ b/third_party/blink/renderer/core/script/value_wrapper_synthetic_module_script.h
@@ -0,0 +1,44 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_VALUE_WRAPPER_SYNTHETIC_MODULE_SCRIPT_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_VALUE_WRAPPER_SYNTHETIC_MODULE_SCRIPT_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/script/module_script.h" + +namespace WTF { +class TextPosition; +} // namespace WTF + +namespace blink { + +class KURL; +class Modulator; + +// ValueWrapperSyntheticModuleScript is a module script +// (https://html.spec.whatwg.org/C/#module-script) that default-exports a single +// v8::Value, for example JSON Module Script: +// https://html.spec.whatwg.org/multipage/webappapis.html#json-module-script +class CORE_EXPORT ValueWrapperSyntheticModuleScript final + : public ModuleScript { + public: + ValueWrapperSyntheticModuleScript(Modulator* settings_object, + ModuleRecord record, + const KURL& source_url, + const KURL& base_url, + const ScriptFetchOptions& fetch_options, + v8::Local<v8::Value> value, + const TextPosition& start_position); + + String InlineSourceTextForCSP() const override; + void Trace(blink::Visitor* visitor) override; + + private: + TraceWrapperV8Reference<v8::Value> export_value_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_VALUE_WRAPPER_SYNTHETIC_MODULE_SCRIPT_H_
diff --git a/third_party/blink/renderer/devtools/OWNERS b/third_party/blink/renderer/devtools/OWNERS index 40f586c..147b931 100644 --- a/third_party/blink/renderer/devtools/OWNERS +++ b/third_party/blink/renderer/devtools/OWNERS
@@ -2,4 +2,5 @@ pfeldman@chromium.org lushnikov@chromium.org einbinder@chromium.org +luoe@chromium.org per-file BUILD.gn=*
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index 497d399..19be961c 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -243,7 +243,7 @@ if (HasContentEditableAttributeSet()) return kIncludeObject; - static const std::set<ax::mojom::Role> always_included_computed_roles = { + static const HashSet<ax::mojom::Role> always_included_computed_roles = { ax::mojom::Role::kAbbr, ax::mojom::Role::kBlockquote, ax::mojom::Role::kContentDeletion,
diff --git a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc index 8c8baef..cd1eeded 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
@@ -270,7 +270,7 @@ } void AXRelationCache::LabelChanged(Node* node) { - const AtomicString& id = ToHTMLElement(node)->FastGetAttribute(kForAttr); + const auto& id = To<HTMLElement>(node)->FastGetAttribute(kForAttr); if (!id.IsEmpty()) { all_previously_seen_label_target_ids_.insert(id); if (HTMLElement* control = ToHTMLLabelElement(node)->control())
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc index bd0161d9..ec554b7 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc
@@ -88,7 +88,7 @@ KURL BackgroundFetchIconLoader::PickBestIconForDisplay( ExecutionContext* execution_context, int ideal_size_pixels) { - std::vector<Manifest::ImageResource> icons; + WebVector<Manifest::ImageResource> icons; for (auto& icon : icons_) { // Update the src of |icon| to include the base URL in case relative paths // were used. @@ -106,7 +106,7 @@ } return KURL(ManifestIconSelector::FindBestMatchingSquareIcon( - std::move(icons), ideal_size_pixels, kMinimumIconSizeInPx, + icons.ReleaseVector(), ideal_size_pixels, kMinimumIconSizeInPx, Manifest::ImageResource::Purpose::ANY)); }
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h b/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h index e4e736ad..44646c5 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h
@@ -7,8 +7,6 @@ #include <stdint.h> -#include <set> - #include "base/single_thread_task_runner.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" @@ -118,7 +116,6 @@ mojom::blink::IDBCallbacksAssociatedPtrInfo GetCallbacksProxy( std::unique_ptr<WebIDBCallbacks> callbacks); - std::set<int32_t> observer_ids_; mojom::blink::IDBDatabaseAssociatedPtr database_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; };
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.h b/third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.h index bf91d72..e46c1994 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.h +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_transaction_impl.h
@@ -7,7 +7,6 @@ #include <stdint.h> #include <memory> -#include <set> #include "base/single_thread_task_runner.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h"
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc b/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc index 1066e30..c048895 100644 --- a/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc +++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc
@@ -113,9 +113,9 @@ blink::WebMediaStreamSource::Capabilities capabilities; capabilities.device_id = track_id; - capabilities.echo_cancellation = std::vector<bool>({false}); - capabilities.auto_gain_control = std::vector<bool>({false}); - capabilities.noise_suppression = std::vector<bool>({false}); + capabilities.echo_cancellation.emplace_back(false); + capabilities.auto_gain_control.emplace_back(false); + capabilities.noise_suppression.emplace_back(false); capabilities.sample_size = { media::SampleFormatToBitsPerChannel(media::kSampleFormatS16), // min media::SampleFormatToBitsPerChannel(media::kSampleFormatS16) // max
diff --git a/third_party/blink/renderer/modules/mediarecorder/audio_track_encoder.h b/third_party/blink/renderer/modules/mediarecorder/audio_track_encoder.h index 238ae2b8..24a959b5 100644 --- a/third_party/blink/renderer/modules/mediarecorder/audio_track_encoder.h +++ b/third_party/blink/renderer/modules/mediarecorder/audio_track_encoder.h
@@ -29,7 +29,7 @@ public: using OnEncodedAudioCB = base::RepeatingCallback<void(const media::AudioParameters& params, - std::unique_ptr<std::string> encoded_data, + std::string encoded_data, base::TimeTicks capture_time)>; explicit AudioTrackEncoder(OnEncodedAudioCB on_encoded_audio_cb);
diff --git a/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc index 75de047..007b35d7 100644 --- a/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc +++ b/third_party/blink/renderer/modules/mediarecorder/audio_track_opus_encoder.cc
@@ -171,9 +171,9 @@ audio_bus->ToInterleaved<media::Float32SampleTypeTraits>( audio_bus->frames(), buffer_.get()); - std::unique_ptr<std::string> encoded_data(new std::string()); + std::string encoded_data; if (DoEncode(opus_encoder_, buffer_.get(), kOpusPreferredFramesPerBuffer, - encoded_data.get())) { + &encoded_data)) { const base::TimeTicks capture_time_of_first_sample = capture_time - media::AudioTimestampHelper::FramesToTime( input_bus->frames(), input_params_.sample_rate());
diff --git a/third_party/blink/renderer/modules/mediarecorder/audio_track_pcm_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/audio_track_pcm_encoder.cc index c6af2621..81c65e2 100644 --- a/third_party/blink/renderer/modules/mediarecorder/audio_track_pcm_encoder.cc +++ b/third_party/blink/renderer/modules/mediarecorder/audio_track_pcm_encoder.cc
@@ -36,10 +36,10 @@ if (paused_) return; - std::unique_ptr<std::string> encoded_data_string(new std::string()); - encoded_data_string->resize(input_bus->frames() * input_bus->channels() * - sizeof(float)); - char* encoded_data_ptr = base::data(*encoded_data_string); + std::string encoded_data_string; + encoded_data_string.resize(input_bus->frames() * input_bus->channels() * + sizeof(float)); + char* encoded_data_ptr = base::data(encoded_data_string); input_bus->ToInterleaved<media::Float32SampleTypeTraits>( input_bus->frames(), reinterpret_cast<float*>(encoded_data_ptr));
diff --git a/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h b/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h index e9eb1d02..d8a87a0 100644 --- a/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h +++ b/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h
@@ -46,7 +46,7 @@ using OnEncodedAudioCB = base::RepeatingCallback<void(const media::AudioParameters& params, - std::unique_ptr<std::string> encoded_data, + std::string encoded_data, base::TimeTicks capture_time)>; static CodecId GetPreferredCodecId();
diff --git a/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc b/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc index fe3230d1..2da3042 100644 --- a/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc +++ b/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc
@@ -177,9 +177,9 @@ base::TimeTicks timestamp)); void OnEncodedAudio(const media::AudioParameters& params, - std::unique_ptr<std::string> encoded_data, + std::string encoded_data, base::TimeTicks timestamp) { - EXPECT_TRUE(!encoded_data->empty()); + EXPECT_TRUE(!encoded_data.empty()); if (codec_ == AudioTrackRecorder::CodecId::OPUS) { // Decode |encoded_data| and check we get the expected number of frames @@ -188,22 +188,22 @@ kDefaultSampleRate * kOpusBufferDurationMs / 1000, opus_decode_float( opus_decoder_, - reinterpret_cast<uint8_t*>(base::data(*encoded_data)), - encoded_data->size(), opus_buffer_.get(), kFramesPerBuffer, 0)); + reinterpret_cast<uint8_t*>(base::data(encoded_data)), + encoded_data.size(), opus_buffer_.get(), kFramesPerBuffer, 0)); } else if (codec_ == AudioTrackRecorder::CodecId::PCM) { // Manually confirm that we're getting the same data out as what we // generated from the sine wave. - for (size_t b = 0; b + 3 < encoded_data->size() && + for (size_t b = 0; b + 3 < encoded_data.size() && first_source_cache_pos_ < first_source_cache_.size(); b += sizeof(first_source_cache_[0]), ++first_source_cache_pos_) { float sample; - memcpy(&sample, &(*encoded_data)[b], 4); + memcpy(&sample, &(encoded_data)[b], 4); ASSERT_FLOAT_EQ(sample, first_source_cache_[first_source_cache_pos_]) << "(Sample " << first_source_cache_pos_ << ")"; } } - DoOnEncodedAudio(params, *encoded_data, timestamp); + DoOnEncodedAudio(params, std::move(encoded_data), timestamp); } // ATR and WebMediaStreamTrack for fooling it.
diff --git a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc index 1f6ca859..3764fbc 100644 --- a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc +++ b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
@@ -84,7 +84,7 @@ const media::WebmMuxer::VideoParameters video_params(frame); frame = nullptr; - std::unique_ptr<std::string> data(new std::string); + std::string data; const uint8_t kNALStartCode[4] = {0, 0, 0, 1}; for (int layer = 0; layer < info.iLayerNum; ++layer) { const SLayerBSInfo& layerInfo = info.sLayerInfo[layer]; @@ -101,7 +101,7 @@ layer_len += layerInfo.pNalLengthInByte[nal]; } // Copy the entire layer's data (including NAL start codes). - data->append(reinterpret_cast<char*>(layerInfo.pBsBuf), layer_len); + data.append(reinterpret_cast<char*>(layerInfo.pBsBuf), layer_len); } const bool is_key_frame = info.eFrameType == videoFrameTypeIDR; @@ -110,7 +110,7 @@ CrossThreadBindOnce( OnFrameEncodeCompleted, WTF::Passed(CrossThreadBindRepeating(on_encoded_video_callback_)), - video_params, std::move(data), nullptr, capture_timestamp, + video_params, std::move(data), std::string(), capture_timestamp, is_key_frame)); }
diff --git a/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc b/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc index 416dbb5a..1f49b42 100644 --- a/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc +++ b/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc
@@ -454,8 +454,8 @@ void MediaRecorderHandler::OnEncodedVideo( const media::WebmMuxer::VideoParameters& params, - std::unique_ptr<std::string> encoded_data, - std::unique_ptr<std::string> encoded_alpha, + std::string encoded_data, + std::string encoded_alpha, base::TimeTicks timestamp, bool is_key_frame) { DCHECK(IsMainThread()); @@ -474,10 +474,9 @@ } } -void MediaRecorderHandler::OnEncodedAudio( - const media::AudioParameters& params, - std::unique_ptr<std::string> encoded_data, - base::TimeTicks timestamp) { +void MediaRecorderHandler::OnEncodedAudio(const media::AudioParameters& params, + std::string encoded_data, + base::TimeTicks timestamp) { DCHECK(IsMainThread()); if (UpdateTracksAndCheckIfChanged()) {
diff --git a/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h b/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h index b368325..37194f5 100644 --- a/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h +++ b/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h
@@ -89,15 +89,13 @@ // Called to indicate there is encoded video data available. |encoded_alpha| // represents the encode output of alpha channel when available, can be // nullptr otherwise. - // TODO(crbug.com/960665): Replace std::string with WTF::String void OnEncodedVideo(const media::WebmMuxer::VideoParameters& params, - std::unique_ptr<std::string> encoded_data, - std::unique_ptr<std::string> encoded_alpha, + std::string encoded_data, + std::string encoded_alpha, base::TimeTicks timestamp, bool is_key_frame); - // TODO(crbug.com/960665): Replace std::string with WTF::String void OnEncodedAudio(const media::AudioParameters& params, - std::unique_ptr<std::string> encoded_data, + std::string encoded_data, base::TimeTicks timestamp); void WriteData(base::StringPiece data);
diff --git a/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc index b94567f6..0ece792 100644 --- a/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc +++ b/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc
@@ -135,9 +135,9 @@ base::SharedMemory* output_buffer = output_buffers_[bitstream_buffer_id].get(); - std::unique_ptr<std::string> data(new std::string); - data->append(static_cast<char*>(output_buffer->memory()), - metadata.payload_size_bytes); + std::string data; + data.append(static_cast<char*>(output_buffer->memory()), + metadata.payload_size_bytes); const auto front_frame = frames_in_encode_.TakeFirst(); PostCrossThreadTask( @@ -145,7 +145,7 @@ CrossThreadBindOnce( OnFrameEncodeCompleted, WTF::Passed(CrossThreadBindRepeating(on_encoded_video_callback_)), - front_frame.first, std::move(data), nullptr, front_frame.second, + front_frame.first, std::move(data), std::string(), front_frame.second, metadata.key_frame)); UseOutputBitstreamBufferId(bitstream_buffer_id);
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc index b993f06..06ee37bb 100644 --- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc +++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
@@ -368,11 +368,11 @@ void VideoTrackRecorder::Encoder::OnFrameEncodeCompleted( const OnEncodedVideoInternalCB& on_encoded_video_cb, const media::WebmMuxer::VideoParameters& params, - std::unique_ptr<std::string> data, - std::unique_ptr<std::string> alpha_data, + std::string data, + std::string alpha_data, base::TimeTicks capture_timestamp, bool keyframe) { - DVLOG(1) << (keyframe ? "" : "non ") << "keyframe " << data->length() << "B, " + DVLOG(1) << (keyframe ? "" : "non ") << "keyframe " << data.length() << "B, " << capture_timestamp << " ms"; on_encoded_video_cb.Run(params, std::move(data), std::move(alpha_data), capture_timestamp, keyframe);
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h index 88d99224..189b3a5 100644 --- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h +++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h
@@ -58,6 +58,13 @@ static Type Copy(Type pointer) { return pointer; } }; +template <> +struct CrossThreadCopier<std::string> { + STATIC_ONLY(CrossThreadCopier); + using Type = std::string; + static Type Copy(Type&& value) { return std::move(value); } +}; + } // namespace WTF namespace blink { @@ -89,8 +96,8 @@ using OnEncodedVideoCB = base::RepeatingCallback<void( const media::WebmMuxer::VideoParameters& params, - std::unique_ptr<std::string> encoded_data, - std::unique_ptr<std::string> encoded_alpha, + std::string encoded_data, + std::string encoded_alpha, base::TimeTicks capture_timestamp, bool is_key_frame)>; using OnErrorCB = base::RepeatingClosure; @@ -147,16 +154,16 @@ using OnEncodedVideoInternalCB = WTF::CrossThreadFunction<void( const media::WebmMuxer::VideoParameters& params, - std::unique_ptr<std::string> encoded_data, - std::unique_ptr<std::string> encoded_alpha, + std::string encoded_data, + std::string encoded_alpha, base::TimeTicks capture_timestamp, bool is_key_frame)>; static void OnFrameEncodeCompleted( const OnEncodedVideoInternalCB& on_encoded_video_cb, const media::WebmMuxer::VideoParameters& params, - std::unique_ptr<std::string> data, - std::unique_ptr<std::string> alpha_data, + std::string data, + std::string alpha_data, base::TimeTicks capture_timestamp, bool keyframe);
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc index aed1633..c58e630 100644 --- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc +++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc
@@ -104,12 +104,11 @@ base::TimeTicks timestamp, bool keyframe)); void OnEncodedVideo(const media::WebmMuxer::VideoParameters& params, - std::unique_ptr<std::string> encoded_data, - std::unique_ptr<std::string> encoded_alpha, + std::string encoded_data, + std::string encoded_alpha, base::TimeTicks timestamp, bool is_key_frame) { - DoOnEncodedVideo(params, *encoded_data, - encoded_alpha ? *encoded_alpha : std::string(), timestamp, + DoOnEncodedVideo(params, encoded_data, encoded_alpha, timestamp, is_key_frame); }
diff --git a/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc index ab6c646..5d1afe33 100644 --- a/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc +++ b/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc
@@ -107,7 +107,7 @@ const bool force_keyframe = frame_has_alpha && !last_frame_had_alpha_; last_frame_had_alpha_ = frame_has_alpha; - std::unique_ptr<std::string> data(new std::string); + std::string data; bool keyframe = false; DoEncode(encoder_.get(), frame_size, frame->data(VideoFrame::kYPlane), frame->visible_data(VideoFrame::kYPlane), @@ -115,10 +115,10 @@ frame->visible_data(VideoFrame::kUPlane), frame->stride(VideoFrame::kUPlane), frame->visible_data(VideoFrame::kVPlane), - frame->stride(VideoFrame::kVPlane), duration, force_keyframe, - data.get(), &keyframe); + frame->stride(VideoFrame::kVPlane), duration, force_keyframe, data, + &keyframe); - std::unique_ptr<std::string> alpha_data(new std::string); + std::string alpha_data; if (frame_has_alpha) { bool alpha_keyframe = false; DoEncode(alpha_encoder_.get(), frame_size, frame->data(VideoFrame::kAPlane), @@ -126,8 +126,8 @@ frame->stride(VideoFrame::kAPlane), alpha_dummy_planes_.data(), SafeCast<int>(u_plane_stride_), alpha_dummy_planes_.data() + v_plane_offset_, - SafeCast<int>(v_plane_stride_), duration, keyframe, - alpha_data.get(), &alpha_keyframe); + SafeCast<int>(v_plane_stride_), duration, keyframe, alpha_data, + &alpha_keyframe); DCHECK_EQ(keyframe, alpha_keyframe); } frame = nullptr; @@ -152,7 +152,7 @@ int v_stride, const base::TimeDelta& duration, bool force_keyframe, - std::string* const output_data, + std::string& output_data, bool* const keyframe) { DCHECK(encoding_task_runner_->BelongsToCurrentThread()); @@ -186,8 +186,8 @@ while ((pkt = vpx_codec_get_cx_data(encoder, &iter))) { if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) continue; - output_data->assign(static_cast<char*>(pkt->data.frame.buf), - pkt->data.frame.sz); + output_data.assign(static_cast<char*>(pkt->data.frame.buf), + pkt->data.frame.sz); *keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0; break; }
diff --git a/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.h b/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.h index 07a0f2d..24c472f 100644 --- a/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.h +++ b/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.h
@@ -55,7 +55,7 @@ int v_stride, const base::TimeDelta& duration, bool force_keyframe, - std::string* const output_data, + std::string& output_data, bool* const keyframe); // Returns true if |codec_config| has been filled in at least once.
diff --git a/third_party/blink/renderer/modules/nfc/nfc.idl b/third_party/blink/renderer/modules/nfc/nfc.idl index 4274711c..9876547d 100644 --- a/third_party/blink/renderer/modules/nfc/nfc.idl +++ b/third_party/blink/renderer/modules/nfc/nfc.idl
@@ -9,8 +9,8 @@ // https://w3c.github.io/web-nfc/#the-nfc-interface [ - RuntimeEnabled=WebNFC, - SecureContext + RuntimeEnabled=WebNFC, + SecureContext ] interface NFC { [CallWith=ScriptState, MeasureAs=WebNFCPush] Promise<void> push (NDEFMessageSource message, optional NFCPushOptions options); [CallWith=ScriptState, MeasureAs=WebNFCCancelPush] Promise<void> cancelPush (optional NFCPushTarget target = "any");
diff --git a/third_party/blink/renderer/modules/nfc/nfc_proxy.cc b/third_party/blink/renderer/modules/nfc/nfc_proxy.cc index 1a8bbb1..d25b488 100644 --- a/third_party/blink/renderer/modules/nfc/nfc_proxy.cc +++ b/third_party/blink/renderer/modules/nfc/nfc_proxy.cc
@@ -8,6 +8,7 @@ #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/renderer/modules/nfc/nfc_reader.h" +#include "third_party/blink/renderer/modules/nfc/nfc_utils.h" #include "third_party/blink/renderer/modules/nfc/nfc_writer.h" #include "third_party/blink/renderer/platform/mojo/mojo_helper.h" @@ -64,6 +65,7 @@ void NFCProxy::RemoveReader(NFCReader* reader) { auto iter = readers_.find(reader); if (iter != readers_.end()) { + DCHECK(nfc_); nfc_->CancelWatch(iter->value, WTF::Bind(&NFCProxy::OnCancelWatch, WrapPersistent(this), WrapPersistent(reader))); @@ -83,6 +85,13 @@ nfc_->Push(std::move(message), std::move(options), std::move(cb)); } +void NFCProxy::CancelPush( + const String& target, + device::mojom::blink::NFC::CancelPushCallback callback) { + DCHECK(nfc_); + nfc_->CancelPush(StringToNFCPushTarget(target), std::move(callback)); +} + void NFCProxy::PageVisibilityChanged() { // If service is not initialized, there cannot be any pending NFC activities if (!nfc_)
diff --git a/third_party/blink/renderer/modules/nfc/nfc_proxy.h b/third_party/blink/renderer/modules/nfc/nfc_proxy.h index 2fec61a..adad2b9 100644 --- a/third_party/blink/renderer/modules/nfc/nfc_proxy.h +++ b/third_party/blink/renderer/modules/nfc/nfc_proxy.h
@@ -49,6 +49,8 @@ void Push(device::mojom::blink::NDEFMessagePtr message, device::mojom::blink::NFCPushOptionsPtr options, device::mojom::blink::NFC::PushCallback cb); + void CancelPush(const String& target, + device::mojom::blink::NFC::CancelPushCallback callback); // Implementation of PageVisibilityObserver. void PageVisibilityChanged() override;
diff --git a/third_party/blink/renderer/modules/nfc/nfc_push_options.idl b/third_party/blink/renderer/modules/nfc/nfc_push_options.idl index 637eb64f..39da64f 100644 --- a/third_party/blink/renderer/modules/nfc/nfc_push_options.idl +++ b/third_party/blink/renderer/modules/nfc/nfc_push_options.idl
@@ -10,5 +10,6 @@ NFCPushTarget target = "any"; unrestricted double timeout; // in ms boolean ignoreRead = true; + AbortSignal? signal; NDEFCompatibility compatibility = "nfc-forum"; };
diff --git a/third_party/blink/renderer/modules/nfc/nfc_writer.cc b/third_party/blink/renderer/modules/nfc/nfc_writer.cc index dcbfd8da..275d190 100644 --- a/third_party/blink/renderer/modules/nfc/nfc_writer.cc +++ b/third_party/blink/renderer/modules/nfc/nfc_writer.cc
@@ -8,6 +8,7 @@ #include "mojo/public/cpp/bindings/callback_helpers.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/modules/nfc/nfc_error.h" #include "third_party/blink/renderer/modules/nfc/nfc_push_options.h" @@ -31,7 +32,7 @@ } // https://w3c.github.io/web-nfc/#writing-or-pushing-content -// https://w3c.github.io/web-nfc/#dom-nfc-push +// https://w3c.github.io/web-nfc/#the-push-method ScriptPromise NFCWriter::push(ScriptState* script_state, const NDEFMessageSource& push_message, const NFCPushOptions* options) { @@ -45,12 +46,19 @@ kNfcAccessInNonTopFrame)); } + if (options->hasSignal() && options->signal()->aborted()) { + // If signal’s aborted flag is set, then reject p with an "AbortError" + // DOMException and return p. + return ScriptPromise::RejectWithDOMException( + script_state, MakeGarbageCollected<DOMException>( + DOMExceptionCode::kAbortError, kNfcCancelled)); + } + ScriptPromise is_valid_message = RejectIfInvalidNDEFMessageSource(script_state, push_message); if (!is_valid_message.IsEmpty()) return is_valid_message; - // https://w3c.github.io/web-nfc/#dom-nfc-push // 9. If timeout value is NaN or negative, reject promise with "TypeError" // and abort these steps. if (options->hasTimeout() && @@ -84,10 +92,17 @@ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); requests_.insert(resolver); + InitNfcProxyIfNeeded(); + + // If signal is not null, then add the abort steps to signal. + if (options->hasSignal() && !options->signal()->aborted()) { + options->signal()->AddAlgorithm( + WTF::Bind(&NFCWriter::Abort, WrapPersistent(this), options->target(), + WrapPersistent(resolver))); + } + auto callback = WTF::Bind(&NFCWriter::OnRequestCompleted, WrapPersistent(this), WrapPersistent(resolver)); - - InitNfcProxyIfNeeded(); nfc_proxy_->Push(std::move(message), device::mojom::blink::NFCPushOptions::From(options), std::move(callback)); @@ -120,9 +135,22 @@ nfc_proxy_->AddWriter(this); } +void NFCWriter::Abort(const String& target, ScriptPromiseResolver* resolver) { + // |nfc_proxy_| could be null on Mojo connection failure, simply ignore the + // abort request in this case. + if (!nfc_proxy_) + return; + + // OnRequestCompleted() should always be called whether the push operation is + // cancelled successfully or not. So do nothing for the cancelled callback. + nfc_proxy_->CancelPush(target, + device::mojom::blink::NFC::CancelPushCallback()); +} + void NFCWriter::OnRequestCompleted(ScriptPromiseResolver* resolver, device::mojom::blink::NFCErrorPtr error) { DCHECK(requests_.Contains(resolver)); + requests_.erase(resolver); if (error.is_null())
diff --git a/third_party/blink/renderer/modules/nfc/nfc_writer.h b/third_party/blink/renderer/modules/nfc/nfc_writer.h index 915ec8a..d385b06 100644 --- a/third_party/blink/renderer/modules/nfc/nfc_writer.h +++ b/third_party/blink/renderer/modules/nfc/nfc_writer.h
@@ -40,6 +40,7 @@ private: void InitNfcProxyIfNeeded(); + void Abort(const String& target, ScriptPromiseResolver* resolver); void OnRequestCompleted(ScriptPromiseResolver* resolver, device::mojom::blink::NFCErrorPtr error);
diff --git a/third_party/blink/renderer/modules/nfc/nfc_writer.idl b/third_party/blink/renderer/modules/nfc/nfc_writer.idl index 954fabc..a594cbe 100644 --- a/third_party/blink/renderer/modules/nfc/nfc_writer.idl +++ b/third_party/blink/renderer/modules/nfc/nfc_writer.idl
@@ -1,11 +1,15 @@ -typedef (DOMString or ArrayBuffer or NDEFMessage) NDEFMessageSource; +// 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. + +// https://w3c.github.io/web-nfc/#the-nfcreader-and-nfcwriter-objects [ - RuntimeEnabled=WebNFC, - SecureContext, - Constructor(), - ConstructorCallWith=ExecutionContext, - Exposed=Window + RuntimeEnabled=WebNFC, + SecureContext, + Constructor(), + ConstructorCallWith=ExecutionContext, + Exposed=Window ] interface NFCWriter { - [CallWith=ScriptState] Promise<void> push (NDEFMessageSource message, optional NFCPushOptions options); -}; \ No newline at end of file + [CallWith=ScriptState] Promise<void> push (NDEFMessageSource message, optional NFCPushOptions options); +};
diff --git a/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h index 470f56aa..39a3bc8 100644 --- a/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h +++ b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h
@@ -5,11 +5,11 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_CALL_SETUP_STATE_TRACKER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_CALL_SETUP_STATE_TRACKER_H_ -#include <set> #include <utility> #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" namespace blink { @@ -117,9 +117,9 @@ bool NoteAnswererStateEvent(AnswererState event, bool document_uses_media); private: - const std::set<std::pair<OffererState, OffererState>> + const HashSet<std::pair<OffererState, OffererState>> valid_offerer_transitions_; - const std::set<std::pair<AnswererState, AnswererState>> + const HashSet<std::pair<AnswererState, AnswererState>> valid_answerer_transitions_; OffererState offerer_state_;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index e8a6a17..602122b 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -32,7 +32,6 @@ #include <algorithm> #include <memory> -#include <set> #include <string> #include <utility> @@ -1066,8 +1065,9 @@ } } -std::set<RTCIceTransport*> RTCPeerConnection::ActiveIceTransports() const { - std::set<RTCIceTransport*> active_transports; +HeapHashSet<Member<RTCIceTransport>> RTCPeerConnection::ActiveIceTransports() + const { + HeapHashSet<Member<RTCIceTransport>> active_transports; for (auto transceiver : transceivers_) { auto* sender = transceiver->sender(); if (sender) { @@ -3097,7 +3097,7 @@ } bool RTCPeerConnection::HasAnyFailedIceTransport() const { - for (auto* transport : ActiveIceTransports()) { + for (auto& transport : ActiveIceTransports()) { if (transport->GetState() == webrtc::IceTransportState::kFailed) return true; } @@ -3105,7 +3105,7 @@ } bool RTCPeerConnection::HasAnyDisconnectedIceTransport() const { - for (auto* transport : ActiveIceTransports()) { + for (auto& transport : ActiveIceTransports()) { if (transport->GetState() == webrtc::IceTransportState::kDisconnected) return true; } @@ -3113,7 +3113,7 @@ } bool RTCPeerConnection::HasAllNewOrClosedIceTransports() const { - for (auto* transport : ActiveIceTransports()) { + for (auto& transport : ActiveIceTransports()) { if (transport->GetState() != webrtc::IceTransportState::kNew && transport->GetState() != webrtc::IceTransportState::kClosed) return false; @@ -3122,7 +3122,7 @@ } bool RTCPeerConnection::HasAnyNewOrCheckingIceTransport() const { - for (auto* transport : ActiveIceTransports()) { + for (auto& transport : ActiveIceTransports()) { if (transport->GetState() == webrtc::IceTransportState::kNew || transport->GetState() == webrtc::IceTransportState::kChecking) return true; @@ -3131,7 +3131,7 @@ } bool RTCPeerConnection::HasAllCompletedOrClosedIceTransports() const { - for (auto* transport : ActiveIceTransports()) { + for (auto& transport : ActiveIceTransports()) { if (transport->GetState() != webrtc::IceTransportState::kCompleted && transport->GetState() != webrtc::IceTransportState::kClosed) return false; @@ -3140,7 +3140,7 @@ } bool RTCPeerConnection::HasAllConnectedCompletedOrClosedIceTransports() const { - for (auto* transport : ActiveIceTransports()) { + for (auto& transport : ActiveIceTransports()) { if (transport->GetState() != webrtc::IceTransportState::kConnected && transport->GetState() != webrtc::IceTransportState::kCompleted && transport->GetState() != webrtc::IceTransportState::kClosed)
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h index 82d36814..3557fca 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
@@ -54,6 +54,7 @@ #include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { @@ -495,7 +496,7 @@ void MaybeWarnAboutUnsafeSdp( const RTCSessionDescriptionInit* session_description_init) const; - std::set<RTCIceTransport*> ActiveIceTransports() const; + HeapHashSet<Member<RTCIceTransport>> ActiveIceTransports() const; webrtc::PeerConnectionInterface::SignalingState signaling_state_; webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state_;
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_container.cc b/third_party/blink/renderer/modules/service_worker/service_worker_container.cc index d3680865..a12ea0d 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_container.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
@@ -599,11 +599,11 @@ void ServiceWorkerContainer::EnableClientMessageQueue() { dom_content_loaded_observer_ = nullptr; if (is_client_message_queue_enabled_) { - DCHECK(queued_messages_.empty()); + DCHECK(queued_messages_.IsEmpty()); return; } is_client_message_queue_enabled_ = true; - std::vector<std::unique_ptr<MessageFromServiceWorker>> messages; + Vector<std::unique_ptr<MessageFromServiceWorker>> messages; messages.swap(queued_messages_); for (auto& message : messages) { DispatchMessageEvent(std::move(message->source),
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_container.h b/third_party/blink/renderer/modules/service_worker/service_worker_container.h index 817fc4e..168f1dd 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_container.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_container.h
@@ -32,7 +32,6 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_CONTAINER_H_ #include <memory> -#include <vector> #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom-blink.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h" @@ -50,6 +49,7 @@ #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/forward.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { @@ -157,7 +157,7 @@ // queue using this flag since the task runner is shared with other task // sources. bool is_client_message_queue_enabled_ = false; - std::vector<std::unique_ptr<MessageFromServiceWorker>> queued_messages_; + Vector<std::unique_ptr<MessageFromServiceWorker>> queued_messages_; Member<DomContentLoadedListener> dom_content_loaded_observer_; };
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc b/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc index adf4c22..a2975e4 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc
@@ -57,12 +57,12 @@ manager_->TransferInstalledScript(std::move(script_info)); } - void PushBody(const std::string& data) { - PushDataPipe(data, body_handle_.get()); + void PushBody(const String& data) { + PushDataPipe(data.Utf8(), body_handle_.get()); } - void PushMetaData(const std::string& data) { - PushDataPipe(data, meta_data_handle_.get()); + void PushMetaData(const String& data) { + PushDataPipe(data.Utf8(), meta_data_handle_.get()); } void FinishTransferBody() { body_handle_.reset(); } @@ -221,8 +221,8 @@ { std::unique_ptr<RawScriptData> script_data; - const std::string kExpectedBody = "This is a script body."; - const std::string kExpectedMetaData = "This is a meta data."; + const String kExpectedBody = "This is a script body."; + const String kExpectedMetaData = "This is a meta data."; const String kScriptInfoEncoding("utf8"); const HashMap<String, String> kScriptInfoHeaders( {{"Cache-Control", "no-cache"}, {"User-Agent", "Chrome"}}); @@ -231,9 +231,9 @@ GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data); // Start transferring the script. +1 for null terminator. - sender.TransferInstalledScript(kScriptUrl, kScriptInfoEncoding, - kScriptInfoHeaders, kExpectedBody.size() + 1, - kExpectedMetaData.size() + 1); + sender.TransferInstalledScript( + kScriptUrl, kScriptInfoEncoding, kScriptInfoHeaders, + kExpectedBody.length() + 1, kExpectedMetaData.length() + 1); sender.PushBody(kExpectedBody); sender.PushMetaData(kExpectedMetaData); // GetRawScriptData should be blocked until body and meta data transfer are @@ -247,12 +247,12 @@ EXPECT_TRUE(script_data); Vector<uint8_t> script_text = script_data->TakeScriptText(); Vector<uint8_t> meta_data = script_data->TakeMetaData(); - ASSERT_EQ(kExpectedBody.size() + 1, script_text.size()); - EXPECT_STREQ(kExpectedBody.data(), - reinterpret_cast<const char*>(script_text.data())); - ASSERT_EQ(kExpectedMetaData.size() + 1, meta_data.size()); - EXPECT_STREQ(kExpectedMetaData.data(), - reinterpret_cast<const char*>(meta_data.data())); + ASSERT_EQ(kExpectedBody.length() + 1, script_text.size()); + EXPECT_EQ(kExpectedBody, + String(reinterpret_cast<const char*>(script_text.data()))); + ASSERT_EQ(kExpectedMetaData.length() + 1, meta_data.size()); + EXPECT_EQ(kExpectedMetaData, + String(reinterpret_cast<const char*>(meta_data.data()))); EXPECT_EQ(kScriptInfoEncoding, script_data->Encoding()); EXPECT_EQ(ToCrossThreadHTTPHeaderMapData(kScriptInfoHeaders), *(script_data->TakeHeaders())); @@ -260,8 +260,8 @@ { std::unique_ptr<RawScriptData> script_data; - const std::string kExpectedBody = "This is another script body."; - const std::string kExpectedMetaData = "This is another meta data."; + const String kExpectedBody = "This is another script body."; + const String kExpectedMetaData = "This is another meta data."; const String kScriptInfoEncoding("ASCII"); const HashMap<String, String> kScriptInfoHeaders( {{"Connection", "keep-alive"}, {"Content-Length", "512"}}); @@ -274,9 +274,9 @@ sender.WaitForRequestInstalledScript(kScriptUrl); // Start transferring the script. +1 for null terminator. - sender.TransferInstalledScript(kScriptUrl, kScriptInfoEncoding, - kScriptInfoHeaders, kExpectedBody.size() + 1, - kExpectedMetaData.size() + 1); + sender.TransferInstalledScript( + kScriptUrl, kScriptInfoEncoding, kScriptInfoHeaders, + kExpectedBody.length() + 1, kExpectedMetaData.length() + 1); sender.PushBody(kExpectedBody); sender.PushMetaData(kExpectedMetaData); // GetRawScriptData should be blocked until body and meta data transfer are @@ -290,12 +290,12 @@ EXPECT_TRUE(script_data); Vector<uint8_t> script_text = script_data->TakeScriptText(); Vector<uint8_t> meta_data = script_data->TakeMetaData(); - ASSERT_EQ(kExpectedBody.size() + 1, script_text.size()); - EXPECT_STREQ(kExpectedBody.data(), - reinterpret_cast<const char*>(script_text.data())); - ASSERT_EQ(kExpectedMetaData.size() + 1, meta_data.size()); - EXPECT_STREQ(kExpectedMetaData.data(), - reinterpret_cast<const char*>(meta_data.data())); + ASSERT_EQ(kExpectedBody.length() + 1, script_text.size()); + EXPECT_EQ(kExpectedBody, + String(reinterpret_cast<const char*>(script_text.data()))); + ASSERT_EQ(kExpectedMetaData.length() + 1, meta_data.size()); + EXPECT_EQ(kExpectedMetaData, + String(reinterpret_cast<const char*>(meta_data.data()))); EXPECT_EQ(kScriptInfoEncoding, script_data->Encoding()); EXPECT_EQ(ToCrossThreadHTTPHeaderMapData(kScriptInfoHeaders), *(script_data->TakeHeaders())); @@ -311,18 +311,18 @@ { std::unique_ptr<RawScriptData> script_data; - const std::string kExpectedBody = "This is a script body."; - const std::string kExpectedMetaData = "This is a meta data."; + const String kExpectedBody = "This is a script body."; + const String kExpectedMetaData = "This is a meta data."; base::WaitableEvent* get_raw_script_data_waiter = GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data); // Start transferring the script. // Body is expected to be 100 bytes larger than kExpectedBody, but sender - // only sends kExpectedBody and a null byte (kExpectedBody.size() + 1 bytes - // in total). + // only sends kExpectedBody and a null byte (kExpectedBody.length() + 1 + // bytes in total). sender.TransferInstalledScript( kScriptUrl, String::FromUTF8("utf8"), HashMap<String, String>(), - kExpectedBody.size() + 100, kExpectedMetaData.size() + 1); + kExpectedBody.length() + 100, kExpectedMetaData.length() + 1); sender.PushBody(kExpectedBody); sender.PushMetaData(kExpectedMetaData); // GetRawScriptData should be blocked until body and meta data transfer are @@ -356,18 +356,18 @@ { std::unique_ptr<RawScriptData> script_data; - const std::string kExpectedBody = "This is a script body."; - const std::string kExpectedMetaData = "This is a meta data."; + const String kExpectedBody = "This is a script body."; + const String kExpectedMetaData = "This is a meta data."; base::WaitableEvent* get_raw_script_data_waiter = GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data); // Start transferring the script. // Meta data is expected to be 100 bytes larger than kExpectedMetaData, but // sender only sends kExpectedMetaData and a null byte - // (kExpectedMetaData.size() + 1 bytes in total). + // (kExpectedMetaData.length() + 1 bytes in total). sender.TransferInstalledScript( kScriptUrl, String::FromUTF8("utf8"), HashMap<String, String>(), - kExpectedBody.size() + 1, kExpectedMetaData.size() + 100); + kExpectedBody.length() + 1, kExpectedMetaData.length() + 100); sender.PushBody(kExpectedBody); sender.PushMetaData(kExpectedMetaData); // GetRawScriptData should be blocked until body and meta data transfer are
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer_test.cc b/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer_test.cc index 93b7edb..185a6eed 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer_test.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer_test.cc
@@ -48,13 +48,12 @@ WTF::Unretained(out_is_called)); } -base::OnceClosure CreateDispatchingEventTask( - ServiceWorkerTimeoutTimer* timer, - std::string tag, - std::vector<std::string>* out_tags) { +base::OnceClosure CreateDispatchingEventTask(ServiceWorkerTimeoutTimer* timer, + String tag, + Vector<String>* out_tags) { return WTF::Bind( - [](ServiceWorkerTimeoutTimer* timer, std::string tag, - std::vector<std::string>* out_tags) { + [](ServiceWorkerTimeoutTimer* timer, String tag, + Vector<String>* out_tags) { // Event dispatched inside of pending task should run successfully. MockEvent event; const int event_id = timer->StartEvent(event.CreateAbortCallback()); @@ -332,7 +331,7 @@ timer.SetIdleTimerDelayToZero(); EXPECT_TRUE(timer.did_idle_timeout()); - std::vector<std::string> handled_tasks; + Vector<String> handled_tasks; timer.PushPendingTask( CreateDispatchingEventTask(&timer, "1", &handled_tasks)); timer.PushPendingTask(
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc index b37f9c3..133cfbe 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
@@ -170,10 +170,10 @@ using_gpu_compositing, requested_attributes, context_type) { - supported_internal_formats_storage_.insert( - kSupportedInternalFormatsStorage, - kSupportedInternalFormatsStorage + - base::size(kSupportedInternalFormatsStorage)); + for (size_t i = 0; i < base::size(kSupportedInternalFormatsStorage); ++i) { + supported_internal_formats_storage_.insert( + kSupportedInternalFormatsStorage[i]); + } } void WebGL2RenderingContextBase::DestroyContext() {
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h index 54b02ee..c971693 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h
@@ -1120,8 +1120,8 @@ // Member rather than Member. Member<WebGLTransformFeedback> default_transform_feedback_; - std::set<GLenum> supported_internal_formats_storage_; - std::set<GLenum> compressed_texture_formats_etc2eac_; + GLenumHashSet supported_internal_formats_storage_; + GLenumHashSet compressed_texture_formats_etc2eac_; Member<WebGLBuffer> bound_copy_read_buffer_; Member<WebGLBuffer> bound_copy_write_buffer_;
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h index b18c1c76..6fd2248 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -27,7 +27,6 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_RENDERING_CONTEXT_BASE_H_ #include <memory> -#include <set> #include "base/containers/mru_cache.h" #include "base/macros.h" @@ -106,6 +105,10 @@ class WebGLRenderingContextErrorMessageCallback; +using GLenumHashSet = HashSet<GLenum, + WTF::AlreadyHashed, + WTF::UnsignedWithZeroKeyHashTraits<GLenum>>; + // This class uses the color mask to prevent drawing to the alpha channel, if // the DrawingBuffer requires RGB emulation. class ScopedRGBEmulationColorMask { @@ -1001,13 +1004,13 @@ bool is_ext_srgb_formats_types_added_ = false; bool is_ext_color_buffer_float_formats_added_ = false; - std::set<GLenum> supported_internal_formats_; - std::set<GLenum> supported_tex_image_source_internal_formats_; - std::set<GLenum> supported_internal_formats_copy_tex_image_; - std::set<GLenum> supported_formats_; - std::set<GLenum> supported_tex_image_source_formats_; - std::set<GLenum> supported_types_; - std::set<GLenum> supported_tex_image_source_types_; + GLenumHashSet supported_internal_formats_; + GLenumHashSet supported_tex_image_source_internal_formats_; + GLenumHashSet supported_internal_formats_copy_tex_image_; + GLenumHashSet supported_formats_; + GLenumHashSet supported_tex_image_source_formats_; + GLenumHashSet supported_types_; + GLenumHashSet supported_tex_image_source_types_; // Helpers for getParameter and others ScriptValue GetBooleanParameter(ScriptState*, GLenum);
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc index 7eef7d8..b52c5a76 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -36,6 +36,7 @@ #include "base/memory/ptr_util.h" #include "mojo/public/cpp/bindings/interface_request.h" #include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/mojom/websockets/websocket_connector.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/web_url.h" @@ -206,10 +207,7 @@ DCHECK(!blob_loader_); } -bool WebSocketChannelImpl::Connect( - const KURL& url, - const String& protocol, - network::mojom::blink::WebSocketPtr socket_ptr) { +bool WebSocketChannelImpl::Connect(const KURL& url, const String& protocol) { NETWORK_DVLOG(1) << this << " Connect()"; if (!handle_) return false; @@ -255,8 +253,17 @@ return true; } + mojom::blink::WebSocketConnectorPtr connector; + if (execution_context_->GetInterfaceProvider()) { + execution_context_->GetInterfaceProvider()->GetInterface(mojo::MakeRequest( + &connector, execution_context_->GetTaskRunner(TaskType::kWebSocket))); + } else { + // Create a fake request. This will lead to a closed WebSocket due to + // a mojo connection error. + mojo::MakeRequest(&connector); + } handle_->Connect( - std::move(socket_ptr), url, protocols, + std::move(connector), url, protocols, GetBaseFetchContext()->GetSiteForCookies(), execution_context_->UserAgent(), this, execution_context_->GetTaskRunner(TaskType::kNetworking).get()); @@ -281,17 +288,6 @@ return true; } -bool WebSocketChannelImpl::Connect(const KURL& url, const String& protocol) { - network::mojom::blink::WebSocketPtr socket_ptr; - auto socket_request = mojo::MakeRequest( - &socket_ptr, execution_context_->GetTaskRunner(TaskType::kWebSocket)); - service_manager::InterfaceProvider* interface_provider = - execution_context_->GetInterfaceProvider(); - if (interface_provider) - interface_provider->GetInterface(std::move(socket_request)); - return Connect(url, protocol, std::move(socket_ptr)); -} - void WebSocketChannelImpl::Send(const std::string& message) { NETWORK_DVLOG(1) << this << " Send(" << message << ") (std::string argument)"; probe::DidSendWebSocketMessage(execution_context_, identifier_,
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc index e9330ebc..3fa651f8 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc
@@ -82,7 +82,7 @@ ~MockWebSocketHandle() override = default; - void Connect(network::mojom::blink::WebSocketPtr websocket, + void Connect(blink::mojom::blink::WebSocketConnectorPtr connector, const KURL& url, const Vector<String>& protocols, const KURL& site_for_cookies,
diff --git a/third_party/blink/renderer/modules/websockets/websocket_handle.h b/third_party/blink/renderer/modules/websockets/websocket_handle.h index bd574b8..c7c1aee 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_handle.h +++ b/third_party/blink/renderer/modules/websockets/websocket_handle.h
@@ -34,6 +34,7 @@ #include <stdint.h> #include "base/single_thread_task_runner.h" #include "services/network/public/mojom/websocket.mojom-blink.h" +#include "third_party/blink/public/mojom/websockets/websocket_connector.mojom-blink.h" #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" @@ -60,7 +61,7 @@ virtual ~WebSocketHandle() = default; - virtual void Connect(network::mojom::blink::WebSocketPtr, + virtual void Connect(mojom::blink::WebSocketConnectorPtr, const KURL&, const Vector<String>& protocols, const KURL& site_for_cookies,
diff --git a/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc index 82fa18ed..99bb582 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_handle_impl.cc
@@ -35,19 +35,13 @@ websocket_->StartClosingHandshake(kAbnormalShutdownOpCode, g_empty_string); } -void WebSocketHandleImpl::Connect(network::mojom::blink::WebSocketPtr websocket, +void WebSocketHandleImpl::Connect(mojom::blink::WebSocketConnectorPtr connector, const KURL& url, const Vector<String>& protocols, const KURL& site_for_cookies, const String& user_agent_override, WebSocketChannelImpl* channel, base::SingleThreadTaskRunner* task_runner) { - DCHECK(!websocket_); - websocket_ = std::move(websocket); - // We intentionally ignore errors on |websocket_| in favour of catching them - // on |client_binding_|, which gives more reliable ordering semantics. - DCHECK(websocket_); - NETWORK_DVLOG(1) << this << " connect(" << url.GetString() << ")"; DCHECK(!channel_); @@ -56,10 +50,6 @@ network::mojom::blink::WebSocketHandshakeClientPtr handshake_client_proxy; Vector<network::mojom::blink::HttpHeaderPtr> additional_headers; - if (!user_agent_override.IsNull()) { - additional_headers.push_back(network::mojom::blink::HttpHeader::New( - http_names::kUserAgent, user_agent_override)); - } handshake_client_binding_.Bind( mojo::MakeRequest(&handshake_client_proxy, task_runner), task_runner); network::mojom::blink::WebSocketClientPtr client_proxy; @@ -68,9 +58,9 @@ client_binding_.set_connection_error_with_reason_handler(WTF::Bind( &WebSocketHandleImpl::OnConnectionError, WTF::Unretained(this))); - websocket_->AddChannelRequest( - url, protocols, site_for_cookies, std::move(additional_headers), - std::move(handshake_client_proxy), std::move(client_proxy)); + connector->Connect(url, protocols, site_for_cookies, user_agent_override, + std::move(handshake_client_proxy), + std::move(client_proxy)); } void WebSocketHandleImpl::Send(bool fin, @@ -167,6 +157,7 @@ } void WebSocketHandleImpl::OnConnectionEstablished( + network::mojom::blink::WebSocketPtr websocket, const String& protocol, const String& extensions, uint64_t receive_quota_threshold) { @@ -176,6 +167,8 @@ if (!channel_) return; + DCHECK(!websocket_); + websocket_ = std::move(websocket); channel_->DidConnect(this, protocol, extensions, receive_quota_threshold); // |this| can be deleted here. }
diff --git a/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h b/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h index 995f57b..dce31cda 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h +++ b/third_party/blink/renderer/modules/websockets/websocket_handle_impl.h
@@ -33,6 +33,7 @@ #include "mojo/public/cpp/bindings/binding.h" #include "services/network/public/mojom/websocket.mojom-blink.h" +#include "third_party/blink/public/mojom/websockets/websocket_connector.mojom-blink.h" #include "third_party/blink/renderer/modules/websockets/websocket_handle.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" @@ -47,7 +48,7 @@ WebSocketHandleImpl(); ~WebSocketHandleImpl() override; - void Connect(network::mojom::blink::WebSocketPtr, + void Connect(mojom::blink::WebSocketConnectorPtr, const KURL&, const Vector<String>& protocols, const KURL& site_for_cookies, @@ -68,7 +69,8 @@ network::mojom::blink::WebSocketHandshakeRequestPtr) override; void OnResponseReceived( network::mojom::blink::WebSocketHandshakeResponsePtr) override; - void OnConnectionEstablished(const String& selected_protocol, + void OnConnectionEstablished(network::mojom::blink::WebSocketPtr websocket, + const String& selected_protocol, const String& extensions, uint64_t receive_quota_threshold) override; // network::mojom::blink::WebSocketClient methods:
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string.h b/third_party/blink/renderer/platform/bindings/parkable_string.h index 4b68ce3..8e33ddfe 100644 --- a/third_party/blink/renderer/platform/bindings/parkable_string.h +++ b/third_party/blink/renderer/platform/bindings/parkable_string.h
@@ -7,7 +7,6 @@ #include <map> #include <memory> -#include <set> #include <utility> #include "base/gtest_prod_util.h"
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index c162d66..c5cebd31 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -520,6 +520,10 @@ SetRestrictAutomaticLazyImageLoadingToDataSaverEnabled(enable); } +void WebRuntimeFeatures::EnableLazyImageLoadingMetadataFetch(bool enable) { + RuntimeEnabledFeatures::SetLazyImageLoadingMetadataFetchEnabled(enable); +} + void WebRuntimeFeatures::EnableExpensiveBackgroundTimerThrottling(bool enable) { RuntimeEnabledFeatures::SetExpensiveBackgroundTimerThrottlingEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/exported/web_url_response.cc b/third_party/blink/renderer/platform/exported/web_url_response.cc index 1324bc8..e7de3a6 100644 --- a/third_party/blink/renderer/platform/exported/web_url_response.cc +++ b/third_party/blink/renderer/platform/exported/web_url_response.cc
@@ -278,9 +278,9 @@ resource_response_->GetSecurityDetails(); if (!security_details.has_value()) return base::nullopt; - std::vector<SignedCertificateTimestamp> sct_list; + SignedCertificateTimestampList sct_list; for (const auto& iter : security_details->sct_list) { - sct_list.push_back(SignedCertificateTimestamp( + sct_list.emplace_back(SignedCertificateTimestamp( iter.status_, iter.origin_, iter.log_description_, iter.log_id_, iter.timestamp_, iter.hash_algorithm_, iter.signature_algorithm_, iter.signature_data_)); @@ -291,7 +291,7 @@ security_details->mac, security_details->subject_name, security_details->san_list, security_details->issuer, security_details->valid_from, security_details->valid_to, - security_details->certificate, SignedCertificateTimestampList(sct_list)); + security_details->certificate, sct_list); } const ResourceResponse& WebURLResponse::ToResourceResponse() const {
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc index 945a3f3..3dab0c0b 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -806,45 +806,43 @@ const TransformPaintPropertyNode* transform_node) { DCHECK(transform_node); while (transform_node && !transform_node->IsRoot()) { - if (!can_be_decomposited.Contains(transform_node)) { - can_be_decomposited.insert(transform_node, false); - } else { - if (!can_be_decomposited.at(transform_node)) + auto result = can_be_decomposited.insert(transform_node, false); + if (!result.is_new_entry) { + if (!result.stored_value->value) break; - can_be_decomposited.Set(transform_node, false); + result.stored_value->value = false; } - transform_node = SafeUnalias(transform_node->Parent()); + transform_node = &transform_node->Parent()->Unalias(); } }; // Add the transform and all transform parents to the map. for (const auto* node = &property_state.Transform().Unalias(); - node && !can_be_decomposited.Contains(node); - node = SafeUnalias(node->Parent())) { - can_be_decomposited.insert(node, !node->IsRoot()); + !node->IsRoot() && !can_be_decomposited.Contains(node); + node = &node->Parent()->Unalias()) { if (!node->IsIdentityOr2DTranslation() || node->ScrollNode() || node->IsAffectedByOuterViewportBoundsDelta() || node->HasDirectCompositingReasonsOtherThan3dTransform() || !node->FlattensInheritedTransformSameAsParent() || !node->BackfaceVisibilitySameAsParent()) { mark_not_decompositable(node); + break; } + can_be_decomposited.insert(node, true); } // Add clips and effects, and their parents, that we haven't already seen. for (const auto* node = &property_state.Clip().Unalias(); - node && !clips_and_effects_seen.Contains(node); - node = SafeUnalias(node->Parent())) { + !node->IsRoot() && !clips_and_effects_seen.Contains(node); + node = &node->Parent()->Unalias()) { clips_and_effects_seen.insert(node); - if (!node->IsRoot()) - mark_not_decompositable(&node->LocalTransformSpace()); + mark_not_decompositable(&node->LocalTransformSpace()); } for (const auto* node = &property_state.Effect().Unalias(); - node && !clips_and_effects_seen.Contains(node); - node = SafeUnalias(node->Parent())) { + !node->IsRoot() && !clips_and_effects_seen.Contains(node); + node = &node->Parent()->Unalias()) { clips_and_effects_seen.insert(node); - if (!node->IsRoot()) - mark_not_decompositable(&node->LocalTransformSpace()); + mark_not_decompositable(&node->LocalTransformSpace()); } if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.cc b/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.cc index fd84adc0..e304b38 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.cc +++ b/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.cc
@@ -63,6 +63,24 @@ int brightness_threshold_; }; +class InvertHighBrightnessColorsClassifier : public DarkModeColorClassifier { + public: + InvertHighBrightnessColorsClassifier(int brightness_threshold) + : brightness_threshold_(brightness_threshold) { + DCHECK_GT(brightness_threshold_, 0); + DCHECK_LT(brightness_threshold_, 256); + } + + DarkModeClassification ShouldInvertColor(const Color& color) override { + if (CalculateColorBrightness(color) > brightness_threshold_) + return DarkModeClassification::kApplyFilter; + return DarkModeClassification::kDoNotApplyFilter; + } + + private: + int brightness_threshold_; +}; + } // namespace // Values below which a color is considered sufficiently transparent that a @@ -103,6 +121,23 @@ settings.text_brightness_threshold); } +std::unique_ptr<DarkModeColorClassifier> +DarkModeColorClassifier::MakeBackgroundColorClassifier( + const DarkModeSettings& settings) { + DCHECK_LE(settings.background_brightness_threshold, 256); + DCHECK_GE(settings.background_brightness_threshold, 0); + + // The value should be between 0 and 256, but check for values outside that + // range here to preserve correct behavior in non-debug builds. + if (settings.background_brightness_threshold >= 256) + return SimpleColorClassifier::NeverInvert(); + if (settings.background_brightness_threshold <= 0) + return SimpleColorClassifier::AlwaysInvert(); + + return std::make_unique<InvertHighBrightnessColorsClassifier>( + settings.background_brightness_threshold); +} + DarkModeColorClassifier::~DarkModeColorClassifier() {} } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h b/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h index d4e2f73..894fd498 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h +++ b/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h
@@ -18,10 +18,10 @@ class PLATFORM_EXPORT DarkModeColorClassifier { public: - // TODO(https://crbug.com/968340): Add methods to create classifiers for other - // types of elements/shapes. static std::unique_ptr<DarkModeColorClassifier> MakeTextColorClassifier( const DarkModeSettings& settings); + static std::unique_ptr<DarkModeColorClassifier> MakeBackgroundColorClassifier( + const DarkModeSettings& settings); virtual ~DarkModeColorClassifier();
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc b/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc index 4a2fd122..5242caf 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc +++ b/third_party/blink/renderer/platform/graphics/dark_mode_color_classifier_test.cc
@@ -49,5 +49,28 @@ GetColorWithBrightness(settings.text_brightness_threshold))); } +TEST(DarkModeColorClassifierTest, ApplyFilterToLightBackgroundElementsOnly) { + DarkModeSettings settings; + settings.mode = DarkMode::kSimpleInvertForTesting; + settings.background_brightness_threshold = 200; + auto classifier = + DarkModeColorClassifier::MakeBackgroundColorClassifier(settings); + + EXPECT_EQ(DarkModeClassification::kApplyFilter, + classifier->ShouldInvertColor(Color::kWhite)); + EXPECT_EQ(DarkModeClassification::kDoNotApplyFilter, + classifier->ShouldInvertColor(Color::kBlack)); + + EXPECT_EQ(DarkModeClassification::kApplyFilter, + classifier->ShouldInvertColor(GetColorWithBrightness( + settings.background_brightness_threshold + 5))); + EXPECT_EQ(DarkModeClassification::kDoNotApplyFilter, + classifier->ShouldInvertColor(GetColorWithBrightness( + settings.background_brightness_threshold))); + EXPECT_EQ(DarkModeClassification::kDoNotApplyFilter, + classifier->ShouldInvertColor(GetColorWithBrightness( + settings.background_brightness_threshold - 5))); +} + } // namespace } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc index bf14f248..90483c8 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc +++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
@@ -103,6 +103,8 @@ text_classifier_ = DarkModeColorClassifier::MakeTextColorClassifier(settings_); + background_classifier_ = + DarkModeColorClassifier::MakeBackgroundColorClassifier(settings_); } Color DarkModeFilter::InvertColorIfNeeded(const Color& color, @@ -151,8 +153,11 @@ // perform some other logic in between confirming dark mode is active and // checking the color classifiers. bool DarkModeFilter::ShouldApplyToColor(const Color& color, ElementRole role) { - if (role == ElementRole::kBackground) - return true; + if (role == ElementRole::kBackground) { + DCHECK_NE(background_classifier_, nullptr); + return background_classifier_->ShouldInvertColor(color) == + DarkModeClassification::kApplyFilter; + } DCHECK_EQ(role, ElementRole::kText); DCHECK_NE(text_classifier_, nullptr);
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter.h b/third_party/blink/renderer/platform/graphics/dark_mode_filter.h index 420d688..81ccf428 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_filter.h +++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
@@ -54,6 +54,7 @@ bool ShouldApplyToColor(const Color& color, ElementRole role); std::unique_ptr<DarkModeColorClassifier> text_classifier_; + std::unique_ptr<DarkModeColorClassifier> background_classifier_; std::unique_ptr<DarkModeColorFilter> color_filter_; sk_sp<SkColorFilter> image_filter_; };
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_settings.h b/third_party/blink/renderer/platform/graphics/dark_mode_settings.h index 4206cdb..85e95553 100644 --- a/third_party/blink/renderer/platform/graphics/dark_mode_settings.h +++ b/third_party/blink/renderer/platform/graphics/dark_mode_settings.h
@@ -47,6 +47,13 @@ // above it will be left as in the original, non-dark-mode page. Set to 256 // to always invert text color or to 0 to never invert text color. int text_brightness_threshold = 256; + + // Background elements with brightness above this threshold will be inverted, + // and below it will be left as in the original, non-dark-mode page. Set to + // 256 to never invert the color or to 0 to always invert it. + // + // Warning: This behavior is the opposite of text_brightness_threshold! + int background_brightness_threshold = 0; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump.h b/third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump.h index 31adea9..8273ed8 100644 --- a/third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump.h +++ b/third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump.h
@@ -8,7 +8,6 @@ #include <map> #include <memory> #include <unordered_map> -#include <vector> #include "base/gtest_prod_util.h" #include "base/macros.h" @@ -163,8 +162,7 @@ memory_allocator_dumps_; // Stores SkTraceMemoryDump for the current ProcessMemoryDump. - std::vector<std::unique_ptr<skia::SkiaTraceMemoryDumpImpl>> - sk_trace_dump_list_; + Vector<std::unique_ptr<skia::SkiaTraceMemoryDumpImpl>> sk_trace_dump_list_; DISALLOW_COPY_AND_ASSIGN(WebProcessMemoryDump); };
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc index 407db56..91cfcfa 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler_test.cc
@@ -34,10 +34,14 @@ void NotifyRun(MockClient* client) { client_order_.push_back(client); } // The call order that hte clients ran in. - const std::vector<MockClient*>& client_order() { return client_order_; } + const HeapVector<Member<MockClient>>& client_order() { + return client_order_; + } + + void Trace(blink::Visitor* visitor) { visitor->Trace(client_order_); } private: - std::vector<MockClient*> client_order_; + HeapVector<Member<MockClient>> client_order_; }; ~MockClient() = default; @@ -448,7 +452,7 @@ EXPECT_TRUE(client2->WasRun()); // Verify high priority request ran first. - std::vector<MockClient*> order = delegate.client_order(); + auto& order = delegate.client_order(); EXPECT_EQ(order[0], client2); EXPECT_EQ(order[1], client1);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 9d4426ed..69d87e2 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -232,7 +232,7 @@ std::unique_ptr<CodeCacheLoader> code_cache_loader_; const GURL gurl_; bool defers_loading_ = false; - std::vector<uint8_t> cached_code_; + Vector<uint8_t> cached_code_; base::Time cached_code_response_time_; base::Time resource_response_time_; bool use_isolated_code_cache_ = false; @@ -270,10 +270,11 @@ status_ = kPendingResponse; base::Time response_time; - std::vector<uint8_t> data; + WebVector<uint8_t> data; code_cache_loader_->FetchFromCodeCacheSynchronously(gurl_, &response_time, &data); - ProcessCodeCacheResponse(response_time, data, resource_loader); + ProcessCodeCacheResponse(response_time, data.ReleaseVector(), + resource_loader); return true; } @@ -325,7 +326,8 @@ // Wait for the response before we can send the cached code. // TODO(crbug.com/866889): Pass this as a handle to avoid the overhead of // copying this data. - cached_code_.assign(data.begin(), data.end()); + cached_code_.clear(); + cached_code_.AppendRange(data.begin(), data.end()); return; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc index ebe93b4..7107cda 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader_defer_loading_test.cc
@@ -66,10 +66,9 @@ ~TestCodeCacheLoader() override = default; // CodeCacheLoader methods: - void FetchFromCodeCacheSynchronously( - const GURL& url, - base::Time* response_time_out, - std::vector<uint8_t>* data_out) override {} + void FetchFromCodeCacheSynchronously(const GURL& url, + base::Time* response_time_out, + WebVector<uint8_t>* data_out) override {} void FetchFromCodeCache( blink::mojom::CodeCacheType cache_type, const GURL& url, @@ -182,8 +181,7 @@ // After code cache fetch it should have deferred WebURLLoader. DCHECK(web_url_loader_defers_); DCHECK(resource); - std::move(code_cache_response_callback_) - .Run(base::Time(), std::vector<uint8_t>()); + std::move(code_cache_response_callback_).Run(base::Time(), {}); // Once the response is received it should be reset. DCHECK(!web_url_loader_defers_); } @@ -191,7 +189,7 @@ TEST_F(ResourceLoaderDefersLoadingTest, CodeCacheFetchSyncReturn) { platform_->SetCodeCacheProcessFunction( base::BindRepeating([](CodeCacheLoader::FetchCodeCacheCallback callback) { - std::move(callback).Run(base::Time(), std::vector<uint8_t>()); + std::move(callback).Run(base::Time(), {}); })); auto* fetcher = CreateFetcher(); @@ -240,8 +238,7 @@ loader->SetDefersLoading(true); DCHECK(web_url_loader_defers_); - std::move(code_cache_response_callback_) - .Run(base::Time(), std::vector<uint8_t>()); + std::move(code_cache_response_callback_).Run(base::Time(), {}); // Since it was requested to be deferred, it should be reset to the // correct value. DCHECK(web_url_loader_defers_); @@ -265,8 +262,7 @@ loader->SetDefersLoading(false); DCHECK(web_url_loader_defers_); - std::move(code_cache_response_callback_) - .Run(base::Time(), std::vector<uint8_t>()); + std::move(code_cache_response_callback_).Run(base::Time(), {}); DCHECK(!web_url_loader_defers_); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/shared_buffer_bytes_consumer_test.cc b/third_party/blink/renderer/platform/loader/fetch/shared_buffer_bytes_consumer_test.cc index f765c2a9..9c5b242 100644 --- a/third_party/blink/renderer/platform/loader/fetch/shared_buffer_bytes_consumer_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/shared_buffer_bytes_consumer_test.cc
@@ -6,7 +6,6 @@ #include <string> #include <utility> -#include <vector> #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/loader/testing/bytes_consumer_test_reader.h" @@ -18,8 +17,8 @@ using PublicState = BytesConsumer::PublicState; TEST(SharedBufferBytesConsumerTest, Read) { - const std::vector<std::string> kData{"This is a expected data!", - "This is another data!"}; + const Vector<std::string> kData{"This is a expected data!", + "This is another data!"}; std::string flatten_expected_data; auto shared_buffer = SharedBuffer::Create(); for (const auto& chunk : kData) { @@ -44,8 +43,8 @@ } TEST(SharedBufferBytesConsumerTest, Cancel) { - const std::vector<std::string> kData{"This is a expected data!", - "This is another data!"}; + const Vector<std::string> kData{"This is a expected data!", + "This is another data!"}; auto shared_buffer = SharedBuffer::Create(); for (const auto& chunk : kData) { shared_buffer->Append(chunk.data(), chunk.size());
diff --git a/third_party/blink/renderer/platform/network/encoded_form_data_element.typemap b/third_party/blink/renderer/platform/network/encoded_form_data_element.typemap index 7ee387a..aac97c6 100644 --- a/third_party/blink/renderer/platform/network/encoded_form_data_element.typemap +++ b/third_party/blink/renderer/platform/network/encoded_form_data_element.typemap
@@ -2,10 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -mojom = "//services/network/public/mojom/url_loader.mojom" +mojom = "//third_party/blink/public/mojom/fetch/fetch_api_request.mojom" public_headers = [ "//third_party/blink/renderer/platform/network/encoded_form_data.h" ] traits_headers = [ "//third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h" ] type_mappings = - [ "network.mojom.DataElement=::blink::FormDataElement[move_only]" ] + [ "blink.mojom.FetchAPIDataElement=::blink::FormDataElement[move_only]" ]
diff --git a/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc b/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc index 0c906c9..03ff576 100644 --- a/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc +++ b/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.cc
@@ -24,8 +24,8 @@ // static network::mojom::DataElementType -StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>::type( - const blink::FormDataElement& data) { +StructTraits<blink::mojom::FetchAPIDataElementDataView, + blink::FormDataElement>::type(const blink::FormDataElement& data) { switch (data.type_) { case blink::FormDataElement::kData: return network::mojom::DataElementType::kBytes; @@ -45,30 +45,31 @@ // static base::span<const uint8_t> -StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>::buf( - const blink::FormDataElement& data) { +StructTraits<blink::mojom::FetchAPIDataElementDataView, + blink::FormDataElement>::buf(const blink::FormDataElement& data) { return base::make_span(reinterpret_cast<const uint8_t*>(data.data_.data()), data.data_.size()); } // static base::File -StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>::file( - const blink::FormDataElement& data) { +StructTraits<blink::mojom::FetchAPIDataElementDataView, + blink::FormDataElement>::file(const blink::FormDataElement& data) { return base::File(); } // static base::FilePath -StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>::path( - const blink::FormDataElement& data) { +StructTraits<blink::mojom::FetchAPIDataElementDataView, + blink::FormDataElement>::path(const blink::FormDataElement& data) { return base::FilePath::FromUTF8Unsafe(data.filename_.Utf8()); } // static -network::mojom::blink::DataPipeGetterPtrInfo -StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>:: - data_pipe_getter(const blink::FormDataElement& data) { +network::mojom::blink::DataPipeGetterPtrInfo StructTraits< + blink::mojom::FetchAPIDataElementDataView, + blink::FormDataElement>::data_pipe_getter(const blink::FormDataElement& + data) { if (data.type_ == blink::FormDataElement::kDataPipe) { if (!data.data_pipe_getter_) return nullptr; @@ -93,8 +94,8 @@ } // static -base::Time -StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>:: +base::Time StructTraits<blink::mojom::FetchAPIDataElementDataView, + blink::FormDataElement>:: expected_modification_time(const blink::FormDataElement& data) { if (data.type_ == blink::FormDataElement::kEncodedFile) return base::Time::FromDoubleT(data.expected_file_modification_time_); @@ -102,8 +103,9 @@ } // static -bool StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>:: - Read(network::mojom::DataElementDataView data, +bool StructTraits<blink::mojom::FetchAPIDataElementDataView, + blink::FormDataElement>:: + Read(blink::mojom::FetchAPIDataElementDataView data, blink::FormDataElement* out) { network::mojom::DataElementType data_type; if (!data.ReadType(&data_type)) {
diff --git a/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h b/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h index 8ed20e2..74c00ea 100644 --- a/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h +++ b/third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h
@@ -6,13 +6,14 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_ENCODED_FORM_DATA_ELEMENT_MOJOM_TRAITS_H_ #include "services/network/public/mojom/url_loader.mojom-blink.h" +#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/renderer/platform/network/encoded_form_data.h" namespace mojo { template <> -struct PLATFORM_EXPORT - StructTraits<network::mojom::DataElementDataView, blink::FormDataElement> { +struct PLATFORM_EXPORT StructTraits<blink::mojom::FetchAPIDataElementDataView, + blink::FormDataElement> { static network::mojom::DataElementType type( const blink::FormDataElement& data); @@ -49,7 +50,7 @@ static base::Time expected_modification_time( const blink::FormDataElement& data); - static bool Read(network::mojom::DataElementDataView data, + static bool Read(blink::mojom::FetchAPIDataElementDataView data, blink::FormDataElement* out); };
diff --git a/third_party/blink/renderer/platform/network/encoded_form_data_test.cc b/third_party/blink/renderer/platform/network/encoded_form_data_test.cc index 31cbbcd..85c172a1 100644 --- a/third_party/blink/renderer/platform/network/encoded_form_data_test.cc +++ b/third_party/blink/renderer/platform/network/encoded_form_data_test.cc
@@ -14,6 +14,7 @@ #include "mojo/public/cpp/test_support/test_utils.h" #include "services/network/public/mojom/url_loader.mojom-blink.h" #include "third_party/blink/public/mojom/blob/blob.mojom-blink.h" +#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/renderer/platform/network/encoded_form_data.h" #include "third_party/blink/renderer/platform/network/encoded_form_data_element_mojom_traits.h" #include "third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h" @@ -119,9 +120,8 @@ original1.type_ = blink::FormDataElement::kData; original1.data_ = {'a', 'b', 'c', 'd'}; FormDataElement copied1; - EXPECT_TRUE( - mojo::test::SerializeAndDeserialize<network::mojom::blink::DataElement>( - &original1, &copied1)); + EXPECT_TRUE(mojo::test::SerializeAndDeserialize< + blink::mojom::blink::FetchAPIDataElement>(&original1, &copied1)); EXPECT_EQ(original1.type_, copied1.type_); EXPECT_EQ(original1.data_, copied1.data_); @@ -132,9 +132,8 @@ original2.filename_ = "file.name"; original2.expected_file_modification_time_ = base::Time::Now().ToDoubleT(); FormDataElement copied2; - EXPECT_TRUE( - mojo::test::SerializeAndDeserialize<network::mojom::blink::DataElement>( - &original2, &copied2)); + EXPECT_TRUE(mojo::test::SerializeAndDeserialize< + blink::mojom::blink::FetchAPIDataElement>(&original2, &copied2)); EXPECT_EQ(original2.type_, copied2.type_); EXPECT_EQ(original2.file_start_, copied2.file_start_); EXPECT_EQ(original2.file_length_, copied2.file_length_); @@ -150,9 +149,8 @@ original3.blob_uuid_, "type-test", 100, mojom::blink::BlobPtrInfo(std::move(pipe.handle0), 0)); FormDataElement copied3; - EXPECT_TRUE( - mojo::test::SerializeAndDeserialize<network::mojom::blink::DataElement>( - &original3, &copied3)); + EXPECT_TRUE(mojo::test::SerializeAndDeserialize< + blink::mojom::blink::FetchAPIDataElement>(&original3, &copied3)); EXPECT_EQ(copied3.type_, blink::FormDataElement::kDataPipe); FormDataElement original4; @@ -163,9 +161,8 @@ base::MakeRefCounted<blink::WrappedDataPipeGetter>( std::move(data_pipe_getter)); FormDataElement copied4; - EXPECT_TRUE( - mojo::test::SerializeAndDeserialize<network::mojom::blink::DataElement>( - &original4, &copied4)); + EXPECT_TRUE(mojo::test::SerializeAndDeserialize< + blink::mojom::blink::FetchAPIDataElement>(&original4, &copied4)); EXPECT_TRUE(copied4.data_pipe_getter_); }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 1fce1c5..ef782e8 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -854,6 +854,10 @@ status: "experimental", }, { + name: "LazyImageLoadingMetadataFetch", + depends_on: ["LazyImageLoading"], + }, + { name: "LazyImageVisibleLoadTimeMetrics", }, {
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h index a3ab005..da09c62e 100644 --- a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h +++ b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h
@@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_THROTTLING_TASK_QUEUE_THROTTLER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_THROTTLING_TASK_QUEUE_THROTTLER_H_ -#include <set> #include <unordered_map> #include "base/logging.h"
diff --git a/third_party/blink/renderer/platform/testing/code_cache_loader_mock.cc b/third_party/blink/renderer/platform/testing/code_cache_loader_mock.cc index d57078d..e84785f 100644 --- a/third_party/blink/renderer/platform/testing/code_cache_loader_mock.cc +++ b/third_party/blink/renderer/platform/testing/code_cache_loader_mock.cc
@@ -9,9 +9,9 @@ void CodeCacheLoaderMock::FetchFromCodeCacheSynchronously( const GURL& url, base::Time* response_time_out, - std::vector<uint8_t>* data_out) { + WebVector<uint8_t>* data_out) { *response_time_out = base::Time(); - *data_out = std::vector<uint8_t>(); + *data_out = WebVector<uint8_t>(); } void CodeCacheLoaderMock::FetchFromCodeCache(
diff --git a/third_party/blink/renderer/platform/testing/code_cache_loader_mock.h b/third_party/blink/renderer/platform/testing/code_cache_loader_mock.h index 3fc9db1..c45598f 100644 --- a/third_party/blink/renderer/platform/testing/code_cache_loader_mock.h +++ b/third_party/blink/renderer/platform/testing/code_cache_loader_mock.h
@@ -20,7 +20,7 @@ // CodeCacheLoader methods: void FetchFromCodeCacheSynchronously(const GURL& url, base::Time* response_time_out, - std::vector<uint8_t>* data_out) override; + WebVector<uint8_t>* data_out) override; void FetchFromCodeCache( blink::mojom::CodeCacheType cache_type, const GURL& url,
diff --git a/third_party/blink/renderer/platform/testing/fuzzed_data_provider.cc b/third_party/blink/renderer/platform/testing/fuzzed_data_provider.cc index 2a9f311..c3c77e0 100644 --- a/third_party/blink/renderer/platform/testing/fuzzed_data_provider.cc +++ b/third_party/blink/renderer/platform/testing/fuzzed_data_provider.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "third_party/blink/renderer/platform/testing/fuzzed_data_provider.h" +#include "third_party/blink/public/platform/web_vector.h" namespace blink { @@ -17,8 +18,8 @@ } std::string FuzzedDataProvider::ConsumeRemainingBytes() { - std::vector<char> bytes = provider_.ConsumeRemainingBytes<char>(); - return std::string(bytes.data(), bytes.size()); + WebVector<char> bytes = provider_.ConsumeRemainingBytes<char>(); + return std::string(bytes.Data(), bytes.size()); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h b/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h index 577edefb..058efc0 100644 --- a/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h +++ b/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.h
@@ -83,7 +83,7 @@ private: class DummyWebRTCRtpTransceiver; - std::vector<std::unique_ptr<DummyWebRTCRtpTransceiver>> transceivers_; + Vector<std::unique_ptr<DummyWebRTCRtpTransceiver>> transceivers_; }; class TestingPlatformSupportWithWebRTC : public TestingPlatformSupport {
diff --git a/third_party/blink/renderer/platform/text/bidi_resolver_test.cc b/third_party/blink/renderer/platform/text/bidi_resolver_test.cc index 9d6f961..1652c73 100644 --- a/third_party/blink/renderer/platform/text/bidi_resolver_test.cc +++ b/third_party/blink/renderer/platform/text/bidi_resolver_test.cc
@@ -129,15 +129,15 @@ } void RunTest(const std::basic_string<UChar>& input, - const std::vector<int>& reorder, - const std::vector<int>& levels, + const Vector<int>& reorder, + const Vector<int>& levels, bidi_test::ParagraphDirection, const std::string& line, size_t line_number); size_t tests_run_; size_t tests_skipped_; - std::set<UChar> skipped_code_points_; + HashSet<UChar> skipped_code_points_; size_t ignored_char_failures_; size_t level_failures_; size_t order_failures_; @@ -156,8 +156,7 @@ // But it seems to expect LRI, etc. to be rendered!? } -std::string DiffString(const std::vector<int>& actual, - const std::vector<int>& expected) { +std::string DiffString(const Vector<int>& actual, const Vector<int>& expected) { std::ostringstream diff; diff << "actual: "; // This is the magical way to print a vector to a stream, clear, right? @@ -170,14 +169,14 @@ } void BidiTestRunner::RunTest(const std::basic_string<UChar>& input, - const std::vector<int>& expected_order, - const std::vector<int>& expected_levels, + const Vector<int>& expected_order, + const Vector<int>& expected_levels, bidi_test::ParagraphDirection paragraph_direction, const std::string& line, size_t line_number) { - if (!skipped_code_points_.empty()) { + if (!skipped_code_points_.IsEmpty()) { for (size_t i = 0; i < input.size(); i++) { - if (skipped_code_points_.count(input[i])) { + if (skipped_code_points_.Contains(input[i])) { tests_skipped_++; return; } @@ -213,9 +212,9 @@ error_context << " context: " << bidi_test::NameFromParagraphDirection(paragraph_direction); - std::vector<int> actual_order; - std::vector<int> actual_levels; - actual_levels.assign(input.size(), -1); + Vector<int> actual_order; + Vector<int> actual_levels; + actual_levels.Fill(-1, input.size()); BidiCharacterRun* run = runs.FirstRun(); while (run) { // Blink's UBA just makes runs, the actual ordering of the display of
diff --git a/third_party/blink/renderer/platform/text/bidi_test_harness.h b/third_party/blink/renderer/platform/text/bidi_test_harness.h index 104d27d..5f470b76 100644 --- a/third_party/blink/renderer/platform/text/bidi_test_harness.h +++ b/third_party/blink/renderer/platform/text/bidi_test_harness.h
@@ -35,7 +35,6 @@ #include <map> #include <stdio.h> #include <string> -#include <vector> // FIXME: We don't have any business owning this code. We should try to // upstream this to unicode.org if possible (for other implementations to use). @@ -116,8 +115,8 @@ Ltrim(s); } -static std::vector<std::string> ParseStringList(const std::string& str) { - std::vector<std::string> strings; +static Vector<std::string> ParseStringList(const std::string& str) { + Vector<std::string> strings; static const std::string kSeparators(" \t"); size_t last_pos = str.find_first_not_of(kSeparators); // skip leading spaces size_t pos = str.find_first_of(kSeparators, last_pos); // find next space @@ -134,9 +133,9 @@ return atoi(str.c_str()); } -static std::vector<int> ParseIntList(const std::string& str) { - std::vector<int> ints; - std::vector<std::string> strings = ParseStringList(str); +static Vector<int> ParseIntList(const std::string& str) { + Vector<int> ints; + Vector<std::string> strings = ParseStringList(str); for (size_t x = 0; x < strings.size(); x++) { int i = ParseInt(strings[x]); ints.push_back(i); @@ -144,9 +143,9 @@ return ints; } -static std::vector<int> ParseLevels(const std::string& line) { - std::vector<int> levels; - std::vector<std::string> strings = ParseStringList(line); +static Vector<int> ParseLevels(const std::string& line) { + Vector<int> levels; + Vector<std::string> strings = ParseStringList(line); for (size_t x = 0; x < strings.size(); x++) { const std::string& level_string = strings[x]; int i; @@ -191,7 +190,7 @@ char_class_examples.insert(std::make_pair("PDI", 0x2069)); } - std::vector<std::string> char_classes = ParseStringList(line); + Vector<std::string> char_classes = ParseStringList(line); for (size_t i = 0; i < char_classes.size(); i++) { // FIXME: If the lookup failed we could return false for a parse error. test_string.push_back(char_class_examples.find(char_classes[i])->second); @@ -218,8 +217,8 @@ // FIXME: UChar is an ICU type and cheating a bit to use here. // uint16_t might be more portable. std::basic_string<UChar> test_string; - std::vector<int> levels; - std::vector<int> reorder; + Vector<int> levels; + Vector<int> reorder; int paragraph_direction_mask; std::string line; @@ -285,7 +284,7 @@ static std::basic_string<UChar> ParseUCharHexadecimalList( const std::string& str) { std::basic_string<UChar> string; - std::vector<std::string> strings = ParseStringList(str); + Vector<std::string> strings = ParseStringList(str); for (size_t x = 0; x < strings.size(); x++) { int i = strtol(strings[x].c_str(), nullptr, 16); string.push_back((UChar)i); @@ -308,7 +307,7 @@ } static int ParseSuppresedChars(const std::string& str) { - std::vector<std::string> strings = ParseStringList(str); + Vector<std::string> strings = ParseStringList(str); int suppresed_chars = 0; for (size_t x = 0; x < strings.size(); x++) { if (strings[x] == "x") @@ -384,7 +383,7 @@ } int supressed_chars = ParseSuppresedChars(line.substr(0, separator_index)); - std::vector<int> levels = ParseLevels(line.substr(0, separator_index)); + Vector<int> levels = ParseLevels(line.substr(0, separator_index)); if (test_string.size() != levels.size()) { ParseError(original_line, line_number); continue; @@ -398,7 +397,7 @@ continue; } - std::vector<int> visual_ordering = ParseIntList(line); + Vector<int> visual_ordering = ParseIntList(line); if (test_string.size() - supressed_chars != visual_ordering.size()) { ParseError(original_line, line_number); continue;
diff --git a/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc b/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc index 0409d533..df1985f 100644 --- a/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc +++ b/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.cc
@@ -6,7 +6,6 @@ #include <algorithm> #include <utility> -#include <vector> #include "base/files/file.h" #include "base/files/memory_mapped_file.h" @@ -82,9 +81,8 @@ return true; } -std::vector<uint8_t> HyphenationMinikin::Hyphenate( - const StringView& text) const { - std::vector<uint8_t> result; +Vector<uint8_t> HyphenationMinikin::Hyphenate(const StringView& text) const { + Vector<uint8_t> result; if (text.Is8Bit()) { String text16_bit = text.ToString(); text16_bit.Ensure16Bit(); @@ -110,7 +108,7 @@ before_index <= kMinimumPrefixLength) return 0; - std::vector<uint8_t> result = Hyphenate(word); + Vector<uint8_t> result = Hyphenate(word); CHECK_LE(before_index, result.size()); CHECK_GE(before_index, 1u); static_assert(kMinimumPrefixLength >= 1, "|beforeIndex - 1| can underflow"); @@ -130,7 +128,7 @@ if (word.length() < kMinimumPrefixLength + kMinimumSuffixLength) return hyphen_locations; - std::vector<uint8_t> result = Hyphenate(word); + Vector<uint8_t> result = Hyphenate(word); static_assert(kMinimumPrefixLength >= 1, "Change the 'if' above if this fails"); for (wtf_size_t i = word.length() - kMinimumSuffixLength - 1;
diff --git a/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.h b/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.h index 20d7eca..e17bacf 100644 --- a/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.h +++ b/third_party/blink/renderer/platform/text/hyphenation/hyphenation_minikin.h
@@ -33,7 +33,7 @@ private: bool OpenDictionary(base::File); - std::vector<uint8_t> Hyphenate(const StringView&) const; + Vector<uint8_t> Hyphenate(const StringView&) const; base::MemoryMappedFile file_; std::unique_ptr<android::Hyphenator> hyphenator_;
diff --git a/third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.cc b/third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.cc index c03f40b..d88444b0 100644 --- a/third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.cc +++ b/third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.cc
@@ -16,7 +16,6 @@ * * ***** END LICENSE BLOCK ***** */ -#include <vector> #include <memory> #include <algorithm> #include <unicode/uchar.h> @@ -26,8 +25,6 @@ #include "third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.h" -using std::vector; - namespace android { static const uint16_t CHAR_SOFT_HYPHEN = 0x00AD; @@ -112,7 +109,7 @@ return result; } -void Hyphenator::hyphenate(vector<uint8_t>* result, +void Hyphenator::hyphenate(Vector<uint8_t>* result, const uint16_t* word, size_t len) { result->clear();
diff --git a/third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.h b/third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.h index 7ae5e47..7860f44 100644 --- a/third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.h +++ b/third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.h
@@ -24,7 +24,7 @@ */ #include <memory> -#include <unordered_map> +#include "third_party/blink/renderer/platform/wtf/vector.h" namespace android { @@ -42,9 +42,7 @@ // 1 means insert hyphen and break, but this will be expanded to other edits // for nonstandard hyphenation. Example: word is "hyphen", result is [0 0 1 0 // 0 0], corresponding to "hy-phen". - void hyphenate(std::vector<uint8_t>* result, - const uint16_t* word, - size_t len); + void hyphenate(Vector<uint8_t>* result, const uint16_t* word, size_t len); // pattern data is in binary format, as described in doc/hyb_file_format.md. // Note: the caller is responsible for ensuring that the lifetime of the
diff --git a/third_party/blink/renderer/platform/wtf/pod_free_list_arena_test.cc b/third_party/blink/renderer/platform/wtf/pod_free_list_arena_test.cc index 19efe40..45232f37 100644 --- a/third_party/blink/renderer/platform/wtf/pod_free_list_arena_test.cc +++ b/third_party/blink/renderer/platform/wtf/pod_free_list_arena_test.cc
@@ -27,6 +27,7 @@ #include "base/memory/scoped_refptr.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/pod_arena_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -101,7 +102,7 @@ // Make sure the arena runs constructors of the objects allocated within. TEST_F(PODFreeListArenaTest, RunsConstructorsOnReusedObjects) { - std::set<TestClass1*> objects; + HashSet<TestClass1*> objects; scoped_refptr<PODFreeListArena<TestClass1>> arena = PODFreeListArena<TestClass1>::Create(); for (int i = 0; i < 100; i++) { @@ -113,8 +114,8 @@ objects.insert(tc1); } - for (std::set<TestClass1*>::iterator it = objects.begin(); - it != objects.end(); ++it) { + for (HashSet<TestClass1*>::iterator it = objects.begin(); it != objects.end(); + ++it) { arena->FreeObject(*it); } for (int i = 0; i < 100; i++) { @@ -145,14 +146,14 @@ // Make sure allocations use previously freed memory. TEST_F(PODFreeListArenaTest, ReusesPreviouslyFreedObjects) { - std::set<TestClass2*> objects; + HashSet<TestClass2*> objects; scoped_refptr<PODFreeListArena<TestClass2>> arena = PODFreeListArena<TestClass2>::Create(); for (int i = 0; i < 100; i++) { objects.insert(arena->AllocateObject()); } - for (std::set<TestClass2*>::iterator it = objects.begin(); - it != objects.end(); ++it) { + for (HashSet<TestClass2*>::iterator it = objects.begin(); it != objects.end(); + ++it) { arena->FreeObject(*it); } for (int i = 0; i < 100; i++) {
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index 22a5ba5..4f1cfae 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -404,7 +404,7 @@ 'disallowed': [ ('base::Bind(|Once|Repeating)', 'Use WTF::Bind or WTF::BindRepeating.'), - ('std::(map)', + ('std::(map|vector)', 'Use WTF containers like WTF::HashMap instead of the banned std containers.'), ], },
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 662a5ef..42431dc 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -827,7 +827,6 @@ external/wpt/css/css-backgrounds/background-size-025.html [ WontFix ] external/wpt/css/css-backgrounds/background-size-027.html [ WontFix ] external/wpt/css/css-backgrounds/background-size-029.html [ WontFix ] -external/wpt/css/css-backgrounds/background-size-035.html [ WontFix ] external/wpt/css/css-backgrounds/background-size/background-size-contain.xht [ WontFix ] external/wpt/css/css-backgrounds/background-size/vector/background-size-vector-003.html [ WontFix ] external/wpt/css/css-backgrounds/background-size/vector/background-size-vector-004.html [ WontFix ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index c2733f16..81a14dd 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2722,6 +2722,15 @@ crbug.com/v8/8742 http/tests/devtools/sources/debugger/rethrow-error-from-bindings-crash.js [ Failure Pass ] crbug.com/v8/8742 virtual/mouseevent_fractional/fast/events/window-onerror-11.html [ Failure Pass ] crbug.com/v8/8742 virtual/mouseevent_fractional/fast/events/window-onerror-12.html [ Failure Pass ] +# Also stack trace layout. The following web tests now include 'eval' in the stack trace. +# Can be renabled when the corresponding V8 CL lands. +crbug.com/v8/8742 http/tests/devtools/console/console-error-on-call-frame.js [ Failure Pass ] +crbug.com/v8/8742 http/tests/devtools/console/console-trace-in-eval.js [ Failure Pass ] +crbug.com/v8/8742 http/tests/devtools/console/console-uncaught-exception-in-eval.js [ Failure Pass ] +crbug.com/v8/8742 http/tests/devtools/sources/debugger-async/async-callstack.js [ Failure Pass ] +crbug.com/v8/8742 http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused-throws.js [ Failure Pass ] +crbug.com/v8/8742 http/tests/inspector-protocol/network/navigation-long-async-stack.js [ Failure Pass ] +crbug.com/v8/8742 inspector-protocol/runtime/runtime-console-basic-functions-paused.js [ Failure Pass ] # These testcases are incorrect, mark them as failing until they're fixed in the testsuite. # https://lists.w3.org/Archives/Public/www-style/2016Jan/0275.html @@ -3203,6 +3212,7 @@ crbug.com/968164 external/wpt/css/css-ui/webkit-appearance-menulist-button-001.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/webauthn/idlharness-manual.https.window.js [ Skip ] crbug.com/626703 [ Mac ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-size-select-elem-003.html [ Failure ] crbug.com/626703 [ Mac ] virtual/layout_ng_experimental/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-size-select-elem-004.html [ Failure ] crbug.com/626703 virtual/layout_ng_experimental/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/contain/contain-size-select-elem-005.html [ Failure ] @@ -6245,6 +6255,11 @@ crbug.com/980924 [ Linux Win Debug ] external/wpt/html/cross-origin/null.tentative.html [ Pass Failure ] crbug.com/980283 [ Mac ] virtual/gpu/fast/canvas/image-object-in-canvas.html [ Pass Failure ] crbug.com/981137 [ Win ] virtual/gpu-rasterization/images/webp-no-color-profile-lossy.html [ Pass Failure ] +crbug.com/981210 [ Linux ] external/wpt/web-animations/interfaces/Animation/oncancel.html [ Pass Failure ] + +# Sheriff 2019-07-04 +crbug.com/981249 [ Linux Win ] fast/forms/form-submission-create-crash.xhtml [ Pass Failure ] +crbug.com/981267 [ Linux ] http/tests/devtools/persistence/persistence-move-breakpoints.js [ Pass Failure ] # TODO(crbug.com/980588): reenable once WPT is fixed crbug.com/980588 external/wpt/screen-orientation/lock-unlock-check.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index 3e7563bf..cf9e5bd0 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -7183,6 +7183,12 @@ {} ] ], + "webauthn/idlharness-manual.https.window.js": [ + [ + "webauthn/idlharness-manual.https.window.js", + {} + ] + ], "webstorage/storage_local-manual.html": [ [ "webstorage/storage_local-manual.html", @@ -32503,18 +32509,6 @@ {} ] ], - "css/css-backgrounds/background-size-035.html": [ - [ - "css/css-backgrounds/background-size-035.html", - [ - [ - "/css/css-backgrounds/reference/background-size-ref.html", - "==" - ] - ], - {} - ] - ], "css/css-backgrounds/background-size-contain-001.html": [ [ "css/css-backgrounds/background-size-contain-001.html", @@ -175427,9 +175421,6 @@ "webxr/idlharness.https.window-expected.txt": [ [] ], - "webxr/resources/test-constants.js": [ - [] - ], "webxr/resources/webxr_check.html": [ [] ], @@ -340901,10 +340892,6 @@ "0debc25b2bb1335b2619b2f592cf5c7135c27ca2", "reftest" ], - "css/css-backgrounds/background-size-035.html": [ - "1e5052ac14347fcc665e36a346988db2bcbf2950", - "reftest" - ], "css/css-backgrounds/background-size-applies-to-block.htm": [ "b1273ef334ec9a13a3f7e8fd138aab1fd4ba663a", "visual" @@ -462718,7 +462705,7 @@ "support" ], "resources/chromium/webxr-test.js": [ - "31bf916caf80bdbd8c2d4173ff6a22e661524b38", + "e584ea37cb37edb7af3ed019e91b0a71b2648a44", "support" ], "resources/chromium/webxr-test.js.headers": [ @@ -478562,11 +478549,11 @@ "testharness" ], "web-nfc/NFCWriter_push.https-expected.txt": [ - "e7939625a7ed3ef5c68aedc893d5f07104cc2b9d", + "7d4e6ec7505d9e7f66b855b7afbdc8c6c594231c", "support" ], "web-nfc/NFCWriter_push.https.html": [ - "5a14b4090afe7b7850a36129eb3f882ac1886267", + "0b804615930b12d1ac4d7bfc1b395e715de03778", "testharness" ], "web-nfc/NFCWriter_push_signal-manual.https-expected.txt": [ @@ -479797,8 +479784,12 @@ "73474b5ecbfd5b5f2f83d8e4b3ad7f317f75a5bd", "support" ], + "webauthn/idlharness-manual.https.window.js": [ + "884702753d84ba92f85204f24227d2ed7b44cce7", + "manual" + ], "webauthn/idlharness.https.window.js": [ - "fa5e812eeee1632488e0ad77d8d97c0e115ae021", + "ff0efcb656a740e9fdee2a3cc8dbfddda9b2a563", "testharness" ], "webauthn/securecontext.http.html": [ @@ -486689,10 +486680,6 @@ "3e54e367787cb95dada398790fe23b10174df29f", "testharness" ], - "webxr/resources/test-constants.js": [ - "aab0417aed0b08e930347ff666cd672d271b8e00", - "support" - ], "webxr/resources/webxr_check.html": [ "2d8e5b387dc88588921ccfa49dd14db58009900c", "support" @@ -486706,11 +486693,11 @@ "support" ], "webxr/resources/webxr_test_constants.js": [ - "c38c012ba8462589c33fcdecab49299125c85ec5", + "a846f1da75fe4707623a123f5e9e1bfe2952fd8a", "support" ], "webxr/resources/webxr_util.js": [ - "860d363f2c96bbf108e38659b5b6afc90957817e", + "54a91c85c86a311b382c293c3e53fa92c0182b81", "support" ], "webxr/resources/xr-test-asserts.js": [ @@ -486718,11 +486705,11 @@ "support" ], "webxr/webGLCanvasContext_create_xrcompatible.https.html": [ - "8b2f196fa76ecc102319bf9409cba143d0d35e13", + "b83b9601aed1930b5687154b9f5a1b6877bb988a", "testharness" ], "webxr/webGLCanvasContext_makecompatible_contextlost.https.html": [ - "3102008c57db1e32a0910eabfc93c55809b8300c", + "0e3dbfc97f98fd58d8a399c164db4d75a4435b0e", "testharness" ], "webxr/webxr-supported-by-feature-policy.html": [ @@ -486734,107 +486721,107 @@ "testharness" ], "webxr/xrDevice_requestSession_immersive.https.html": [ - "50a9d344541c8ce3b6bca11d1d5b30a52a835227", + "a397d1a89f6e0d3ac7784a39ac8612350aa69dcd", "testharness" ], "webxr/xrDevice_requestSession_immersive_no_gesture.https.html": [ - "eb5a4fda0bdfc6e69cc9fbafa276d2ac85a2a16e", + "10e15b63244da8625e16181687fdab897418ab4d", "testharness" ], "webxr/xrDevice_requestSession_immersive_unsupported.https.html": [ - "2592f3a4a0d4b96b81ca2d3b0e2c43c06343c9aa", + "6c0e6284a420eac8860c648045d26b74a45a1052", "testharness" ], "webxr/xrDevice_requestSession_no_mode.https.html": [ - "c4ac3f6b6d77e9aab391069eb8895a28cb1c904a", + "de77b38c868e3b5dad88b8eface770b16b5f16c1", "testharness" ], "webxr/xrDevice_requestSession_non_immersive_no_gesture.https.html": [ - "40e6f4928b3f63c9c6e4bd71d40022e86dbf4bec", + "59950592558513f2530aaedaa86f89c955166863", "testharness" ], "webxr/xrDevice_supportsSession_immersive.https.html": [ - "53dd41e3d27d1be2d2d31c6fd88d26676f10db0a", + "fd0827a526ef01299eeccd94f93f131e4014cd7b", "testharness" ], "webxr/xrDevice_supportsSession_immersive_unsupported.https.html": [ - "0fb44a895d1f790b4b0c4c9b2f236cb7a4169824", + "1d63a2b1c3a254d999473bc507453095c4243a08", "testharness" ], "webxr/xrDevice_supportsSession_non_immersive.https.html": [ - "d5191400c449808b9b21f3687742c4dfa487dffc", + "b376495d765106fcb1435c3e60c0fa6e167d9c71", "testharness" ], "webxr/xrFrame_getPose.https.html": [ - "243fb8cd66617667f8d2dae5742112e3fc476dec", + "50e8abf145b98730f4859c5ccd2ded4eb38d57ba", "testharness" ], "webxr/xrFrame_lifetime.https.html": [ - "27ef02de337451551d4e028bc7e6f5de524d8aeb", + "c7af792c7bb45155c1a24e177ed3be05875872d6", "testharness" ], "webxr/xrRay_constructor.https.html": [ - "ebf88845b0cdd86ff44443f17e2540aa01b6c13c", + "b955db4509c2f60facee570e6011a1441297e3dd", "testharness" ], "webxr/xrRay_matrix.https.html": [ - "85d7bffb87b731f6a863ec752ede5ceac3bfca16", + "83a1050d6b169d28ad6b9d4417f06895e53bcfc6", "testharness" ], "webxr/xrRigidTransform_constructor.https.html": [ - "15666973473abbf722fdd3bc8e90d679a36b8732", + "6a54fff808d93ac4423364b9c8b9d528a7e520c0", "testharness" ], "webxr/xrRigidTransform_inverse.https.html": [ - "706f72102ad3e7e6d9daaf30e6a98c888fbdbcba", + "a314f6b55a21b03abe5fb4ae0b32bc5c458e09f6", "testharness" ], "webxr/xrRigidTransform_matrix.https.html": [ - "21236c732461de4422dcab7a3709cdc7ffc0f3a6", + "df804193ffe9eb87dbb16383cb333a5fe0a06546", "testharness" ], "webxr/xrSession_cancelAnimationFrame.https.html": [ - "d45349ad24464ef424e411cae0d059fbbb33d570", + "6a294f21f06d98483d9278d08e50124d84779aad", "testharness" ], "webxr/xrSession_cancelAnimationFrame_invalidhandle.https.html": [ - "b93f4e27909efa888793a85f4529d8da7bf0546c", + "51a639b956c8f64c3f219df4fbde2e99160e9959", "testharness" ], "webxr/xrSession_end.https.html": [ - "26b6b47d2bfeea35249bd36ca49fda1d5b2ec1f8", + "b91a5b977cab3d2fbb5c4989246f45b0c9b2024b", "testharness" ], "webxr/xrSession_prevent_multiple_exclusive.https.html": [ - "e61bd392718ae3b0f8ac8de0fa81604f2d32dcce", + "cd140703784961911586f8b63cebd52b356facd5", "testharness" ], "webxr/xrSession_requestAnimationFrame_callback_calls.https.html": [ - "2ed468bc3a5a44c1653de6bdb3716d8de4078167", + "98231c8e9e70ea73a0b63785bb108362512f36e4", "testharness" ], "webxr/xrSession_requestAnimationFrame_data_valid.https.html": [ - "c5108e4eccf9f553fb4ee2990c6cd6ad471d16c7", + "760ff3dd657f9c56d01f6d952879bb20dd9a0e46", "testharness" ], "webxr/xrSession_requestAnimationFrame_getViewerPose.https.html": [ - "95d9e78105948fc496af2ecec1dc015ff25fc134", + "f8587796a229ec7f0aa5ab4fcde573737c2e7eca", "testharness" ], "webxr/xrSession_requestReferenceSpace.https.html": [ - "2fbf9b977ca153acf7028bd73844b7eb10c20b72", + "c90d6ce5a545563664ed34d946db2bca48edca40", "testharness" ], "webxr/xrSession_viewer_referenceSpace.https.html": [ - "85e5e87f8266f2701c96dc643e8890942ef013bd", + "fd6082bc3468f094953152d220fceafa083baf76", "testharness" ], "webxr/xrView_eyes.https.html": [ - "8090bcebadb39902189c716b8434de949e9c5ae9", + "4ff22ff618d96d53c7a9e8cc573608bb0ea7919e", "testharness" ], "webxr/xrWebGLLayer_viewports.https.html": [ - "f789e473354890e39bc0ffa5abc410daea7615cf", + "247e3b779d6105f4a9e57fd39c5dcf06ca737950", "testharness" ], "workers/META.yml": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-035.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-035.html deleted file mode 100644 index 1e5052ac..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-size-035.html +++ /dev/null
@@ -1,33 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <title>CSS Background and Border Test:background-size conflicts with background-attachment</title> - <link rel="author" title="xiaochun" href="mailto:stenders@163.com"> - <link rel="reviewer" title="Jinlong Zhang" href="mailto:jinlongz@oupeng.com"><!--2012/10/21--> - <link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-size"> - <link rel="match" href="reference/background-size-ref.html"> - <meta name="assert" content="The test passes if we can see the background-image is exactly same as above."> - <style type="text/css"> - .backgroundSize{ - width:295px; - height:289px; - - background-image:url(support/bg.jpg); - background-repeat:no-repeat; - background-size:cover; - background-attachment:fixed; - } - </style> -</head> -<body> - The image used as background-image is :<br /> - <img src="support/bg.jpg" /> - - <p>The test passes if we can see the background-image is exactly same as above.</p> - <div class="container"> - <!-- This is the box that should only contains an image if the test passes --> - <div class="backgroundSize"> - </div> - </div> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https-expected.txt b/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https-expected.txt index e7939625..7d4e6ec 100644 --- a/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https-expected.txt
@@ -2,8 +2,8 @@ PASS Test that promise is rejected with TypeError if NDEFMessageSource is invalid. PASS 'Test that promise is rejected with SyntaxError if NDEFMessageSource contains invalid records. FAIL NFCWriter.push should fail if abort push request before push happends. assert_throws: function "function() { throw e }" threw object "NotReadableError: No NFC adapter or cannot establish connection." that is not a DOMException AbortError: property "code" is equal to 0, expected 20 -FAIL NFCWriter.push should fail if signal's aborted flag is set. assert_throws: function "function() { throw e }" threw object "NotReadableError: No NFC adapter or cannot establish connection." that is not a DOMException AbortError: property "code" is equal to 0, expected 20 -FAIL NFCWriter.push should fail if signal is not an AbortSignal. Test bug: unrecognized DOMException code "TypeError" passed to assert_throws() +PASS NFCWriter.push should fail if signal's aborted flag is set. +PASS NFCWriter.push should fail if signal is not an AbortSignal. PASS NFCWriter.push should fail with TypeError when invalid timeout is provided. PASS NFCWriter.push should fail with TypeError when invalid negative timeout value is provided. FAIL NFCWriter.push should fail with TimeoutError when timer expires. assert_throws: function "function() { throw e }" threw object "NotReadableError: No NFC adapter or cannot establish connection." that is not a DOMException TimeoutError: property "code" is equal to 0, expected 23
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https.html b/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https.html index 5a14b409..0b80461 100644 --- a/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https.html +++ b/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https.html
@@ -132,7 +132,7 @@ const promises = []; invalid_signals.forEach(invalid_signal => { promises.push( - promise_rejects(t, 'TypeError', writer.push(test_text_data, { signal: invalid_signal }))); + promise_rejects(t, new TypeError(), writer.push(test_text_data, { signal: invalid_signal }))); }); return Promise.all(promises); }, "NFCWriter.push should fail if signal is not an AbortSignal.");
diff --git a/third_party/blink/web_tests/external/wpt/webauthn/idlharness-manual.https.window.js b/third_party/blink/web_tests/external/wpt/webauthn/idlharness-manual.https.window.js new file mode 100644 index 0000000..8847027 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webauthn/idlharness-manual.https.window.js
@@ -0,0 +1,53 @@ +// META: timeout=long +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js +// META: script=helpers.js + +// https://w3c.github.io/webauthn/ + +'use strict'; + +idl_test( + ['webauthn'], + ['credential-management'], + async idlArray => { + idlArray.add_untested_idls("[Exposed=(Window,Worker)] interface ArrayBuffer {};"); + + idlArray.add_objects({ + PublicKeyCredential: ['cred', 'assertion'], + AuthenticatorAttestationResponse: ['cred.response'], + AuthenticatorAssertionResponse: ['assertion.response'] + }); + + const challengeBytes = new Uint8Array(16); + window.crypto.getRandomValues(challengeBytes); + + self.cred = await Promise.race([ + new Promise((_, reject) => window.setTimeout(() => { + reject('Timed out waiting for user to touch security key') + }, 3000)), + createCredential({ + options: { + publicKey: { + timeout: 3000, + user: { + id: new Uint8Array(16), + }, + } + } + }), + ]); + + self.assertion = await navigator.credentials.get({ + publicKey: { + timeout: 3000, + allowCredentials: [{ + id: cred.rawId, + transports: ["usb", "nfc", "ble"], + type: "public-key" + }], + challenge: challengeBytes, + } + }); + } +);
diff --git a/third_party/blink/web_tests/external/wpt/webauthn/idlharness.https.window.js b/third_party/blink/web_tests/external/wpt/webauthn/idlharness.https.window.js index fa5e812..ff0efcb 100644 --- a/third_party/blink/web_tests/external/wpt/webauthn/idlharness.https.window.js +++ b/third_party/blink/web_tests/external/wpt/webauthn/idlharness.https.window.js
@@ -11,38 +11,11 @@ ['webauthn'], ['credential-management'], async idlArray => { - idlArray.add_untested_idls("[Exposed=(Window,Worker)] interface ArrayBuffer {};"); - idlArray.add_objects({ - WebAuthentication: ['navigator.authentication'], - PublicKeyCredential: ['cred', 'assertion'], - AuthenticatorAttestationResponse: ['cred.response'], - AuthenticatorAssertionResponse: ['assertion.response'] - }); - - const challengeBytes = new Uint8Array(16); - window.crypto.getRandomValues(challengeBytes); - - self.cred = await createCredential({ - options: { - publicKey: { - timeout: 3000, - user: { - id: new Uint8Array(16), - }, - } - } - }); - - self.assertion = await navigator.credentials.get({ - publicKey: { - timeout: 3000, - allowCredentials: [{ - id: cred.rawId, - transports: ["usb", "nfc", "ble"], - type: "public-key" - }], - challenge: challengeBytes, - } - }); + // NOTE: The following are tested in idlharness-manual.https.window.js: + // idlArray.add_objects({ + // PublicKeyCredential: ['cred', 'assertion'], + // AuthenticatorAttestationResponse: ['cred.response'], + // AuthenticatorAssertionResponse: ['assertion.response'] + // }); } );
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index ae80a51..22827a0 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -36100,6 +36100,7 @@ <int value="1620369597" label="enable-unsafe-webgpu"/> <int value="1621298798" label="VrBrowserKeyboard:enabled"/> <int value="1622131033" label="ozone-test-single-overlay-support"/> + <int value="1624443254" label="AnimatedAvatarButton:disabled"/> <int value="1626824478" label="ExperimentalAppBanners:disabled"/> <int value="1628831121" label="SafeBrowsingUseLocalBlacklistsV2:enabled"/> <int value="1630988998" label="VrBrowsingExperimentalRendering:disabled"/> @@ -36292,6 +36293,7 @@ <int value="1896527497" label="ImmersiveUiMode:enabled"/> <int value="1898231011" label="enable-native-notifications"/> <int value="1900529524" label="disable-touch-drag-drop"/> + <int value="1903290829" label="AnimatedAvatarButton:enabled"/> <int value="1905465678" label="ContextualSearchSingleActions:enabled"/> <int value="1906942630" label="enable-easy-unlock"/> <int value="1910240042" label="enable-experimental-fullscreen-exit-ui"/> @@ -60085,6 +60087,7 @@ <int value="9" label="WindowOpened"/> <int value="10" label="NotValidManifestForWebApp"/> <int value="11" label="IntentToPlayStore"/> + <int value="12" label="WebAppDisabled"/> </enum> <enum name="WebAppInstallSource">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index dd57d01..f5ca20b 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -103265,6 +103265,9 @@ </histogram> <histogram name="PrintPreview.PageCount.Initial" expires_after="M77"> + <obsolete> + Deprecated 07/2019. + </obsolete> <owner>thestig@chromium.org</owner> <summary> The page count of the initial print preview, a.k.a. the total number of @@ -103273,6 +103276,9 @@ </histogram> <histogram name="PrintPreview.PageCount.OpenInMacPreview" expires_after="M77"> + <obsolete> + Deprecated 07/2019. + </obsolete> <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed to PDF and @@ -103281,6 +103287,9 @@ </histogram> <histogram name="PrintPreview.PageCount.PrintToCloudPrint"> + <obsolete> + Deprecated 07/2019. + </obsolete> <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed to a cloud @@ -103301,6 +103310,9 @@ </histogram> <histogram name="PrintPreview.PageCount.PrintToGoogleDrive" expires_after="M77"> + <obsolete> + Deprecated 07/2019. + </obsolete> <owner>rbpotter@chromium.org</owner> <owner>thestig@chromium.org</owner> <summary> @@ -103310,6 +103322,9 @@ </histogram> <histogram name="PrintPreview.PageCount.PrintToPDF"> + <obsolete> + Deprecated 07/2019. + </obsolete> <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed to PDF. @@ -103317,6 +103332,9 @@ </histogram> <histogram name="PrintPreview.PageCount.PrintToPrinter"> + <obsolete> + Deprecated 07/2019. + </obsolete> <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed to a @@ -103325,6 +103343,9 @@ </histogram> <histogram name="PrintPreview.PageCount.PrintWithExtension"> + <obsolete> + Deprecated 07/2019. + </obsolete> <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed to an @@ -103333,6 +103354,9 @@ </histogram> <histogram name="PrintPreview.PageCount.PrintWithPrivet"> + <obsolete> + Deprecated 07/2019. + </obsolete> <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed to a privet @@ -103341,6 +103365,9 @@ </histogram> <histogram name="PrintPreview.PageCount.SystemDialog"> + <obsolete> + Deprecated 07/2019. + </obsolete> <owner>thestig@chromium.org</owner> <summary> The final page count (after page selection) of documents printed using @@ -122535,12 +122562,17 @@ </histogram> <histogram name="Signin.ListAccountsRetry" enum="GoogleServiceAuthError" - expires_after="M77"> + expires_after="never"> +<!-- expires-never: ListAccounts calls are used to monitor the accounts in the +Gaia cookies. This is a mandatory step for account reconcilor and therefore +should be kept for as long as Chrome continues to reconciles accounts between +the browser and content area. --> + <owner>msarda@chromium.org</owner> <owner>droger@chromium.org</owner> <summary> - Retry reason of failed ListAccounts call during Chrome OS login during - account reconciliation, Chrome OS login, or signin internals queries. + Retry reason of failed ListAccounts calls (these calls calls are used to + fetch the list of Google accounts present in the Gaia cookies). </summary> </histogram> @@ -122631,7 +122663,10 @@ </histogram> <histogram name="Signin.OAuth2TokenGetRetry" enum="GoogleServiceAuthError" - expires_after="M77"> + expires_after="never"> +<!-- expires-never: This reports the retry reason for fetching OAuth 2.0 access +tokens and is needed for as long as Chrome is fetching access tokens. --> + <owner>msarda@chromium.org</owner> <owner>droger@chromium.org</owner> <summary> @@ -122720,7 +122755,8 @@ </summary> </histogram> -<histogram name="Signin.Reconciler.ExternalCcResultTime.Completed"> +<histogram name="Signin.Reconciler.ExternalCcResultTime.Completed" units="ms" + expires_after="2020-06-14"> <owner>msarda@chromium.org</owner> <owner>droger@chromium.org</owner> <summary> @@ -126670,7 +126706,7 @@ <summary>Tracks when mixed content is displayed or run.</summary> </histogram> -<histogram name="SSORecallPromo.AccountsAvailable" expires_after="M77"> +<histogram name="SSORecallPromo.AccountsAvailable" expires_after="2020-11-30"> <owner>msarda@chromium.org</owner> <summary> Number of accounts available for Single Sign On with the current device, @@ -126679,14 +126715,14 @@ </histogram> <histogram name="SSORecallPromo.PromoAction" enum="SSOPromoUserAction" - expires_after="M77"> + expires_after="2020-11-30"> <owner>msarda@chromium.org</owner> <summary> Action the user takes when the Single Sign On promotion is shown. </summary> </histogram> -<histogram name="SSORecallPromo.PromoSeenCount" expires_after="M77"> +<histogram name="SSORecallPromo.PromoSeenCount" expires_after="2020-11-30"> <owner>msarda@chromium.org</owner> <summary> Number of times the promotion has been seen on the current device.
diff --git a/ui/chromeos/resources/default_100_percent/fingerprint/fingerprint_scanner_laptop.png b/ui/chromeos/resources/default_100_percent/fingerprint/fingerprint_scanner_laptop_bottom_right.png similarity index 100% rename from ui/chromeos/resources/default_100_percent/fingerprint/fingerprint_scanner_laptop.png rename to ui/chromeos/resources/default_100_percent/fingerprint/fingerprint_scanner_laptop_bottom_right.png Binary files differ
diff --git a/ui/chromeos/resources/default_100_percent/fingerprint/fingerprint_scanner_laptop_top_right.png b/ui/chromeos/resources/default_100_percent/fingerprint/fingerprint_scanner_laptop_top_right.png new file mode 100644 index 0000000..2a3e52b --- /dev/null +++ b/ui/chromeos/resources/default_100_percent/fingerprint/fingerprint_scanner_laptop_top_right.png Binary files differ
diff --git a/ui/chromeos/resources/default_100_percent/fingerprint/fingerprint_scanner.png b/ui/chromeos/resources/default_100_percent/fingerprint/fingerprint_scanner_tablet_power_button.png similarity index 100% rename from ui/chromeos/resources/default_100_percent/fingerprint/fingerprint_scanner.png rename to ui/chromeos/resources/default_100_percent/fingerprint/fingerprint_scanner_tablet_power_button.png Binary files differ
diff --git a/ui/chromeos/resources/default_200_percent/fingerprint/fingerprint_scanner_laptop.png b/ui/chromeos/resources/default_200_percent/fingerprint/fingerprint_scanner_laptop_bottom_right.png similarity index 100% rename from ui/chromeos/resources/default_200_percent/fingerprint/fingerprint_scanner_laptop.png rename to ui/chromeos/resources/default_200_percent/fingerprint/fingerprint_scanner_laptop_bottom_right.png Binary files differ
diff --git a/ui/chromeos/resources/default_200_percent/fingerprint/fingerprint_scanner_laptop_top_right.png b/ui/chromeos/resources/default_200_percent/fingerprint/fingerprint_scanner_laptop_top_right.png new file mode 100644 index 0000000..68f6f92 --- /dev/null +++ b/ui/chromeos/resources/default_200_percent/fingerprint/fingerprint_scanner_laptop_top_right.png Binary files differ
diff --git a/ui/chromeos/resources/default_200_percent/fingerprint/fingerprint_scanner.png b/ui/chromeos/resources/default_200_percent/fingerprint/fingerprint_scanner_tablet_power_button.png similarity index 100% rename from ui/chromeos/resources/default_200_percent/fingerprint/fingerprint_scanner.png rename to ui/chromeos/resources/default_200_percent/fingerprint/fingerprint_scanner_tablet_power_button.png Binary files differ
diff --git a/ui/chromeos/resources/ui_chromeos_resources.grd b/ui/chromeos/resources/ui_chromeos_resources.grd index cb7aa2b..4371033 100644 --- a/ui/chromeos/resources/ui_chromeos_resources.grd +++ b/ui/chromeos/resources/ui_chromeos_resources.grd
@@ -96,8 +96,9 @@ <!-- Fingerprint images. --> <structure type="chrome_scaled_image" name="IDR_LOGIN_FINGERPRINT_ICON_ANIMATION" file="fingerprint/fingerprint.png" /> <structure type="chrome_scaled_image" name="IDR_LOGIN_FINGERPRINT_ENROLLMENT_COMPLETE_ANIMATION" file="fingerprint/tick.png" /> - <structure type="chrome_scaled_image" name="IDR_LOGIN_FINGERPRINT_SCANNER_TABLET_ANIMATION" file="fingerprint/fingerprint_scanner.png" /> - <structure type="chrome_scaled_image" name="IDR_LOGIN_FINGERPRINT_SCANNER_LAPTOP_ANIMATION" file="fingerprint/fingerprint_scanner_laptop.png" /> + <structure type="chrome_scaled_image" name="IDR_LOGIN_FINGERPRINT_SCANNER_TABLET_POWER_BUTTON_ANIMATION" file="fingerprint/fingerprint_scanner_tablet_power_button.png" /> + <structure type="chrome_scaled_image" name="IDR_LOGIN_FINGERPRINT_SCANNER_LAPTOP_BOTTOM_RIGHT_ANIMATION" file="fingerprint/fingerprint_scanner_laptop_bottom_right.png" /> + <structure type="chrome_scaled_image" name="IDR_LOGIN_FINGERPRINT_SCANNER_LAPTOP_TOP_RIGHT_ANIMATION" file="fingerprint/fingerprint_scanner_laptop_top_right.png" /> </structures> </release>
diff --git a/ui/file_manager/file_manager/foreground/elements/files_metadata_entry.html b/ui/file_manager/file_manager/foreground/elements/files_metadata_entry.html index 9e97a727..28b7676 100644 --- a/ui/file_manager/file_manager/foreground/elements/files_metadata_entry.html +++ b/ui/file_manager/file_manager/foreground/elements/files_metadata_entry.html
@@ -44,29 +44,20 @@ width: 160px; } - #value[loading] { - /* TODO(crbug.com/965370) loading is only set on |size| metatdata of a - directory entry. This font-size makes the modificationTime value that - appears below it, render further down from its normal position. Once - the size is loaded, this "loading" CSS is removed & modificationTime - renders in its normal position: visual effect is the modificationTime - "bounces" around in the metadata box. */ - font-size: 30px; - } - #value[loading]::after { - /* TODO(crbug.com/965370) see above */ - animation: ellipsis steps(4,end) 900ms infinite; - content: '\2026'; /* ascii code for the ellipsis character */ + animation: ellipsis 1s steps(4,end) 100ms infinite; + content: '\2026'; /* Unicode horizontal ellipsis */ display: inline-block; overflow: hidden; + transform: scale(2.5) translate(0, 1px); + transform-origin: left bottom; vertical-align: bottom; width: 0; } @keyframes ellipsis { to { - width: 1.25em; + width: 0.93em; } } @@ -87,13 +78,10 @@ } </style> <div id="box" hidden="[[!value]]"> + <!--TODO(crbug.com/965370): remove this useless <div>. If we want padding + before #key, use CSS start margin or padding to do that. --> <div id="padding"></div> <div id="key">[[key]]</div> - <!-- TODO(crbug.com/965370) The loading animation is only applied to a - directory entry size metadata field at this time. On switching to - another directory, the size field value is cleared, and that hides - our <div id="box"> parent. Result: the #value[loading] animation - applied here _is never visible_! --> <div id="value" loading$="{{loading}}"> <div hidden="[[loading]]">[[value]]</div> </div>
diff --git a/ui/file_manager/file_manager/foreground/elements/xf_panel_item.js b/ui/file_manager/file_manager/foreground/elements/xf_panel_item.js index 94922ac6..dbc70bb 100644 --- a/ui/file_manager/file_manager/foreground/elements/xf_panel_item.js +++ b/ui/file_manager/file_manager/foreground/elements/xf_panel_item.js
@@ -31,6 +31,12 @@ /** @public {?DisplayPanel} */ this.parent = null; + + /** + * Callback that signals events happening in the panel (e.g. click). + * @private @type {!function(*)} + */ + this.signal_ = console.log; } /** @@ -111,14 +117,9 @@ switch (type) { case this.panelTypeProgress: this.setAttribute('indicator', 'progress'); - primaryButton = document.createElement('xf-button'); - primaryButton.id = 'primary-action'; - primaryButton.dataset.category = 'pause'; - primaryButton.setAttribute('aria-label', '$i18n{PAUSE_LABEL}'); - buttonSpacer.insertAdjacentElement('beforebegin', primaryButton); - secondaryButton = document.createElement('xf-button'); secondaryButton.id = 'secondary-action'; + secondaryButton.onclick = this.onclick; secondaryButton.dataset.category = 'cancel'; secondaryButton.setAttribute('aria-label', '$i18n{CANCEL_LABEL}'); buttonSpacer.insertAdjacentElement('afterend', secondaryButton); @@ -136,6 +137,7 @@ this.setAttribute('status', 'success'); primaryButton = document.createElement('xf-button'); primaryButton.id = 'primary-action'; + primaryButton.onclick = this.onclick; primaryButton.dataset.category = 'dismiss'; buttonSpacer.insertAdjacentElement('beforebegin', primaryButton); @@ -149,6 +151,7 @@ this.setAttribute('status', 'failure'); secondaryButton = document.createElement('xf-button'); secondaryButton.id = 'secondary-action'; + secondaryButton.onclick = this.onclick; secondaryButton.dataset.category = 'retry'; buttonSpacer.insertAdjacentElement('afterend', secondaryButton); break; @@ -275,6 +278,61 @@ } /** + * DOM connected. + * @private + */ + connectedCallback() { + this.onclick = this.onClicked_.bind(this); + } + + /** + * DOM disconnected. + * @private + */ + disconnectedCallback() { + // Replace references to any signal callback. + this.signal_ = console.log; + + // Clear click event handler references. + let button = this.shadowRoot.querySelector('#primary-action'); + if (button) { + button.onclick = null; + } + button = this.shadowRoot.querySelector('#secondary-action'); + if (button) { + button.onclick = null; + } + this.onclick = null; + } + + /** + * Handles 'click' events from our sub-elements and sends + * signals to the |signal_| callback if needed. + * @param {?Event} event + * @private + */ + onClicked_(event) { + event.stopImmediatePropagation(); + event.preventDefault(); + + // Ignore clicks on the panel item itself. + if (event.target === this) { + return; + } + + let id = assert(event.target.dataset.category); + this.signal_(id); + } + + /** + * Sets the callback that triggers signals from events on the panel. + * @param {?function(*)} signal + */ + set signalCallback(signal) { + this.signal_ = signal || console.log; + } + + /** * Setter to set the indicator type. * @param {string} indicator Progress (optionally large) or status. */
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js index 5e9097f..a9ce6b4 100644 --- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js +++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
@@ -1360,6 +1360,13 @@ return false; } + const sourceUrls = (clipboardData.getData('fs/sources') || '').split('\n'); + // If the destination is sub-tree of any of the sources paste isn't allowed. + const destinationUrl = destinationEntry.toURL(); + if (sourceUrls.some(source => destinationUrl.startsWith(source))) { + return false; + } + // Destination entry needs the 'canAddChildren' permission. const metadata = this.metadataModel_.getCache([destinationEntry], ['canAddChildren']);
diff --git a/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js b/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js index 74d5b06..c20e0aff 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js +++ b/ui/file_manager/file_manager/foreground/js/metadata_box_controller.js
@@ -65,11 +65,13 @@ /** * Initialize the controller with quick view which will be lazily loaded. + * + * TODO(oka): store quickViewModel_.metadataBoxActive state to persistent + * storage using FilesApp window.appState? + * * @param{!FilesQuickView} quickView */ MetadataBoxController.prototype.init = function(quickView) { - // TODO(oka): Add storage to persist the value of - // quickViewModel_.metadataBoxActive. this.fileMetadataFormatter_.addEventListener( 'date-time-format-changed', this.updateView_.bind(this)); @@ -233,6 +235,10 @@ /** * Set a current directory's size in metadata box. + * + * A loading animation is shown while fetching the directory size. However, it + * won't show if there is no size value. Use a dummy value ' ' in that case. + * * If previous getDirectorySize is still running, next getDirectorySize is not * called at the time. After the previous callback is finished, getDirectorySize * that corresponds to the last setDirectorySize_ is called. @@ -248,6 +254,10 @@ return; } + if (this.metadataBox_.size === '') { + this.metadataBox_.size = ' '; // Provide a dummy size value. + } + if (this.isDirectorySizeLoading_) { if (!isSameEntry) { this.metadataBox_.isSizeLoading = true; @@ -262,9 +272,11 @@ // false if the entry is same. true if the entry is changed. this.metadataBox_.isSizeLoading = !isSameEntry; + this.isDirectorySizeLoading_ = true; chrome.fileManagerPrivate.getDirectorySize(entry, size => { this.isDirectorySizeLoading_ = false; + if (this.onDirectorySizeLoaded_) { setTimeout(this.onDirectorySizeLoaded_.bind(null, entry)); this.onDirectorySizeLoaded_ = null; @@ -279,7 +291,7 @@ return; } - this.metadataBox_.isSizeLoading = false; this.metadataBox_.size = this.fileMetadataFormatter_.formatSize(size, true); + this.metadataBox_.isSizeLoading = false; }); };
diff --git a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js index 305f59f..94c98f2 100644 --- a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js +++ b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
@@ -717,6 +717,58 @@ /** * Tests context menu for MyFiles, Downloads and sub-folder. */ + testcase.dirContextMenuMyFilesWithPaste = async () => { + const myFilesMenus = [ + ['#share-with-linux', true], + ['#new-folder', true], + ]; + const downloadsMenus = [ + ['#cut', false], + ['#copy', true], + ['#paste-into-folder', true], + ['#share-with-linux', true], + ['#delete', false], + ['#new-folder', true], + ]; + const photosMenus = [ + ['#cut', true], + ['#copy', true], + ['#paste-into-folder', false], + ['#share-with-linux', true], + ['#rename', true], + ['#delete', true], + ['#new-folder', true], + ]; + // Open Files app on local Downloads. + const appId = await setupAndWaitUntilReady( + RootPath.DOWNLOADS, [ENTRIES.beautiful, ENTRIES.photos, ENTRIES.hello], + []); + + // Select and copy hello.txt into the clipboard to test paste-into-folder + // command. + chrome.test.assertTrue( + !!await remoteCall.callRemoteTestUtil('selectFile', appId, ['photos']), + 'selectFile failed'); + chrome.test.assertTrue( + !!await remoteCall.callRemoteTestUtil('execCommand', appId, ['copy']), + 'execCommand failed'); + + // Check the context menu is on desired state for MyFiles. + await checkContextMenu( + appId, '/My files', myFilesMenus, false /* rootMenu */); + + // Check the context menu for MyFiles>Downloads. + await checkContextMenu( + appId, '/My files/Downloads', downloadsMenus, false /* rootMenu */); + + // Check the context menu for MyFiles>Downloads>photos. + await checkContextMenu( + appId, '/My files/Downloads/photos', photosMenus, false /* rootMenu */); + }; + + /** + * Tests context menu for MyFiles, Downloads and sub-folder. + */ testcase.dirContextMenuMyFiles = async () => { const myFilesMenus = [ ['#share-with-linux', true],
diff --git a/ui/gfx/x/x11.h b/ui/gfx/x/x11.h index 3a93a98..f53865fc 100644 --- a/ui/gfx/x/x11.h +++ b/ui/gfx/x/x11.h
@@ -121,13 +121,13 @@ // The x11 namespace allows to scope X11 constants and types that // would be problematic at the default preprocessor level. namespace x11 { -static const long None = 0L; -static const long CurrentTime = 0L; -static const int False = 0; -static const int True = 1; -static const int Success = 0; -static const int FocusIn = 9; -static const int FocusOut = 10; +static constexpr unsigned long None = 0L; +static constexpr long CurrentTime = 0L; +static constexpr int False = 0; +static constexpr int True = 1; +static constexpr int Success = 0; +static constexpr int FocusIn = 9; +static constexpr int FocusOut = 10; typedef int Bool; typedef int Status; } // namespace x11
diff --git a/ui/ozone/demo/vulkan_renderer.cc b/ui/ozone/demo/vulkan_renderer.cc index 2650398f..945937f 100644 --- a/ui/ozone/demo/vulkan_renderer.cc +++ b/ui/ozone/demo/vulkan_renderer.cc
@@ -223,8 +223,8 @@ /* .color = */ {/* .float32 = */ {.5f, 1.f - NextFraction(), .5f, 1.f}}}; gpu::VulkanSwapChain* vulkan_swap_chain = vulkan_surface_->GetSwapChain(); + const uint32_t image = vulkan_swap_chain->current_image(); gpu::VulkanSwapChain::ScopedWrite scoped_write(vulkan_swap_chain); - const uint32_t image = scoped_write.image_index(); { auto& framebuffer = framebuffers_[image]; if (!framebuffer) { @@ -305,7 +305,7 @@ device_queue_->GetFenceHelper()->EnqueueSemaphoreCleanupForSubmittedWork( begin_semaphore); } - vulkan_surface_->SwapBuffers(); + vulkan_swap_chain->SwapBuffers(); PostRenderFrameTask(); }