diff --git a/DEPS b/DEPS index a6751a9..1549c82 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '14987ebb97f491f1b5bc776252b5ddbf65b8fca0', + 'skia_revision': '2e2b27fcc1505e23453b773e1de081fc7aa589e9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '07b2253a044bffa43697c6a43aaccb68c7e82af4', + 'v8_revision': '2e0c8d2cbba7f0e7c00dee5331216df452288514', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -52,7 +52,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '60e17eab29b66d096ef315ec59974c3aebd57ba4', + 'angle_revision': 'fa416b18e3903d2f0bb6d7a9b6ac34e3e658b1bc', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '1b22880748c3f3b3740699ae4c953a33f65ad10f', + 'pdfium_revision': 'bf58fbb14a8b235fb864fbc45c353174446da4ca', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -232,7 +232,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '052975e1c555cdc2414d93b7965368367274a936', # commit position 17551 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'b2ae98c63ccf9f50e86efd69975999428aca318d', # commit position 17566 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'),
diff --git a/WATCHLISTS b/WATCHLISTS index d112719d..dd6d356 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -2171,6 +2171,7 @@ 'subresource_filter': ['subresource-filter-reviews@chromium.org'], 'supervised_users': ['pam+watch@chromium.org'], 'swreporter': ['alito+watch@chromium.org', + 'csharp+watch@chromium.org', 'ftirelo+watch@chromium.org', 'joenotcharles+watch@chromium.org'], 'sync': ['sync-reviews@chromium.org'],
diff --git a/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java b/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java index cd1d0dc..ccf38aba 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java +++ b/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java
@@ -4,7 +4,6 @@ package org.chromium.android_webview; -import android.content.Intent; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -149,19 +148,6 @@ } @Override - public void startContentIntent(Intent intent, String contentUrl, boolean isMainFrame) { - // Make sure that this URL is a valid scheme for this callback if interpreted as an intent, - // even though we don't dispatch it as an intent here, because many WebView apps will once - // it reaches them. - assert intent != null; - - // Comes from WebViewImpl::detectContentOnTouch in Blink, so must be user-initiated, and - // isn't a redirect. - mContentsClient.shouldIgnoreNavigation( - mContainerView.getContext(), contentUrl, isMainFrame, true, false); - } - - @Override public ViewGroup getContainerView() { return mContainerView; }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java index a5c1b89b..c45e920 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
@@ -14,7 +14,6 @@ import org.chromium.android_webview.test.util.JSUtils; import org.chromium.base.annotations.SuppressFBWarnings; import org.chromium.base.test.util.CallbackHelper; -import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; @@ -22,7 +21,6 @@ import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper; import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageStartedHelper; import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnReceivedErrorHelper; -import org.chromium.content.common.ContentSwitches; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.common.ContentUrlConstants; import org.chromium.net.test.util.TestWebServer; @@ -40,15 +38,6 @@ private static final String REDIRECT_TARGET_PATH = "/redirect_target.html"; private static final String TITLE = "TITLE"; private static final String TAG = "AwContentsClientShouldOverrideUrlLoadingTest"; - private static final String TEST_EMAIL = "nobody@example.org"; - private static final String TEST_EMAIL_URI = "mailto:" + TEST_EMAIL.replace("@", "%40"); - private static final String TEST_PHONE = "+16503336000"; - private static final String TEST_PHONE_URI = "tel:" + TEST_PHONE.replace("+", "%2B"); - // Use the shortest possible address to ensure it fits into one line. - // Otherwise, click on the center of the HTML element may get into empty space. - private static final String TEST_ADDRESS = "1 st. long enough, CA 90000"; - private static final String TEST_ADDRESS_URI = "geo:0,0?q=" - + TEST_ADDRESS.replace(" ", "+").replace(",", "%2C"); private TestWebServer mWebServer; private TestAwContentsClient mContentsClient; @@ -968,144 +957,4 @@ getActivity().setIgnoreStartActivity(false); } } - - private String setupForContentClickTest(final String content, boolean inMainFrame) - throws Exception { - final String contentId = "content"; - final String findContentJs = inMainFrame - ? "document.getElementById(\"" + contentId + "\")" - : "window.frames[0].document.getElementById(\"" + contentId + "\")"; - final String pageHtml = inMainFrame - ? "<html><body onload='document.title=" + findContentJs + ".innerText'>" - + "<span id='" + contentId + "'>" + content + "</span></body></html>" - : "<html>" - + "<body style='margin:0;' onload='document.title=" + findContentJs + ".innerText'>" - + " <iframe style='border:none;width:100%;' srcdoc=\"" - + " <body style='margin:0;'><span id='" + contentId + "'>" - + content + "</span></body>" - + "\" src='iframe.html'></iframe>" - + "</body></html>"; - final String testUrl = mWebServer.setResponse("/content_test.html", pageHtml, null); - - enableJavaScriptOnUiThread(mAwContents); - loadUrlAsync(mAwContents, testUrl); - pollUiThread(new Callable<Boolean>() { - @Override - public Boolean call() { - return mAwContents.getTitle().equals(content); - } - }); - return findContentJs; - } - - private void doTestNullContentsClientClickableContent(String pageContent, - String intentContent) throws Throwable { - try { - // The test will fire real intents through the test activity. - // Need to temporarily suppress startActivity otherwise there will be a - // handler selection window and the test can't dismiss that. - getActivity().setIgnoreStartActivity(true); - setupWithProvidedContentsClient(new NullContentsClient() { - @Override - public boolean hasWebViewClient() { - return false; - } - }); - - final String findContentJs = setupForContentClickTest(pageContent, true); - // Clicking on the content should create an intent. - DOMUtils.clickNodeByJs(mAwContents.getContentViewCore(), findContentJs); - pollUiThread(new Callable<Boolean>() { - @Override - public Boolean call() { - return getActivity().getLastSentIntent() != null; - } - }); - assertEquals(intentContent, - getActivity().getLastSentIntent().getData().toString()); - } finally { - getActivity().setIgnoreStartActivity(false); - } - } - - @SmallTest - @Feature({"AndroidWebView"}) - @CommandLineFlags.Add({ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) - public void testNullContentsClientClickableEmail() throws Throwable { - doTestNullContentsClientClickableContent(TEST_EMAIL, TEST_EMAIL_URI); - } - - @SmallTest - @Feature({"AndroidWebView"}) - @CommandLineFlags.Add({ContentSwitches.NETWORK_COUNTRY_ISO + "=us", - ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) - public void testNullContentsClientClickablePhone() throws Throwable { - doTestNullContentsClientClickableContent(TEST_PHONE, TEST_PHONE_URI); - } - - @SmallTest - @Feature({"AndroidWebView"}) - @CommandLineFlags.Add({ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) - public void testNullContentsClientClickableAddress() throws Throwable { - doTestNullContentsClientClickableContent(TEST_ADDRESS, TEST_ADDRESS_URI); - } - - private void doTestClickableContent(String pageContent, String intentContent, - boolean inMainFrame) throws Throwable { - standardSetup(); - - final String findContentJs = setupForContentClickTest(pageContent, inMainFrame); - int callCount = mShouldOverrideUrlLoadingHelper.getCallCount(); - DOMUtils.clickNodeByJs(mAwContents.getContentViewCore(), findContentJs); - mShouldOverrideUrlLoadingHelper.waitForCallback(callCount); - assertEquals(intentContent, - mShouldOverrideUrlLoadingHelper.getShouldOverrideUrlLoadingUrl()); - assertFalse(mShouldOverrideUrlLoadingHelper.isRedirect()); - assertTrue(mShouldOverrideUrlLoadingHelper.hasUserGesture()); - assertEquals(inMainFrame, mShouldOverrideUrlLoadingHelper.isMainFrame()); - } - - @SmallTest - @Feature({"AndroidWebView"}) - @CommandLineFlags.Add({ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) - public void testClickableEmail() throws Throwable { - doTestClickableContent(TEST_EMAIL, TEST_EMAIL_URI, true); - } - - @SmallTest - @Feature({"AndroidWebView"}) - @CommandLineFlags.Add({ContentSwitches.NETWORK_COUNTRY_ISO + "=us", - ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) - public void testClickablePhone() throws Throwable { - doTestClickableContent(TEST_PHONE, TEST_PHONE_URI, true); - } - - @SmallTest - @Feature({"AndroidWebView"}) - @CommandLineFlags.Add({ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) - public void testClickableAddress() throws Throwable { - doTestClickableContent(TEST_ADDRESS, TEST_ADDRESS_URI, true); - } - - @SmallTest - @Feature({"AndroidWebView"}) - @CommandLineFlags.Add({ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) - public void testClickableEmailInIframe() throws Throwable { - doTestClickableContent(TEST_EMAIL, TEST_EMAIL_URI, false); - } - - @SmallTest - @Feature({"AndroidWebView"}) - @CommandLineFlags.Add({ContentSwitches.NETWORK_COUNTRY_ISO + "=us", - ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) - public void testClickablePhoneInIframe() throws Throwable { - doTestClickableContent(TEST_PHONE, TEST_PHONE_URI, false); - } - - @SmallTest - @Feature({"AndroidWebView"}) - @CommandLineFlags.Add({ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) - public void testClickableAddressInIframe() throws Throwable { - doTestClickableContent(TEST_ADDRESS, TEST_ADDRESS_URI, false); - } }
diff --git a/ash/app_list/app_list_presenter_delegate_unittest.cc b/ash/app_list/app_list_presenter_delegate_unittest.cc index 3844f22..1f8b7161 100644 --- a/ash/app_list/app_list_presenter_delegate_unittest.cc +++ b/ash/app_list/app_list_presenter_delegate_unittest.cc
@@ -15,10 +15,18 @@ #include "ui/app_list/views/app_list_view.h" #include "ui/aura/test/test_windows.h" #include "ui/aura/window.h" -#include "ui/display/manager/display_manager.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" #include "ui/events/test/event_generator.h" namespace ash { +namespace { + +int64_t GetPrimaryDisplayId() { + return display::Screen::GetScreen()->GetPrimaryDisplay().id(); +} + +} // namespace class AppListPresenterDelegateTest : public test::AshTestBase { public: @@ -45,7 +53,7 @@ // Tests that app launcher hides when focus moves to a normal window. TEST_F(AppListPresenterDelegateTest, HideOnFocusOut) { - app_list_presenter_impl()->Show(display_manager()->first_display_id()); + app_list_presenter_impl()->Show(GetPrimaryDisplayId()); EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); @@ -58,7 +66,7 @@ // window in kShellWindowId_AppListContainer. TEST_F(AppListPresenterDelegateTest, RemainVisibleWhenFocusingToApplistContainer) { - app_list_presenter_impl()->Show(display_manager()->first_display_id()); + app_list_presenter_impl()->Show(GetPrimaryDisplayId()); EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); aura::Window* applist_container = Shell::GetContainer( @@ -72,7 +80,7 @@ // Tests that clicking outside the app-list bubble closes it. TEST_F(AppListPresenterDelegateTest, ClickOutsideBubbleClosesBubble) { - app_list_presenter_impl()->Show(display_manager()->first_display_id()); + app_list_presenter_impl()->Show(GetPrimaryDisplayId()); aura::Window* app_window = app_list_presenter_impl()->GetWindow(); ASSERT_TRUE(app_window); ui::test::EventGenerator& generator = GetEventGenerator(); @@ -93,7 +101,7 @@ // Tests that clicking outside the app-list bubble closes it. TEST_F(AppListPresenterDelegateTest, TapOutsideBubbleClosesBubble) { - app_list_presenter_impl()->Show(display_manager()->first_display_id()); + app_list_presenter_impl()->Show(GetPrimaryDisplayId()); aura::Window* app_window = app_list_presenter_impl()->GetWindow(); ASSERT_TRUE(app_window); @@ -140,7 +148,7 @@ // Set up a screen with a tiny display (height smaller than the app list). UpdateDisplay("400x300"); - app_list_presenter_impl()->Show(display_manager()->first_display_id()); + app_list_presenter_impl()->Show(GetPrimaryDisplayId()); EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility()); // The top of the app list should be on-screen (even if the bottom is not).
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 69ff7306..86afc07 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -440,9 +440,6 @@ <message name="IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_TITLE" desc="The title of a notification indicating that a low-current USB charger has been connected."> Low-power charger connected </message> - <message name="IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_MESSAGE" desc="The message body of a notification indicating that a low-current USB charger has been connected."> - Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> may not charge while it is turned on. Consider using the official charger. - </message> <message name="IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_MESSAGE_SHORT" desc="The message body of a notification indicating that a low-current USB charger has been connected, short version."> Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> may not charge while it is turned on. </message> @@ -492,10 +489,6 @@ USB-C device </message> - <message name="IDS_CHARGER_REPLACEMENT_ACCESSIBILITY_NOTIFICATION" desc="The notification string used in accessibility to tell user to contact Google for replacing the possible bad charger."> - You may have a bad charger. If you live in the US, please call 866-628-1371 in order to receive help and a replacement. If you live in the UK, please call 0800-026-0613. If you live in Ireland, please call 1-800-832-664. If you live in Canada, please call 866-628-1372. If you live in Australia, please call 1-800-067-460. - </message> - <!-- Status Tray Network strings --> <message name="IDS_ASH_STATUS_TRAY_NETWORK" desc="The label used in the network dialog header."> Network @@ -515,9 +508,6 @@ <message name="IDS_ASH_STATUS_TRAY_VPN_DISCONNECT" desc="Message on button that disconnects from the current VPN."> Disconnect </message> - <message name="IDS_ASH_STATUS_TRAY_VPN_MONITORED" desc="The label used when a VPN connection may be monitored."> - Connection may be monitored - </message> <message name="IDS_ASH_STATUS_TRAY_WIFI_ADDRESS" desc="The label for the mac address of the wifi device."> Wi-Fi: <ph name="ADDRESS">$1<ex>23:45:67:89:AB:CD</ex></ph> </message> @@ -536,39 +526,12 @@ <message name="IDS_ASH_STATUS_TRAY_NETWORK_PROXY_SETTINGS" desc="The label used in the proxy settings entry in the network dialog in the login screen."> Proxy settings </message> - <message name="IDS_ASH_STATUS_TRAY_NETWORK_TECHNOLOGY_ENFORCED_BY_POLICY" desc="The label used for tell users that this technology is disabled by the administrator"> - This network setting is disabled by the administrator. - </message> - <message name="IDS_ASH_STATUS_TRAY_ENABLE_WIFI" desc="The label used for the item to enable wifi."> - Enable Wi-Fi - </message> - <message name="IDS_ASH_STATUS_TRAY_DISABLE_WIFI" desc="The label used for the item to disable wifi."> - Disable Wi-Fi - </message> <message name="IDS_ASH_STATUS_TRAY_OTHER_WIFI" desc="The label used for the item to display other Wi-Fi networks."> Join other... </message> <message name="IDS_ASH_STATUS_TRAY_EXTENSION_CONTROLLED_WIFI" desc="The accessible text for the badge in the detailed network list indicating that the respective network's configuration may be controlled by an extension."> The extension "<ph name="EXTENSION_NAME">$1<ex>Nexus S</ex></ph>" can help connect to this network. </message> - <message name="IDS_ASH_STATUS_TRAY_TURN_ON_WIFI" desc="The label used for the item to turn on Wi-Fi networks."> - Turn Wi-Fi on - </message> - <message name="IDS_ASH_STATUS_TRAY_ENABLE_MOBILE" desc="The label used for the item to enable mobile networks."> - Enable mobile data - </message> - <message name="IDS_ASH_STATUS_TRAY_DISABLE_MOBILE" desc="The label used for the item to disable mobile networks."> - Disable mobile data - </message> - <message name="IDS_ASH_STATUS_TRAY_SETUP_MOBILE" desc="The label used for the item to setup mobile network when no SIM card in installed."> - Set up mobile data - </message> - <message name="IDS_ASH_STATUS_TRAY_OTHER_MOBILE" desc="The label used for the item to display other mobile networks."> - Mobile ... - </message> - <message name="IDS_ASH_STATUS_TRAY_MOBILE_VIEW_ACCOUNT" desc="In the network popup bubble, the text of the top-up URL link."> - View mobile account - </message> <message name="IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERABLE" desc="Notification shown when a Bluetooth adapter is discoverable."> Your computer is discoverable to nearby Bluetooth devices and will appear as "<ph name="NAME">$1<ex>Chromebook</ex></ph>" with address <ph name="ADDRESS">$2<ex>01:23:45:67:89:0A</ex></ph> </message> @@ -601,12 +564,6 @@ <message name="IDS_DESKTOP_CASTING_ACTIVE_MESSAGE" desc="The message for the dialog which tells the user that desktop casting is in progress, asking if the casting should be stopped before switching - or - the switch should be aborted."> Screen sharing will stop when you switch to another user. Do you want to continue? </message> - <message name="IDS_DESKTOP_CASTING_ACTIVE_BUTTON_SWITCH_USER" desc="The button label for the dialog which tells the user that desktop casting is in progress. By selecting this button the casting will be stopped and the user will get switched."> - Yes - </message> - <message name="IDS_DESKTOP_CASTING_ACTIVE_BUTTON_ABORT_USER_SWITCH" desc="The button label for the dialog which tells the user that desktop casting is in progress. By selecting this button the user switch will be cancelled."> - No - </message> <!-- Status tray screen capture strings. --> <message name="IDS_ASH_STATUS_TRAY_SCREEN_CAPTURE_STOP" desc="label used for screen capture stop button"> @@ -767,14 +724,6 @@ CAPS LOCK is on. Press Search or Shift to cancel. </message> - <message name="IDS_ASH_STATUS_TRAY_IME_TURNED_ON_BUBBLE" desc="The message shown on a bubble when an IME is enabled"> - Your input method has changed to <ph name="INPUT_METHOD_ID">$1<ex>EN</ex></ph>. - Press Shift + Alt to switch. - </message> - <message name="IDS_ASH_STATUS_TRAY_THIRD_PARTY_IME_TURNED_ON_BUBBLE" desc="The message shown on a bubble when a third party IME is enabled"> - Your input method has changed to <ph name="INPUT_METHOD_ID">$1<ex>EN</ex></ph>*(<ph name="BEGIN_LINK"><a target="_blank" href="$2"></ph>3rd party<ph name="END_LINK"></a><ex></a></ex></ph>). - Press Shift + Alt to switch. - </message> <message name="IDS_ASH_STATUS_TRAY_BATTERY_FULL" desc="The label in the tray dialog to indicate that the battery is full."> Battery full </message> @@ -882,9 +831,6 @@ <message name="IDS_ASH_STATUS_TRAY_NETWORK_PROHIBITED" desc="Tooltip in network list when no network is prohibited by policy."> This network is disabled by your administrator. </message> - <message name="IDS_ASH_STATUS_TRAY_NETWORK_PROHIBITED_OTHER" desc="Tooltip in network list for joining other network when connecting unmanaged network is prohibited"> - Connecting to other networks is disabled by your administrator. - </message> <message name="IDS_ASH_STATUS_TRAY_NO_NETWORKS" desc="The message to display in the network info bubble when it is otherwise empty."> No network information available </message>
diff --git a/ash/common/test/ash_test.h b/ash/common/test/ash_test.h index d91c4d6..f2b6bb5 100644 --- a/ash/common/test/ash_test.h +++ b/ash/common/test/ash_test.h
@@ -57,9 +57,8 @@ // real implementation. This class exists so that tests can be written to // ash/common and run in both mus and aura. // -// The implementation of AshTestImpl that is used depends upon gn targets. To -// use the aura backend depend on "//ash/test:ash_with_aura_test_support." The -// mus backend is not provided as a separate link target. +// TODO: this class is deprecated and should be removed. +// http://crbug.com/707057. class AshTest : public testing::Test { public: AshTest();
diff --git a/ash/display/display_configuration_controller_unittest.cc b/ash/display/display_configuration_controller_unittest.cc index bd3a8b3..ed007f27 100644 --- a/ash/display/display_configuration_controller_unittest.cc +++ b/ash/display/display_configuration_controller_unittest.cc
@@ -12,14 +12,7 @@ namespace ash { -class DisplayConfigurationControllerTest : public test::AshTestBase { - public: - DisplayConfigurationControllerTest() {} - ~DisplayConfigurationControllerTest() override {} - - private: - DISALLOW_COPY_AND_ASSIGN(DisplayConfigurationControllerTest); -}; +using DisplayConfigurationControllerTest = test::AshTestBase; TEST_F(DisplayConfigurationControllerTest, ErasesAnimatorOnAnimationEnded) { // TODO(wutao): needs display_configuration_controller
diff --git a/ash/display/mirror_window_controller_unittest.cc b/ash/display/mirror_window_controller_unittest.cc index 55fce11..496999f 100644 --- a/ash/display/mirror_window_controller_unittest.cc +++ b/ash/display/mirror_window_controller_unittest.cc
@@ -54,24 +54,7 @@ typedef test::AshTestBase MirrorWindowControllerTest; -#if defined(OS_WIN) -// Software mirroring does not work on win. -#define MAYBE_MirrorCursorBasic DISABLED_MirrorCursorBasic -#define MAYBE_MirrorCursorLocations DISABLED_MirrorCursorLocations -#define MAYBE_MirrorCursorMoveOnEnter DISABLED_MirrorCursorMoveOnEnter -#define MAYBE_MirrorCursorRotate DISABLED_MirrorCursorRotate -#define MAYBE_DockMode DISABLED_DockMode -#define MAYBE_MirrorOnBoot DISABLED_MirrorOnBoot -#else -#define MAYBE_MirrorCursorBasic MirrorCursorBasic -#define MAYBE_MirrorCursorLocations MirrorCursorLocations -#define MAYBE_MirrorCursorMoveOnEnter MirrorCursorMoveOnEnter -#define MAYBE_MirrorCursorRotate MirrorCursorRotate -#define MAYBE_DockMode DockMode -#define MAYBE_MirrorOnBoot MirrorOnBoot -#endif - -TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorBasic) { +TEST_F(MirrorWindowControllerTest, MirrorCursorBasic) { test::MirrorWindowTestApi test_api; aura::test::TestWindowDelegate test_window_delegate; test_window_delegate.set_window_component(HTTOP); @@ -117,7 +100,7 @@ EXPECT_TRUE(test_api.GetCursorWindow()->IsVisible()); } -TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorRotate) { +TEST_F(MirrorWindowControllerTest, MirrorCursorRotate) { test::MirrorWindowTestApi test_api; aura::test::TestWindowDelegate test_window_delegate; test_window_delegate.set_window_component(HTTOP); @@ -171,7 +154,7 @@ // Make sure that the mirror cursor's location is same as // the source display's host location in the mirror root window's // coordinates. -TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorLocations) { +TEST_F(MirrorWindowControllerTest, MirrorCursorLocations) { test::MirrorWindowTestApi test_api; display_manager()->SetMultiDisplayMode(display::DisplayManager::MIRRORING); @@ -205,7 +188,7 @@ // Test the behavior of the cursor when entering software mirror mode swaps the // cursor's display. -TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorMoveOnEnter) { +TEST_F(MirrorWindowControllerTest, MirrorCursorMoveOnEnter) { aura::Env* env = aura::Env::GetInstance(); Shell* shell = Shell::Get(); WindowTreeHostManager* window_tree_host_manager = @@ -253,7 +236,7 @@ // Make sure that the compositor based mirroring can switch // from/to dock mode. -TEST_F(MirrorWindowControllerTest, MAYBE_DockMode) { +TEST_F(MirrorWindowControllerTest, DockMode) { const int64_t internal_id = 1; const int64_t external_id = 2; @@ -297,7 +280,7 @@ EXPECT_EQ(external_id, display_manager()->mirroring_display_id()); } -TEST_F(MirrorOnBootTest, MAYBE_MirrorOnBoot) { +TEST_F(MirrorOnBootTest, MirrorOnBoot) { EXPECT_TRUE(display_manager()->IsInMirrorMode()); RunAllPendingInMessageLoop(); test::MirrorWindowTestApi test_api;
diff --git a/ash/display/root_window_transformers_unittest.cc b/ash/display/root_window_transformers_unittest.cc index 60617a1e..7fdd86a4 100644 --- a/ash/display/root_window_transformers_unittest.cc +++ b/ash/display/root_window_transformers_unittest.cc
@@ -113,12 +113,12 @@ class RootWindowTransformersTest : public test::AshTestBase { public: - RootWindowTransformersTest(){}; - ~RootWindowTransformersTest() override{}; + RootWindowTransformersTest() {} + ~RootWindowTransformersTest() override {} float GetStoredUIScale(int64_t id) { return display_manager()->GetDisplayInfo(id).GetEffectiveUIScale(); - }; + } std::unique_ptr<RootWindowTransformer> CreateCurrentRootWindowTransformerForMirroring() { @@ -132,7 +132,7 @@ return std::unique_ptr<RootWindowTransformer>( CreateRootWindowTransformerForMirroredDisplay(source_display_info, mirror_display_info)); - }; + } DISALLOW_COPY_AND_ASSIGN(RootWindowTransformersTest); }; @@ -141,19 +141,7 @@ // using RootWindowTransformersTest = test::AshTestBase; -#if defined(OS_WIN) -// TODO(scottmg): RootWindow doesn't get resized on Windows -// Ash. http://crbug.com/247916. -#define MAYBE_RotateAndMagnify DISABLED_RotateAndMagniy -#define MAYBE_TouchScaleAndMagnify DISABLED_TouchScaleAndMagnify -#define MAYBE_ConvertHostToRootCoords DISABLED_ConvertHostToRootCoords -#else -#define MAYBE_RotateAndMagnify RotateAndMagniy -#define MAYBE_TouchScaleAndMagnify TouchScaleAndMagnify -#define MAYBE_ConvertHostToRootCoords ConvertHostToRootCoords -#endif - -TEST_F(RootWindowTransformersTest, MAYBE_RotateAndMagnify) { +TEST_F(RootWindowTransformersTest, RotateAndMagnify) { MagnificationController* magnifier = Shell::Get()->magnification_controller(); TestEventHandler event_handler; @@ -295,7 +283,7 @@ Shell::Get()->RemovePreTargetHandler(&event_handler); } -TEST_F(RootWindowTransformersTest, MAYBE_TouchScaleAndMagnify) { +TEST_F(RootWindowTransformersTest, TouchScaleAndMagnify) { TestEventHandler event_handler; Shell::Get()->AddPreTargetHandler(&event_handler); @@ -330,7 +318,7 @@ Shell::Get()->RemovePreTargetHandler(&event_handler); } -TEST_F(RootWindowTransformersTest, MAYBE_ConvertHostToRootCoords) { +TEST_F(RootWindowTransformersTest, ConvertHostToRootCoords) { TestEventHandler event_handler; Shell::Get()->AddPreTargetHandler(&event_handler); MagnificationController* magnifier = Shell::Get()->magnification_controller();
diff --git a/ash/display/screen_ash_unittest.cc b/ash/display/screen_ash_unittest.cc index 4f02ab0..b89b43790 100644 --- a/ash/display/screen_ash_unittest.cc +++ b/ash/display/screen_ash_unittest.cc
@@ -6,18 +6,10 @@ #include "ash/test/ash_test_base.h" #include "ui/aura/test/test_window_delegate.h" #include "ui/aura/window.h" -#include "ui/display/manager/display_manager.h" namespace ash { -class ScreenAshTest : public test::AshTestBase { - public: - ScreenAshTest() {} - ~ScreenAshTest() override {} - - private: - DISALLOW_COPY_AND_ASSIGN(ScreenAshTest); -}; +using ScreenAshTest = test::AshTestBase; // Tests that ScreenAsh::GetWindowAtScreenPoint() returns the correct window on // the correct display.
diff --git a/ash/display/screen_position_controller_unittest.cc b/ash/display/screen_position_controller_unittest.cc index 3c9135c..554b9aac 100644 --- a/ash/display/screen_position_controller_unittest.cc +++ b/ash/display/screen_position_controller_unittest.cc
@@ -21,27 +21,6 @@ #include "ui/display/screen.h" #include "ui/events/test/event_generator.h" -#if defined(OS_WIN) -// TODO(scottmg): RootWindow doesn't get resized immediately on Windows -// Ash. http://crbug.com/247916. -#define MAYBE_ConvertHostPointToScreen DISABLED_ConvertHostPointToScreen -#define MAYBE_ConvertHostPointToScreenHiDPI \ - DISABLED_ConvertHostPointToScreenHiDPI -#define MAYBE_ConvertHostPointToScreenRotate \ - DISABLED_ConvertHostPointToScreenRotate -#define MAYBE_ConvertHostPointToScreenUIScale \ - DISABLED_ConvertHostPointToScreenUIScale -#define MAYBE_ConvertToScreenWhileRemovingSecondaryDisplay \ - DISABLED_ConvertToScreenWhileRemovingSecondaryDisplay -#else -#define MAYBE_ConvertHostPointToScreen ConvertHostPointToScreen -#define MAYBE_ConvertHostPointToScreenHiDPI ConvertHostPointToScreenHiDPI -#define MAYBE_ConvertHostPointToScreenRotate ConvertHostPointToScreenRotate -#define MAYBE_ConvertHostPointToScreenUIScale ConvertHostPointToScreenUIScale -#define MAYBE_ConvertToScreenWhileRemovingSecondaryDisplay \ - ConvertToScreenWhileRemovingSecondaryDisplay -#endif - namespace ash { namespace test { @@ -97,7 +76,7 @@ } // namespace -TEST_F(ScreenPositionControllerTest, MAYBE_ConvertHostPointToScreen) { +TEST_F(ScreenPositionControllerTest, ConvertHostPointToScreen) { // Make sure that the point is in host coordinates. (crbug.com/521919) UpdateDisplay("100+100-200x200,100+300-200x200"); // The point 150,210 should be in host coords, and detected as outside. @@ -190,7 +169,7 @@ EXPECT_EQ("50,0", ConvertHostPointToScreen(50, -400)); } -TEST_F(ScreenPositionControllerTest, MAYBE_ConvertHostPointToScreenHiDPI) { +TEST_F(ScreenPositionControllerTest, ConvertHostPointToScreenHiDPI) { UpdateDisplay("50+50-200x200*2,50+300-300x300"); aura::Window::Windows root_windows = Shell::Get()->GetAllRootWindows(); @@ -221,7 +200,7 @@ EXPECT_EQ("80,80", ConvertHostPointToScreen(160, 160)); } -TEST_F(ScreenPositionControllerTest, MAYBE_ConvertHostPointToScreenRotate) { +TEST_F(ScreenPositionControllerTest, ConvertHostPointToScreenRotate) { // 1st display is rotated 90 clockise, and 2nd display is rotated // 270 clockwise. UpdateDisplay("100+100-200x200/r,100+500-200x200/l"); @@ -253,7 +232,7 @@ EXPECT_EQ("50,149", ConvertHostPointToScreen(50, -350)); } -TEST_F(ScreenPositionControllerTest, MAYBE_ConvertHostPointToScreenUIScale) { +TEST_F(ScreenPositionControllerTest, ConvertHostPointToScreenUIScale) { // 1st display is 2x density with 1.5 UI scale. UpdateDisplay("100+100-200x200*2@1.5,100+500-200x200"); // Put |window_| to the 1st. @@ -321,7 +300,7 @@ // detached from the root window prior to the root window being destroyed. Test // that no events are dispatched at this time. TEST_F(ScreenPositionControllerTest, - MAYBE_ConvertToScreenWhileRemovingSecondaryDisplay) { + ConvertToScreenWhileRemovingSecondaryDisplay) { UpdateDisplay("600x600,600x600"); RunAllPendingInMessageLoop();
diff --git a/ash/mus/bridge/wm_shell_mus.cc b/ash/mus/bridge/wm_shell_mus.cc index 3375fec..0087718 100644 --- a/ash/mus/bridge/wm_shell_mus.cc +++ b/ash/mus/bridge/wm_shell_mus.cc
@@ -215,17 +215,17 @@ } void WmShellMus::LockCursor() { - // TODO: http::/crbug.com/637853 + // TODO: http://crbug.com/637853 NOTIMPLEMENTED(); } void WmShellMus::UnlockCursor() { - // TODO: http::/crbug.com/637853 + // TODO: http://crbug.com/637853 NOTIMPLEMENTED(); } bool WmShellMus::IsMouseEventsEnabled() { - // TODO: http::/crbug.com/637853 + // TODO: http://crbug.com/637853 NOTIMPLEMENTED(); return true; }
diff --git a/ash/system/chromeos/power/tablet_power_button_controller_unittest.cc b/ash/system/chromeos/power/tablet_power_button_controller_unittest.cc index 6a1917b..2765b03 100644 --- a/ash/system/chromeos/power/tablet_power_button_controller_unittest.cc +++ b/ash/system/chromeos/power/tablet_power_button_controller_unittest.cc
@@ -11,6 +11,7 @@ #include "ash/common/test/test_session_controller_client.h" #include "ash/common/wm/maximize_mode/maximize_mode_controller.h" #include "ash/common/wm_shell.h" +#include "ash/public/cpp/config.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/test/lock_state_controller_test_api.h" @@ -76,10 +77,10 @@ void TearDown() override { generator_ = nullptr; - const bool is_mash = WmShell::Get()->IsRunningInMash(); + const Config config = Shell::GetAshConfig(); AshTestBase::TearDown(); - // Mash shuts down dbus after each test. - if (!is_mash) + // Mash/mus shuts down dbus after each test. + if (config == Config::CLASSIC) chromeos::DBusThreadManager::Shutdown(); }
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc index c90f08c..b652427 100644 --- a/ash/wm/overview/window_selector_unittest.cc +++ b/ash/wm/overview/window_selector_unittest.cc
@@ -940,7 +940,8 @@ // The tested behavior relies on the app list presenter delegate. test::TestAppListViewPresenterImpl app_list_presenter_impl; - app_list_presenter_impl.Show(display_manager()->first_display_id()); + app_list_presenter_impl.Show( + display::Screen::GetScreen()->GetPrimaryDisplay().id()); EXPECT_TRUE(app_list_presenter_impl.IsVisible()); ToggleOverview();
diff --git a/ash/wm/window_cycle_controller_unittest.cc b/ash/wm/window_cycle_controller_unittest.cc index c0290ee..fb1cca2b 100644 --- a/ash/wm/window_cycle_controller_unittest.cc +++ b/ash/wm/window_cycle_controller_unittest.cc
@@ -492,7 +492,8 @@ std::unique_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0)); std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1)); - app_list_presenter_impl.Show(display_manager()->first_display_id()); + app_list_presenter_impl.Show( + display::Screen::GetScreen()->GetPrimaryDisplay().id()); EXPECT_TRUE(app_list_presenter_impl.IsVisible()); controller->HandleCycleWindow(WindowCycleController::FORWARD); EXPECT_FALSE(app_list_presenter_impl.IsVisible());
diff --git a/base/BUILD.gn b/base/BUILD.gn index 6686ae6..d1fb90a 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -1626,6 +1626,7 @@ flags = [ "ENABLE_PROFILING=$enable_profiling", "ENABLE_MEMORY_TASK_PROFILER=$enable_memory_task_profiler", + "CAN_UNWIND_WITH_FRAME_POINTERS=$can_unwind_with_frame_pointers", ] }
diff --git a/base/android/jni_android.cc b/base/android/jni_android.cc index 56dc5c2..e91e6f9 100644 --- a/base/android/jni_android.cc +++ b/base/android/jni_android.cc
@@ -29,7 +29,7 @@ g_class_loader = LAZY_INSTANCE_INITIALIZER; jmethodID g_class_loader_load_class_method_id = 0; -#if BUILDFLAG(ENABLE_PROFILING) && HAVE_TRACE_STACK_FRAME_POINTERS +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) base::LazyInstance<base::ThreadLocalPointer<void>>::Leaky g_stack_frame_pointer = LAZY_INSTANCE_INITIALIZER; #endif @@ -289,7 +289,7 @@ return ConvertJavaStringToUTF8(exception_string); } -#if BUILDFLAG(ENABLE_PROFILING) && HAVE_TRACE_STACK_FRAME_POINTERS +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) JNIStackFrameSaver::JNIStackFrameSaver(void* current_fp) { previous_fp_ = g_stack_frame_pointer.Pointer()->Get(); @@ -304,7 +304,7 @@ return g_stack_frame_pointer.Pointer()->Get(); } -#endif // ENABLE_PROFILING && HAVE_TRACE_STACK_FRAME_POINTERS +#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) } // namespace android } // namespace base
diff --git a/base/android/jni_android.h b/base/android/jni_android.h index de53c10f..cc23b2ca 100644 --- a/base/android/jni_android.h +++ b/base/android/jni_android.h
@@ -14,10 +14,11 @@ #include "base/atomicops.h" #include "base/base_export.h" #include "base/compiler_specific.h" +#include "base/debug/debugging_flags.h" #include "base/debug/stack_trace.h" #include "base/macros.h" -#if HAVE_TRACE_STACK_FRAME_POINTERS +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) // When profiling is enabled (enable_profiling=true) this macro is added to // all generated JNI stubs so that it becomes the last thing that runs before @@ -46,7 +47,7 @@ #define JNI_SAVE_FRAME_POINTER #define JNI_LINK_SAVED_FRAME_POINTER -#endif // HAVE_TRACE_STACK_FRAME_POINTERS +#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) namespace base { namespace android { @@ -166,7 +167,7 @@ BASE_EXPORT std::string GetJavaExceptionInfo(JNIEnv* env, jthrowable java_throwable); -#if HAVE_TRACE_STACK_FRAME_POINTERS +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) // Saves caller's PC and stack frame in a thread-local variable. // Implemented only when profiling is enabled (enable_profiling=true). @@ -182,7 +183,7 @@ DISALLOW_COPY_AND_ASSIGN(JNIStackFrameSaver); }; -#endif // HAVE_TRACE_STACK_FRAME_POINTERS +#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) } // namespace android } // namespace base
diff --git a/base/debug/stack_trace.cc b/base/debug/stack_trace.cc index 43a23d95..ede8bd4 100644 --- a/base/debug/stack_trace.cc +++ b/base/debug/stack_trace.cc
@@ -12,7 +12,7 @@ #include "base/logging.h" #include "base/macros.h" -#if HAVE_TRACE_STACK_FRAME_POINTERS +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) #if defined(OS_LINUX) || defined(OS_ANDROID) #include <pthread.h> @@ -28,14 +28,14 @@ extern "C" void* __libc_stack_end; #endif -#endif // HAVE_TRACE_STACK_FRAME_POINTERS +#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) namespace base { namespace debug { namespace { -#if HAVE_TRACE_STACK_FRAME_POINTERS && !defined(OS_WIN) +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) && !defined(OS_WIN) #if defined(__arm__) && defined(__GNUC__) && !defined(__clang__) // GCC and LLVM generate slightly different frames on ARM, see @@ -142,11 +142,11 @@ return prev_parent_fp; } -#endif // HAVE_TRACE_STACK_FRAME_POINTERS && !defined(OS_WIN) +#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) && !defined(OS_WIN) } // namespace -#if HAVE_TRACE_STACK_FRAME_POINTERS +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) uintptr_t GetStackEnd() { #if defined(OS_ANDROID) // Bionic reads proc/maps on every call to pthread_getattr_np() when called @@ -194,7 +194,7 @@ // Don't know how to get end of the stack. return 0; } -#endif // HAVE_TRACE_STACK_FRAME_POINTERS +#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) StackTrace::StackTrace() : StackTrace(arraysize(trace_)) {} @@ -220,7 +220,7 @@ return stream.str(); } -#if HAVE_TRACE_STACK_FRAME_POINTERS +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) size_t TraceStackFramePointers(const void** out_trace, size_t max_depth, @@ -286,7 +286,7 @@ } #endif // !defined(OS_WIN) -#endif // HAVE_TRACE_STACK_FRAME_POINTERS +#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) } // namespace debug } // namespace base
diff --git a/base/debug/stack_trace.h b/base/debug/stack_trace.h index ab1d2ebe..5796f56 100644 --- a/base/debug/stack_trace.h +++ b/base/debug/stack_trace.h
@@ -11,6 +11,7 @@ #include <string> #include "base/base_export.h" +#include "base/debug/debugging_flags.h" #include "base/macros.h" #include "build/build_config.h" @@ -23,24 +24,6 @@ struct _CONTEXT; #endif -// TODO(699863): Clean up HAVE_TRACE_STACK_FRAME_POINTERS. -#if defined(OS_POSIX) - -#if defined(__i386__) || defined(__x86_64__) -#define HAVE_TRACE_STACK_FRAME_POINTERS 1 -#elif defined(__arm__) && !defined(__thumb__) -#define HAVE_TRACE_STACK_FRAME_POINTERS 1 -#else // defined(__arm__) && !defined(__thumb__) -#define HAVE_TRACE_STACK_FRAME_POINTERS 0 -#endif // defined(__arm__) && !defined(__thumb__) - -#elif defined(OS_WIN) -#define HAVE_TRACE_STACK_FRAME_POINTERS 1 - -#else // defined(OS_WIN) -#define HAVE_TRACE_STACK_FRAME_POINTERS 0 -#endif // defined(OS_WIN) - namespace base { namespace debug { @@ -56,7 +39,7 @@ BASE_EXPORT bool EnableInProcessStackDumping(); // Returns end of the stack, or 0 if we couldn't get it. -#if HAVE_TRACE_STACK_FRAME_POINTERS +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) BASE_EXPORT uintptr_t GetStackEnd(); #endif @@ -119,7 +102,7 @@ size_t count_; }; -#if HAVE_TRACE_STACK_FRAME_POINTERS +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) // Traces the stack by using frame pointers. This function is faster but less // reliable than StackTrace. It should work for debug and profiling builds, // but not for release builds (although there are some exceptions). @@ -184,7 +167,7 @@ }; #endif // !defined(OS_WIN) -#endif // HAVE_TRACE_STACK_FRAME_POINTERS +#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) namespace internal {
diff --git a/base/debug/stack_trace_unittest.cc b/base/debug/stack_trace_unittest.cc index 536edb25..bdff543 100644 --- a/base/debug/stack_trace_unittest.cc +++ b/base/debug/stack_trace_unittest.cc
@@ -8,6 +8,7 @@ #include <sstream> #include <string> +#include "base/debug/debugging_flags.h" #include "base/debug/stack_trace.h" #include "base/logging.h" #include "base/process/kill.h" @@ -254,10 +255,11 @@ } #endif // defined(OS_POSIX) && !defined(OS_ANDROID) -#if HAVE_TRACE_STACK_FRAME_POINTERS && !defined(OS_WIN) // Windows x64 binaries cannot be built with frame pointer, and MSVC doesn't // provide intrinsics to query the frame pointer even for the x86 build, nor // does it allow us to take the address of labels, so skip these under Windows. +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) && !defined(OS_WIN) + template <size_t Depth> void NOINLINE ExpectStackFramePointers(const void** frames, size_t max_depth) { @@ -315,7 +317,7 @@ EXPECT_NE(0u, GetStackEnd()); } -#endif // HAVE_TRACE_STACK_FRAME_POINTERS && !defined(OS_WIN) +#endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) && !defined(OS_WIN) } // namespace debug } // namespace base
diff --git a/base/logging_unittest.cc b/base/logging_unittest.cc index 04f349c..62323972 100644 --- a/base/logging_unittest.cc +++ b/base/logging_unittest.cc
@@ -185,7 +185,13 @@ // Official builds have CHECKs directly call BreakDebugger. #if !defined(OFFICIAL_BUILD) -TEST_F(LoggingTest, CheckStreamsAreLazy) { +// https://crbug.com/709067 tracks test flakiness on iOS. +#if defined(OS_IOS) +#define MAYBE_CheckStreamsAreLazy DISABLED_CheckStreamsAreLazy +#else +#define MAYBE_CheckStreamsAreLazy CheckStreamsAreLazy +#endif +TEST_F(LoggingTest, MAYBE_CheckStreamsAreLazy) { MockLogSource mock_log_source, uncalled_mock_log_source; EXPECT_CALL(mock_log_source, Log()).Times(8). WillRepeatedly(Return("check message")); @@ -386,7 +392,13 @@ } void DcheckEmptyFunction2() {} -TEST_F(LoggingTest, Dcheck) { +// https://crbug.com/709067 tracks test flakiness on iOS. +#if defined(OS_IOS) +#define MAYBE_Dcheck DISABLED_Dcheck +#else +#define MAYBE_Dcheck Dcheck +#endif +TEST_F(LoggingTest, MAYBE_Dcheck) { #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) // Release build. EXPECT_FALSE(DCHECK_IS_ON());
diff --git a/base/task_scheduler/task_scheduler.cc b/base/task_scheduler/task_scheduler.cc index bff2de6..0e621f1 100644 --- a/base/task_scheduler/task_scheduler.cc +++ b/base/task_scheduler/task_scheduler.cc
@@ -40,16 +40,29 @@ #if !defined(OS_NACL) // static void TaskScheduler::CreateAndSetSimpleTaskScheduler(const std::string& name) { - constexpr int kMinNumThreads = 1; - std::vector<SchedulerWorkerPoolParams> worker_pool_params_vector; - worker_pool_params_vector.emplace_back( - name, ThreadPriority::NORMAL, - SchedulerWorkerPoolParams::StandbyThreadPolicy::LAZY, - std::max(kMinNumThreads, SysInfo::NumberOfProcessors()), - TimeDelta::FromSeconds(30)); + using StandbyThreadPolicy = SchedulerWorkerPoolParams::StandbyThreadPolicy; + + // Values were chosen so that: + // * There are few background threads. + // * Background threads never outnumber foreground threads. + // * The system is utilized maximally by foreground threads. + const int num_cores = SysInfo::NumberOfProcessors(); + constexpr int kBackgroundMaxThreads = 1; + constexpr int kBackgroundBlockingMaxThreads = 2; + const int kForegroundMaxThreads = std::max(1, num_cores); + const int kForegroundBlockingMaxThreads = std::max(2, num_cores); + + constexpr TimeDelta kSuggestedReclaimTime = TimeDelta::FromSeconds(30); + CreateAndSetDefaultTaskScheduler( - worker_pool_params_vector, - Bind([](const TaskTraits&) -> size_t { return 0; })); + name, {{StandbyThreadPolicy::LAZY, kBackgroundMaxThreads, + kSuggestedReclaimTime}, + {StandbyThreadPolicy::LAZY, kBackgroundBlockingMaxThreads, + kSuggestedReclaimTime}, + {StandbyThreadPolicy::LAZY, kForegroundMaxThreads, + kSuggestedReclaimTime}, + {StandbyThreadPolicy::LAZY, kForegroundBlockingMaxThreads, + kSuggestedReclaimTime}}); } #endif // !defined(OS_NACL)
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.cc b/base/trace_event/heap_profiler_allocation_context_tracker.cc index b47dc16..8c6f441 100644 --- a/base/trace_event/heap_profiler_allocation_context_tracker.cc +++ b/base/trace_event/heap_profiler_allocation_context_tracker.cc
@@ -8,6 +8,7 @@ #include <iterator> #include "base/atomicops.h" +#include "base/debug/debugging_flags.h" #include "base/debug/leak_annotations.h" #include "base/threading/platform_thread.h" #include "base/threading/thread_local_storage.h" @@ -206,7 +207,7 @@ const void* frames[128]; static_assert(arraysize(frames) >= Backtrace::kMaxFrameCount, "not requesting enough frames to fill Backtrace"); -#if HAVE_TRACE_STACK_FRAME_POINTERS && !defined(OS_NACL) +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) && !defined(OS_NACL) size_t frame_count = debug::TraceStackFramePointers( frames, arraysize(frames),
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc index 6ed1ca8..e526ee6 100644 --- a/base/trace_event/memory_dump_manager.cc +++ b/base/trace_event/memory_dump_manager.cc
@@ -195,8 +195,7 @@ if (profiling_mode == "") { AllocationContextTracker::SetCaptureMode( AllocationContextTracker::CaptureMode::PSEUDO_STACK); -#if HAVE_TRACE_STACK_FRAME_POINTERS && \ - (BUILDFLAG(ENABLE_PROFILING) || !defined(NDEBUG)) +#if (BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) || !defined(NDEBUG)) } else if (profiling_mode == switches::kEnableHeapProfilingModeNative) { // We need frame pointers for native tracing to work, and they are // enabled in profiling and debug builds.
diff --git a/build/android/gyp/util/proguard_util.py b/build/android/gyp/util/proguard_util.py index a965ff33..6fc57d9f 100644 --- a/build/android/gyp/util/proguard_util.py +++ b/build/android/gyp/util/proguard_util.py
@@ -15,15 +15,24 @@ """ IGNORE_RE = re.compile( - r'(?:Pro.*version|Note:|Reading|Preparing|.*:.*(?:MANIFEST\.MF|\.empty))') + r'(?:Pro.*version|Note:|Reading|Preparing|ProgramClass:|' + '.*:.*(?:MANIFEST\.MF|\.empty))') def __init__(self): self._last_line_ignored = False + self._ignore_next_line = False def __call__(self, output): ret = [] for line in output.splitlines(True): - if not line.startswith(' '): + if self._ignore_next_line: + self._ignore_next_line = False + continue + + if '***BINARY RUN STATS***' in line: + self._last_line_ignored = True + self._ignore_next_line = True + elif not line.startswith(' '): self._last_line_ignored = bool(self.IGNORE_RE.match(line)) elif 'You should check if you need to specify' in line: self._last_line_ignored = True @@ -199,4 +208,3 @@ } build_utils.WriteJson(this_info, self._outjar + '.info') -
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 5cc1ca1..320b7fce 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1381,18 +1381,22 @@ } config("default_stack_frames") { - if (is_posix && !(is_mac || is_ios)) { - if (using_sanitizer || enable_profiling || is_debug || - current_cpu == "arm64") { - # Explicitly ask for frame pointers, otherwise: - # * Stacks may be missing for sanitizer and profiling builds. - # * Debug tcmalloc can crash (crbug.com/636489). - # * Stacks may be missing for arm64 crash dumps (crbug.com/391706). + if (is_posix) { + if (enabled_frame_pointers) { cflags = [ "-fno-omit-frame-pointer" ] - } else if (is_android) { + } else { cflags = [ "-fomit-frame-pointer" ] } } + # On Windows, the flag to enable framepointers "/Oy-" must always come after + # the optimization flag [e.g. "/O2"]. The optimization flag is set by one of + # the "optimize" configs, see rest of this file. The ordering that cflags are + # applied is well-defined by the GN spec, and there is no way to ensure that + # cflags set by "default_stack_frames" is applied after those set by an + # "optimize" config. Similarly, there is no way to propagate state from this + # config into the "optimize" config. We always apply the "/Oy-" config in the + # definition for common_optimize_on_cflags definition, even though this may + # not be correct. } # Default "optimization on" config.
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index 403dd4fd..2cb9637 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//build/config/android/config.gni") +import("//build/config/arm.gni") import("//build/config/chrome_build.gni") import("//build/config/chromecast_build.gni") import("//build/config/compiler/pgo/pgo.gni") @@ -65,6 +66,34 @@ use_pic = true } +# Whether to emit frame pointers by default. +if (is_mac || is_ios) { + enabled_frame_pointers = true +} else if (is_win) { + # 64-bit Windows ABI doesn't support frame pointers. + if (target_cpu == "x64") { + enabled_frame_pointers = false + } else { + enabled_frame_pointers = true + } +} else { + # Explicitly ask for frame pointers, otherwise: + # * Stacks may be missing for sanitizer and profiling builds. + # * Debug tcmalloc can crash (crbug.com/636489). + # * Stacks may be missing for arm64 crash dumps (crbug.com/391706). + enabled_frame_pointers = + using_sanitizer || enable_profiling || is_debug || current_cpu == "arm64" +} + +# Unwinding with frame pointers requires that frame pointers are enabled by +# default for most translation units, and that the architecture isn't thumb, as +# frame pointers are not correctly emitted for thumb. +if (enabled_frame_pointers && !(current_cpu == "arm" && arm_use_thumb)) { + can_unwind_with_frame_pointers = true +} else { + can_unwind_with_frame_pointers = false +} + declare_args() { # Whether or not the official builds should be built with full WPO. Enabled by # default for the PGO and the x64 builds.
diff --git a/cc/layers/draw_properties.h b/cc/layers/draw_properties.h index d16b40b..f5c7a6cf 100644 --- a/cc/layers/draw_properties.h +++ b/cc/layers/draw_properties.h
@@ -36,10 +36,9 @@ // opacity, or when opacity is compounded by the hierarchy. float opacity; - // xxx_is_animating flags are used to indicate whether the DrawProperties - // are actually meaningful on the main thread. When the properties are - // animating, the main thread may not have the same values that are used - // to draw. + // Whether the layer has a potentially animating transform in its chain of + // transforms to the screen. This is essentially a cache of the transform + // node's potentially-animated status. bool screen_space_transform_is_animating; // True if the layer needs to be clipped by clip_rect.
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 3dd8150..66c1e3ed 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -539,6 +539,10 @@ "//chrome/common:version_header", ] + if (is_chrome_branded) { + deps += [ ":chrome_helpers" ] + } + # Remove the default strip configuration (which strips all symbols) so that # a saves file can be specified. if (enable_stripping) { @@ -633,6 +637,18 @@ ] } + if (is_chrome_branded) { + bundle_data("chrome_helpers") { + sources = [ + "installer/mac/internal/keychain_reauthorizers/$chrome_mac_bundle_id", + ] + + outputs = [ + "{{bundle_root_dir}}/Helpers/{{source_file_part}}", + ] + } + } + bundle_data("chrome_versioned_bundle_data") { sources = [ "$root_out_dir/$chrome_framework_name.framework",
diff --git a/chrome/android/java/res/drawable-hdpi/ic_account_child.png b/chrome/android/java/res/drawable-hdpi/ic_account_child_20dp.png similarity index 100% rename from chrome/android/java/res/drawable-hdpi/ic_account_child.png rename to chrome/android/java/res/drawable-hdpi/ic_account_child_20dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/ic_account_child_grey600_36dp.png b/chrome/android/java/res/drawable-hdpi/ic_account_child_grey600_36dp.png new file mode 100644 index 0000000..2e7682f4 --- /dev/null +++ b/chrome/android/java/res/drawable-hdpi/ic_account_child_grey600_36dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/ic_account_child.png b/chrome/android/java/res/drawable-mdpi/ic_account_child_20dp.png similarity index 100% rename from chrome/android/java/res/drawable-mdpi/ic_account_child.png rename to chrome/android/java/res/drawable-mdpi/ic_account_child_20dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/ic_account_child_grey600_36dp.png b/chrome/android/java/res/drawable-mdpi/ic_account_child_grey600_36dp.png new file mode 100644 index 0000000..8965866 --- /dev/null +++ b/chrome/android/java/res/drawable-mdpi/ic_account_child_grey600_36dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/ic_account_child.png b/chrome/android/java/res/drawable-xhdpi/ic_account_child.png deleted file mode 100644 index 648b205a..0000000 --- a/chrome/android/java/res/drawable-xhdpi/ic_account_child.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/ic_account_child_20dp.png b/chrome/android/java/res/drawable-xhdpi/ic_account_child_20dp.png new file mode 100644 index 0000000..93d23f7b --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/ic_account_child_20dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/ic_account_child_grey600_36dp.png b/chrome/android/java/res/drawable-xhdpi/ic_account_child_grey600_36dp.png new file mode 100644 index 0000000..752c17141 --- /dev/null +++ b/chrome/android/java/res/drawable-xhdpi/ic_account_child_grey600_36dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/ic_account_child.png b/chrome/android/java/res/drawable-xxhdpi/ic_account_child_20dp.png similarity index 100% rename from chrome/android/java/res/drawable-xxhdpi/ic_account_child.png rename to chrome/android/java/res/drawable-xxhdpi/ic_account_child_20dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/ic_account_child_grey600_36dp.png b/chrome/android/java/res/drawable-xxhdpi/ic_account_child_grey600_36dp.png new file mode 100644 index 0000000..c981ed1a --- /dev/null +++ b/chrome/android/java/res/drawable-xxhdpi/ic_account_child_grey600_36dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/ic_account_child.png b/chrome/android/java/res/drawable-xxxhdpi/ic_account_child_20dp.png similarity index 100% rename from chrome/android/java/res/drawable-xxxhdpi/ic_account_child.png rename to chrome/android/java/res/drawable-xxxhdpi/ic_account_child_20dp.png Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/ic_account_child_grey600_36dp.png b/chrome/android/java/res/drawable-xxxhdpi/ic_account_child_grey600_36dp.png new file mode 100644 index 0000000..8bdac5a --- /dev/null +++ b/chrome/android/java/res/drawable-xxxhdpi/ic_account_child_grey600_36dp.png Binary files differ
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java index 2428e99..3be63e69 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java
@@ -10,6 +10,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.SuppressFBWarnings; import org.chromium.chrome.R; import org.chromium.chrome.browser.ResourceId; import org.chromium.chrome.browser.preferences.autofill.AutofillAndPaymentsPreferences; @@ -18,6 +19,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.concurrent.TimeUnit; /** * Android wrapper of the PersonalDataManager which provides access from the Java @@ -62,6 +64,20 @@ } /** + * Callback for subKeys request. + */ + public interface GetSubKeysRequestDelegate { + /** + * Called when the sub-keys are received sucessfully. + * Here the sub-keys are admin areas. + * + * @param subKeys The subKeys. + */ + @CalledByNative("GetSubKeysRequestDelegate") + void onSubKeysReceived(String[] subKeys); + } + + /** * Callback for normalized addresses. */ public interface NormalizedAddressRequestDelegate { @@ -512,6 +528,8 @@ private static PersonalDataManager sManager; + // Suppress FindBugs warning, since |sManager| is only used on the UI thread. + @SuppressFBWarnings("LI_LAZY_INIT_STATIC") public static PersonalDataManager getInstance() { ThreadUtils.assertOnUiThread(); if (sManager == null) { @@ -805,16 +823,42 @@ * * @param regionCode The code of the region for which to load the rules. */ - public void loadRulesForRegion(String regionCode) { + public void loadRulesForAddressNormalization(String regionCode) { ThreadUtils.assertOnUiThread(); - nativeLoadRulesForRegion(mPersonalDataManagerAndroid, regionCode); + nativeLoadRulesForAddressNormalization(mPersonalDataManagerAndroid, regionCode); } /** - * Normalizes the address of the {@code profile} if the rules associated with the - * {@code regionCode} are done loading. Otherwise sets up the callback to start normalizing the - * address when the rules are loaded. The normalized profile will be sent to the - * {@code delegate}. If the profile is not normalized in the specified + * Starts loading the sub-key request rules for the specified {@code regionCode}. + * + * @param regionCode The code of the region for which to load the rules. + */ + public void loadRulesForSubKeys(String regionCode) { + ThreadUtils.assertOnUiThread(); + nativeLoadRulesForSubKeys(mPersonalDataManagerAndroid, regionCode); + } + + /** + * Starts loading the sub keys for the specified {@code regionCode}. + * + * @param regionCode The code of the region for which to load the sub keys. + */ + public void getRegionSubKeys(String regionCode, GetSubKeysRequestDelegate delegate) { + ThreadUtils.assertOnUiThread(); + nativeStartRegionSubKeysRequest(mPersonalDataManagerAndroid, regionCode, delegate); + } + + /** Cancels the pending sub keys request. */ + public void cancelPendingGetSubKeys() { + ThreadUtils.assertOnUiThread(); + nativeCancelPendingGetSubKeys(mPersonalDataManagerAndroid); + } + + /** + * Normalizes the address of the profile associated with the {@code guid} if the rules + * associated with the {@code regionCode} are done loading. Otherwise sets up the callback to + * start normalizing the address when the rules are loaded. The normalized profile will be sent + * to the {@code delegate}. If the profile is not normalized in the specified * {@code sNormalizationTimeoutSeconds}, the {@code delegate} will be notified. * * @param profile The profile to normalize. @@ -888,6 +932,10 @@ sNormalizationTimeoutSeconds = timeout; } + public static long getRequestTimeoutMS() { + return TimeUnit.SECONDS.toMillis(sNormalizationTimeoutSeconds); + } + private native long nativeInit(); private native boolean nativeIsDataLoaded(long nativePersonalDataManagerAndroid); private native String[] nativeGetProfileGUIDsForSettings(long nativePersonalDataManagerAndroid); @@ -947,11 +995,15 @@ long nativePersonalDataManagerAndroid, String guid); private native void nativeGetFullCardForPaymentRequest(long nativePersonalDataManagerAndroid, WebContents webContents, CreditCard card, FullCardRequestDelegate delegate); - private native void nativeLoadRulesForRegion( + private native void nativeLoadRulesForAddressNormalization( + long nativePersonalDataManagerAndroid, String regionCode); + private native void nativeLoadRulesForSubKeys( long nativePersonalDataManagerAndroid, String regionCode); private native void nativeStartAddressNormalization(long nativePersonalDataManagerAndroid, AutofillProfile profile, String regionCode, int timeoutSeconds, NormalizedAddressRequestDelegate delegate); + private native void nativeStartRegionSubKeysRequest(long nativePersonalDataManagerAndroid, + String regionCode, GetSubKeysRequestDelegate delegate); private static native boolean nativeHasProfiles(long nativePersonalDataManagerAndroid); private static native boolean nativeHasCreditCards(long nativePersonalDataManagerAndroid); private static native boolean nativeIsAutofillEnabled(); @@ -960,4 +1012,5 @@ private static native boolean nativeIsPaymentsIntegrationEnabled(); private static native void nativeSetPaymentsIntegrationEnabled(boolean enable); private static native String nativeToCountryCode(String countryName); + private static native void nativeCancelPendingGetSubKeys(long nativePersonalDataManagerAndroid); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/historyreport/AppIndexingReporter.java b/chrome/android/java/src/org/chromium/chrome/browser/historyreport/AppIndexingReporter.java index 4312d82..d9ff99a2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/historyreport/AppIndexingReporter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/historyreport/AppIndexingReporter.java
@@ -23,17 +23,6 @@ * Reports provided entity to on-device index. * Base class does not implement any reporting, and call is a no-op. Child classes should * implement this functionality. - * - * Deprecated, to be removed in follow-up cl, after downstream change. - */ - public void reportEntityJsonLd(String url, String json) { - // Overriden by private class. Base class does nothing. - } - - /** - * Reports provided entity to on-device index. - * Base class does not implement any reporting, and call is a no-op. Child classes should - * implement this functionality. */ public void reportWebPage(WebPage webpage) { // Overriden by private class. Base class does nothing.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java index 4fc0ae9c..ab0e67b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.payments; +import android.app.ProgressDialog; import android.os.Handler; import android.util.Pair; @@ -11,6 +12,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.PersonalDataManager; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; +import org.chromium.chrome.browser.autofill.PersonalDataManager.GetSubKeysRequestDelegate; import org.chromium.chrome.browser.autofill.PhoneNumberUtil; import org.chromium.chrome.browser.payments.ui.EditorFieldModel; import org.chromium.chrome.browser.payments.ui.EditorFieldModel.EditorFieldValidator; @@ -31,15 +33,27 @@ /** * An address editor. Can be used for either shipping or billing address editing. */ -public class AddressEditor extends EditorBase<AutofillAddress> { +public class AddressEditor + extends EditorBase<AutofillAddress> implements GetSubKeysRequestDelegate { private final Handler mHandler = new Handler(); private final Map<Integer, EditorFieldModel> mAddressFields = new HashMap<>(); private final Set<CharSequence> mPhoneNumbers = new HashSet<>(); - @Nullable private AutofillProfileBridge mAutofillProfileBridge; - @Nullable private EditorFieldModel mCountryField; - @Nullable private EditorFieldModel mPhoneField; - @Nullable private EditorFieldValidator mPhoneValidator; - @Nullable private List<AddressUiComponent> mAddressUiComponents; + @Nullable + private AutofillProfileBridge mAutofillProfileBridge; + @Nullable + private EditorFieldModel mCountryField; + @Nullable + private EditorFieldModel mPhoneField; + @Nullable + private EditorFieldValidator mPhoneValidator; + @Nullable + private List<AddressUiComponent> mAddressUiComponents; + private boolean mAdminAreasLoaded; + private String mRecentlySelectedCountry; + private Runnable mCountryChangeCallback; + private AutofillProfile mProfile; + private EditorModel mEditor; + private ProgressDialog mProgressDialog; /** * Adds the given phone number to the autocomplete set, if it's valid. @@ -72,17 +86,20 @@ // default locale on this device. boolean isNewAddress = toEdit == null; - // Ensure that |address| and |profile| are always not null. + // Ensure that |address| and |mProfile| are always not null. final AutofillAddress address = isNewAddress ? new AutofillAddress(mContext, new AutofillProfile()) : toEdit; - final AutofillProfile profile = address.getProfile(); + mProfile = address.getProfile(); // The title of the editor depends on whether we're adding a new address or editing an // existing address. - final EditorModel editor = - new EditorModel(isNewAddress - ? mContext.getString(R.string.autofill_create_profile) - : toEdit.getEditTitle()); + mEditor = + new EditorModel(isNewAddress ? mContext.getString(R.string.autofill_create_profile) + : toEdit.getEditTitle()); + + // When edit is called, a new form is started, so the country on the + // dropdown list is not changed. => mRecentlySelectedCountry should be null. + mRecentlySelectedCountry = null; // The country dropdown is always present on the editor. if (mCountryField == null) { @@ -96,23 +113,24 @@ // discarded, so their contents are preserved. mCountryField.setDropdownCallback(new Callback<Pair<String, Runnable>>() { @Override + /** + * If the selected country on the country dropdown list is changed, + * the first element of eventData is the recently selected dropdown key, + * the second element is the callback to invoke for when the dropdown + * change has been processed. + */ public void onResult(Pair<String, Runnable> eventData) { - editor.removeAllFields(); - editor.addField(mCountryField); - addAddressTextFieldsToEditor(editor, eventData.first, - Locale.getDefault().getLanguage()); - editor.addField(mPhoneField); - - // Notify EditorView that the fields in the model have changed. EditorView should - // re-read the model and update the UI accordingly. - mHandler.post(eventData.second); + mEditor.removeAllFields(); + showProgressDialog(); + mRecentlySelectedCountry = eventData.first; + mCountryChangeCallback = eventData.second; + loadAdminAreasForCountry(mRecentlySelectedCountry); } }); // Country dropdown is cached, so the selected item needs to be updated for the new profile // that's being edited. This will not fire the dropdown callback. - mCountryField.setValue(AutofillAddress.getCountryCode(profile)); - editor.addField(mCountryField); + mCountryField.setValue(AutofillAddress.getCountryCode(mProfile)); // There's a finite number of fields for address editing. Changing the country will re-order // and relabel the fields. The meaning of each field remains the same. @@ -122,10 +140,6 @@ mAddressFields.put(AddressField.DEPENDENT_LOCALITY, EditorFieldModel.createTextInput()); mAddressFields.put(AddressField.ORGANIZATION, EditorFieldModel.createTextInput()); - // State should be formatted in all capitals. - mAddressFields.put(AddressField.ADMIN_AREA, EditorFieldModel.createTextInput( - EditorFieldModel.INPUT_TYPE_HINT_REGION)); - // Sorting code and postal code (a.k.a. ZIP code) should show both letters and digits on // the keyboard, if possible. mAddressFields.put(AddressField.SORTING_CODE, EditorFieldModel.createTextInput( @@ -142,18 +156,6 @@ EditorFieldModel.INPUT_TYPE_HINT_PERSON_NAME)); } - // Address fields are cached, so their values need to be updated for every new profile - // that's being edited. - for (Map.Entry<Integer, EditorFieldModel> entry : mAddressFields.entrySet()) { - entry.getValue().setValue(AutofillAddress.getProfileField(profile, entry.getKey())); - } - - // Both country code and language code dictate which fields should be added to the editor. - // For example, "US" will not add dependent locality to the editor. A "JP" address will - // start with a person's full name or a with a prefecture name, depending on whether the - // language code is "ja-Latn" or "ja". - addAddressTextFieldsToEditor( - editor, mCountryField.getValue().toString(), profile.getLanguageCode()); // Phone number is present and required for all countries. if (mPhoneField == null) { @@ -166,30 +168,48 @@ // Phone number field is cached, so its value needs to be updated for every new profile // that's being edited. - mPhoneField.setValue(profile.getPhoneNumber()); - editor.addField(mPhoneField); + mPhoneField.setValue(mProfile.getPhoneNumber()); // If the user clicks [Cancel], send |toEdit| address back to the caller, which was the // original state (could be null, a complete address, a partial address). - editor.setCancelCallback(new Runnable() { + mEditor.setCancelCallback(new Runnable() { @Override public void run() { + // This makes sure that onSubKeysReceived returns early if it's + // ever called when Cancel has already occurred. + mAdminAreasLoaded = true; + PersonalDataManager.getInstance().cancelPendingGetSubKeys(); callback.onResult(toEdit); } }); // If the user clicks [Done], save changes on disk, mark the address "complete," and send it // back to the caller. - editor.setDoneCallback(new Runnable() { + mEditor.setDoneCallback(new Runnable() { @Override public void run() { - commitChanges(profile); - address.completeAddress(profile); + mAdminAreasLoaded = true; + PersonalDataManager.getInstance().cancelPendingGetSubKeys(); + commitChanges(mProfile); + address.completeAddress(mProfile); callback.onResult(address); } }); - mEditorView.show(editor); + loadAdminAreasForCountry(mProfile.getCountryCode()); + } + + private void showProgressDialog() { + mProgressDialog = new ProgressDialog(mContext); + mProgressDialog.setMessage(mContext.getText(R.string.payments_loading_message)); + mProgressDialog.show(); + } + + private void dismissProgressDialog() { + if (mProgressDialog != null && mProgressDialog.isShowing()) { + mProgressDialog.dismiss(); + } + mProgressDialog = null; } /** Saves the edited profile on disk. */ @@ -221,7 +241,7 @@ } // Save the edited autofill profile locally. - profile.setGUID(PersonalDataManager.getInstance().setProfileToLocal(profile)); + profile.setGUID(PersonalDataManager.getInstance().setProfileToLocal(mProfile)); profile.setIsLocal(true); } @@ -266,27 +286,109 @@ return value == null ? "" : value.toString(); } - /** - * Adds text fields to the editor model based on the country and language code of the profile - * that's being edited. - */ - private void addAddressTextFieldsToEditor( - EditorModel container, String countryCode, String languageCode) { - mAddressUiComponents = mAutofillProfileBridge.getAddressUiComponents(countryCode, - languageCode); + private void setAddressFieldValuesFromCache() { + // Address fields are cached, so their values need to be updated for every new profile + // that's being edited. + for (Map.Entry<Integer, EditorFieldModel> entry : mAddressFields.entrySet()) { + entry.getValue().setValue(AutofillAddress.getProfileField(mProfile, entry.getKey())); + } + } + @Override + public void onSubKeysReceived(String[] adminAreas) { + if (mAdminAreasLoaded) return; + mAdminAreasLoaded = true; + + // If Chrome can't get admin areas from the server or there is no admin area on the server, + // then use the text field. + // Otherwise, use the dropdown list. + if (adminAreas == null || adminAreas.length == 0) { + mAddressFields.put(AddressField.ADMIN_AREA, EditorFieldModel.createTextInput()); + } else { + mAddressFields.put(AddressField.ADMIN_AREA, EditorFieldModel.createDropdown()); + } + + // Admin areas need to be fetched in two cases: + // 1. Initial loading of the form. + // 2. When the selected country is changed in the form. + // mRecentlySelectedCountry is not null if and only if it's the second case + if (mRecentlySelectedCountry != null) { + dismissProgressDialog(); + // Both country code and language code dictate which fields should be added to the + // editor. + // For example, "US" will not add dependent locality to the editor. A "JP" address will + // start with a person's full name or a with a prefecture name, depending on whether the + // language code is "ja-Latn" or "ja". + addAddressFieldsToEditor( + mRecentlySelectedCountry, Locale.getDefault().getLanguage(), adminAreas); + // Notify EditorView that the fields in the model have changed. EditorView should + // re-read the model and update the UI accordingly. + mHandler.post(mCountryChangeCallback); + } else { + // This should be called when all required fields are put in mAddressField. + setAddressFieldValuesFromCache(); + addAddressFieldsToEditor( + mProfile.getCountryCode(), mProfile.getLanguageCode(), adminAreas); + mEditorView.show(mEditor); + } + } + + /** Requests the list of admin areas. */ + private void loadAdminAreasForCountry(String countryCode) { + // Used to check if the callback is called (for time-out). + mAdminAreasLoaded = false; + + // In each rule, admin area keys are saved under sub-keys of country. + PersonalDataManager.getInstance().loadRulesForSubKeys(countryCode); + PersonalDataManager.getInstance().getRegionSubKeys(countryCode, this); + onAdminAreasLoading(); + } + + /** Cancels the request for the list of admin areas. */ + private void cancelAdminAreasRequest() { + if (mAdminAreasLoaded) return; + onSubKeysReceived(null); + PersonalDataManager.getInstance().cancelPendingGetSubKeys(); + } + + /** + * In case the the admin areas are not loaded yet, or the time out is set to 0 for testing, + * starts a timer to cancel the request. + */ + public void onAdminAreasLoading() { + if (mAdminAreasLoaded) return; + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + cancelAdminAreasRequest(); + } + }, PersonalDataManager.getInstance().getRequestTimeoutMS()); + } + + /** + * Adds fields to the editor model based on the country and language code of + * the profile that's being edited. + */ + private void addAddressFieldsToEditor( + String countryCode, String languageCode, String[] adminAreas) { + mAddressUiComponents = + mAutofillProfileBridge.getAddressUiComponents(countryCode, languageCode); + // In terms of order, country must be the first field. + mEditor.addField(mCountryField); for (int i = 0; i < mAddressUiComponents.size(); i++) { AddressUiComponent component = mAddressUiComponents.get(i); - // The country field is a dropdown, so there's no need to add a text field for it. - if (component.id == AddressField.COUNTRY) continue; - EditorFieldModel field = mAddressFields.get(component.id); // Labels depend on country, e.g., state is called province in some countries. These are // already localized. field.setLabel(component.label); field.setIsFullLine(component.isFullLine); + if (component.id == AddressField.ADMIN_AREA && field.isDropdownField()) { + field.setDropdownKeyValues( + mAutofillProfileBridge.getAdminAreaDropdownList(adminAreas)); + } + // Libaddressinput formats do not always require the full name (RECIPIENT), but // PaymentRequest does. if (component.isRequired || component.id == AddressField.RECIPIENT) { @@ -295,9 +397,10 @@ } else { field.setRequiredErrorMessage(null); } - - container.addField(field); + mEditor.addField(field); } + // Phone number must be the last field. + mEditor.addField(mPhoneField); } private EditorFieldValidator getPhoneValidator() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java index 41176e4d..1f1b9f7b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -529,7 +529,7 @@ String countryCode = AutofillAddress.getCountryCode(addresses.get(i).getProfile()); if (!uniqueCountryCodes.contains(countryCode)) { uniqueCountryCodes.add(countryCode); - PersonalDataManager.getInstance().loadRulesForRegion(countryCode); + PersonalDataManager.getInstance().loadRulesForAddressNormalization(countryCode); } } @@ -1387,7 +1387,7 @@ String countryCode = AutofillAddress.getCountryCode(creditCard.getBillingAddress()); if (!uniqueCountryCodes.contains(countryCode)) { uniqueCountryCodes.add(countryCode); - PersonalDataManager.getInstance().loadRulesForRegion(countryCode); + PersonalDataManager.getInstance().loadRulesForAddressNormalization(countryCode); } // If there's a card on file with a valid number and a name, then
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDropdownField.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDropdownField.java index e7f30183..e1568b4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDropdownField.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDropdownField.java
@@ -18,12 +18,15 @@ import android.widget.TextView; import org.chromium.chrome.R; +import org.chromium.chrome.browser.payments.ui.PaymentRequestUI.PaymentRequestObserverForTest; import org.chromium.chrome.browser.preferences.autofill.AutofillProfileBridge.DropdownKeyValue; import org.chromium.ui.UiUtils; import java.util.ArrayList; import java.util.List; +import javax.annotation.Nullable; + /** * Helper class for creating a dropdown view with a label. */ @@ -33,6 +36,8 @@ private final TextView mLabel; private final Spinner mDropdown; private int mSelectedIndex; + @Nullable + private PaymentRequestObserverForTest mObserverForTest; /** * Builds a dropdown view. @@ -44,9 +49,10 @@ * processed. */ public EditorDropdownField(Context context, ViewGroup root, final EditorFieldModel fieldModel, - final Runnable changedCallback) { + final Runnable changedCallback, @Nullable PaymentRequestObserverForTest observer) { assert fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_DROPDOWN; mFieldModel = fieldModel; + mObserverForTest = observer; mLayout = LayoutInflater.from(context).inflate( R.layout.payment_request_editor_dropdown, root, false); @@ -97,6 +103,9 @@ mFieldModel.getDropdownKeyValues().get(position).getKey(), changedCallback); } + if (mObserverForTest != null) { + mObserverForTest.onPaymentRequestEditorTextUpdate(); + } } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorFieldModel.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorFieldModel.java index 690834b..08037a6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorFieldModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorFieldModel.java
@@ -198,6 +198,11 @@ return result; } + /** Constructs a dropdown field model. */ + public static EditorFieldModel createDropdown() { + return new EditorFieldModel(INPUT_TYPE_HINT_DROPDOWN); + } + /** * Constructs a dropdown field model. * @@ -332,11 +337,17 @@ return mValueIconGenerator; } - private boolean isTextField() { + /** @return Whether the input is a text field. */ + public boolean isTextField() { return mInputTypeHint >= INPUT_TYPE_HINT_MIN_INCLUSIVE && mInputTypeHint < INPUT_TYPE_HINT_MAX_TEXT_INPUT_EXCLUSIVE; } + /** @return Whether the input is a dropdown field. */ + public boolean isDropdownField() { + return mInputTypeHint == INPUT_TYPE_HINT_DROPDOWN; + } + /** @return The type of input, for example, INPUT_TYPE_HINT_PHONE. */ public int getInputTypeHint() { return mInputTypeHint;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java index 7506c43..3c9164b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java
@@ -328,7 +328,7 @@ if (nextFieldModel.isFullLine()) useFullLine = true; } - if (useFullLine) { + if (useFullLine || isLastField) { addFieldViewToEditor(mDataView, fieldModel); } else { // Create a LinearLayout to put it and the next view side by side. @@ -385,8 +385,8 @@ if (mObserverForTest != null) mObserverForTest.onPaymentRequestReadyToEdit(); } }; - EditorDropdownField dropdownView = - new EditorDropdownField(mContext, parent, fieldModel, prepareEditorRunnable); + EditorDropdownField dropdownView = new EditorDropdownField( + mContext, parent, fieldModel, prepareEditorRunnable, mObserverForTest); mFieldViews.add(dropdownView); mDropdownFields.add(dropdownView.getDropdown());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ManagedPreferenceDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ManagedPreferenceDelegate.java index 89650b9..2773aea 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ManagedPreferenceDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ManagedPreferenceDelegate.java
@@ -7,6 +7,7 @@ import android.preference.Preference; import android.view.View; +import org.chromium.chrome.R; import org.chromium.chrome.browser.util.ViewUtils; /** @@ -72,6 +73,8 @@ public void initPreference(Preference preference) { if (isPreferenceControlledByPolicy(preference)) { preference.setIcon(ManagedPreferencesUtils.getManagedByEnterpriseIconId()); + } else if (isPreferenceControlledByCustodian(preference)) { + preference.setIcon(R.drawable.ic_account_child_grey600_36dp); } if (isPreferenceClickDisabledByPolicy(preference)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java index 7f0f63d..a5bc8eb5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java
@@ -97,10 +97,31 @@ return result; } }); - return countries; } + /** @return The list of admin areas sorted by their localized display names. */ + public static List<DropdownKeyValue> getAdminAreaDropdownList(String[] keys) { + List<DropdownKeyValue> adminAreas = new ArrayList<>(); + + for (int i = 0; i < keys.length; ++i) { + // TODO (parastoog): show names, save keys. @crbug.com/691643 + adminAreas.add(new DropdownKeyValue(keys[i], keys[i])); + } + + final Collator collator = Collator.getInstance(Locale.getDefault()); + collator.setStrength(Collator.PRIMARY); + Collections.sort(adminAreas, new Comparator<DropdownKeyValue>() { + @Override + public int compare(DropdownKeyValue lhs, DropdownKeyValue rhs) { + // Sorted according to the admin area values, such as Quebec, + // rather than the admin area keys, such as QC. + return collator.compare(lhs.getValue(), rhs.getValue()); + } + }); + return adminAreas; + } + /** @return The list of required fields. COUNTRY is always included. RECIPIENT often omitted. */ public static List<Integer> getRequiredAddressFields(String countryCode) { List<Integer> requiredFields = new ArrayList<>();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java index 02524a3e..5b4e0af 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java
@@ -651,7 +651,7 @@ } sChildAccountId = accountId; Bitmap picture = getUserPicture(accountId, res); - Bitmap badge = BitmapFactory.decodeResource(res, R.drawable.ic_account_child); + Bitmap badge = BitmapFactory.decodeResource(res, R.drawable.ic_account_child_20dp); sCachedBadgedPicture = overlayChildBadgeOnUserPicture(picture, badge, res); return sCachedBadgedPicture; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java index e4689e0e..1fc04b4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java
@@ -4,12 +4,8 @@ package org.chromium.chrome.browser.tab; -import android.content.ActivityNotFoundException; -import android.content.Intent; import android.view.ViewGroup; -import org.chromium.base.Log; -import org.chromium.base.metrics.RecordUserAction; import org.chromium.ui.base.ViewAndroidDelegate; /** @@ -43,16 +39,6 @@ } @Override - public void startContentIntent(Intent intent, String intentUrl, boolean isMainFrame) { - try { - RecordUserAction.record("Android.ContentDetectorActivated"); - mContainerView.getContext().startActivity(intent); - } catch (ActivityNotFoundException ex) { - Log.w(TAG, "No application can handle %s", intentUrl); - } - } - - @Override public ViewGroup getContainerView() { return mContainerView; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java index 86ff686..77f01b87 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java
@@ -45,11 +45,6 @@ return isEnabledInPrefs(); } - // Returns whether updating the WebAPK is enabled. - public static boolean areUpdatesEnabled() { - return canInstallWebApk(); - } - /** Computes the GooglePlayInstallState. */ private static int computeGooglePlayInstallState() { if (!ExternalAuthUtils.getInstance().canUseGooglePlayServices(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java index 286c0012..41bbb50d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java
@@ -56,8 +56,12 @@ String url = urlFromIntent(intent); int source = sourceFromIntent(intent); + + // Force navigation if the extra is not specified to avoid breaking deep linking for old + // WebAPKs which don't specify the {@link WebApkConstants#EXTRA_WEBAPK_FORCE_NAVIGATION} + // intent extra. boolean forceNavigation = IntentUtils.safeGetBooleanExtra( - intent, WebApkConstants.EXTRA_WEBAPK_FORCE_NAVIGATION, false); + intent, WebApkConstants.EXTRA_WEBAPK_FORCE_NAVIGATION, true); return create(webApkPackageName, url, source, forceNavigation); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java index 3a5b864a..c84cb30f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java
@@ -285,8 +285,6 @@ return true; } - if (!ChromeWebApkHost.areUpdatesEnabled()) return false; - if (isShellApkVersionOutOfDate(info)) return true; return mStorage.shouldCheckForUpdate();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java index 9e4877e..45ffb7f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -50,7 +50,6 @@ * All the computation in this file is based off of the bottom of the screen instead of the top * for simplicity. This means that the bottom of the screen is 0 on the Y axis. */ - public class BottomSheet extends FrameLayout implements FadingBackgroundView.FadingViewObserver, NativePageHost { /** The different states that the bottom sheet can have. */ @@ -128,6 +127,9 @@ /** The animator used to move the sheet to a fixed state when released by the user. */ private ValueAnimator mSettleAnimator; + /** The animator used for the toolbar fades. */ + private ValueAnimator mToolbarFadeAnimator; + /** The height of the toolbar. */ private float mToolbarHeight; @@ -138,10 +140,12 @@ private float mContainerHeight; /** The current state that the sheet is in. */ - private int mCurrentState; + @SheetState + private int mCurrentState = SHEET_STATE_PEEK; /** The target sheet state. This is the state that the sheet is currently moving to. */ - private int mTargetState; + @SheetState + private int mTargetState = SHEET_STATE_NONE; /** Used for getting the current tab. */ private TabModelSelector mTabModelSelector; @@ -210,7 +214,7 @@ int getVerticalScrollOffset(); /** - * Called to destroy the BottomSheetContent when it is no longer in use. + * Called to destroy the {@link BottomSheetContent} when it is no longer in use. */ void destroy(); @@ -418,8 +422,6 @@ mBottomSheetContentContainer = (FrameLayout) findViewById(R.id.bottom_sheet_content); - mCurrentState = SHEET_STATE_PEEK; - // Listen to height changes on the root. root.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override @@ -530,8 +532,6 @@ return mContainerHeight - getTranslationY(); } - private ValueAnimator mToolbarFadeAnimator; - /** * Show content in the bottom sheet's content area. * @param content The {@link BottomSheetContent} to show. @@ -564,8 +564,8 @@ * Fade between a new toolbar and the old toolbar to be shown. A null parameter can be used to * refer to the default omnibox toolbar. Normally, the new toolbar is attached to the toolbar * container and faded in. In the case of the default toolbar, the old toolbar is faded out. - * This is because the default toolbar it is always attached to the view hierarchy and sits - * behind the attach point for the other toolbars. + * This is because the default toolbar is always attached to the view hierarchy and sits behind + * the attach point for the other toolbars. * @param newToolbar The toolbar that will be shown. * @param oldToolbar The toolbar being replaced. */ @@ -875,6 +875,7 @@ * @return The current state of the bottom sheet. If the sheet is animating, this will be the * state the sheet is animating to. */ + @SheetState public int getSheetState() { return mCurrentState; } @@ -943,6 +944,7 @@ * bottom to top. * @return The target state of the bottom sheet. */ + @SheetState private int getTargetSheetState(float sheetHeight, float yVelocity) { if (sheetHeight <= getMinOffset()) return SHEET_STATE_PEEK; if (sheetHeight >= getMaxOffset()) return SHEET_STATE_FULL;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetMetrics.java index 930a1a1d..73845aa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetMetrics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheetMetrics.java
@@ -15,7 +15,7 @@ import java.util.concurrent.TimeUnit; /** - * Records user action and histograms related to the {@link BottomSheet}. + * Records user actions and histograms related to the {@link BottomSheet}. */ public class BottomSheetMetrics extends EmptyBottomSheetObserver { /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTestHelper.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTestHelper.java index 5892cb4..f792814c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTestHelper.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTestHelper.java
@@ -31,7 +31,7 @@ ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - PersonalDataManager.getInstance().setNormalizationTimeoutForTesting(1); + PersonalDataManager.getInstance().setNormalizationTimeoutForTesting(0); } }); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInfoTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInfoTest.java index 7ff886c..34a80ce 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInfoTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkInfoTest.java
@@ -210,4 +210,25 @@ Assert.assertEquals(1, iconUrlToMurmur2HashMap.size()); Assert.assertTrue(iconUrlToMurmur2HashMap.containsValue(hash)); } + + /** + * Prior to SHELL_APK_VERSION 2, WebAPKs did not specify + * {@link WebApkConstants.EXTRA_WEBAPK_FORCE_NAVIGATION} in the intent. Test that + * {@link WebApkInfo#shouldForceNavigation()} defaults to true when the intent extra is not + * specified. + */ + @Test + public void testForceNavigationNotSpecified() { + Bundle bundle = new Bundle(); + bundle.putString(WebApkMetaDataKeys.START_URL, START_URL); + WebApkTestHelper.registerWebApkWithMetaData(bundle); + + Intent intent = new Intent(); + intent.putExtra( + WebApkConstants.EXTRA_WEBAPK_PACKAGE_NAME, WebApkTestHelper.WEBAPK_PACKAGE_NAME); + intent.putExtra(ShortcutHelper.EXTRA_URL, START_URL); + + WebApkInfo info = WebApkInfo.create(intent); + Assert.assertTrue(info.shouldForceNavigation()); + } }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index ade7ac6..65abf852 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -4041,17 +4041,6 @@ <message name="IDS_APP_CANT_DOWNGRADE_VERSION" desc="Error message when a user tries to install an app with a lower version than a version that it already installed."> Attempted to downgrade app. </message> - <message name="IDS_EXTENSION_WEBGL_NOT_SUPPORTED" desc="Error message when an extension has a requirement for WebGL that the system does not support."> - WebGL is not supported. - </message> - <message name="IDS_EXTENSION_NPAPI_NOT_SUPPORTED" desc="Error message when an extension has a requirement for plugins that the system does not support."> - NPAPI plugins are not supported. - </message> - <if expr="not use_aura"> - <message name="IDS_EXTENSION_WINDOW_SHAPE_NOT_SUPPORTED" desc="Error message when an extension has a requirement for shaped windows that the system does not support."> - Shaped windows are not supported. - </message> - </if> <if expr="chromeos"> <message name="IDS_EXTENSION_CANT_INSTALL_IN_DEVICE_LOCAL_ACCOUNT" desc="Error message when a user tries to install or the administrator tries to force-install through policy an extension that is not allowed in a device-local account."> <ph name="EXTENSION_NAME">$1<ex>Google Talk</ex></ph> (extension ID "<ph name="EXTENSION_ID">$2<ex>nckgahadagoaajjgafhacjanaoiihapd</ex></ph>") is not allowed in this type of session. @@ -4108,9 +4097,6 @@ <message name="IDS_EXTENSION_BAD_FILE_ENCODING" desc=""> Could not load file '<ph name="RELATIVE_PATH">$1<ex>file.js</ex></ph>' for content script. It isn't UTF-8 encoded. </message> - <message name="IDS_EXTENSION_LOAD_PLUGIN_PATH_FAILED" desc=""> - Could not load '<ph name="PLUGIN_PATH">$1<ex>/path/to/file</ex></ph>' for plugin. - </message> <message name="IDS_EXTENSION_LOAD_ICON_FOR_PAGE_ACTION_FAILED" desc=""> Could not load icon '<ph name="ICON">$1<ex>icon.png</ex></ph>' for page action. </message>
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.cc b/chrome/browser/autofill/android/personal_data_manager_android.cc index f270be2..cc60fce 100644 --- a/chrome/browser/autofill/android/personal_data_manager_android.cc +++ b/chrome/browser/autofill/android/personal_data_manager_android.cc
@@ -13,6 +13,7 @@ #include "base/android/jni_string.h" #include "base/command_line.h" #include "base/format_macros.h" +#include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "chrome/browser/android/resource_mapper.h" @@ -305,6 +306,40 @@ DISALLOW_COPY_AND_ASSIGN(AndroidAddressNormalizerDelegate); }; +class AndroidSubKeyRequesterDelegate + : public PersonalDataManagerAndroid::SubKeyRequestDelegate, + public base::SupportsWeakPtr<AndroidSubKeyRequesterDelegate> { + public: + AndroidSubKeyRequesterDelegate( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& jdelegate, + const std::string& region_code, + base::WeakPtr<PersonalDataManagerAndroid> personal_data_manager_android) { + jdelegate_.Reset(env, jdelegate); + region_code_ = region_code; + personal_data_manager_android_ = personal_data_manager_android; + } + + ~AndroidSubKeyRequesterDelegate() override {} + + private: + // PersonalDataManagerAndroid::SubKeyRequestDelegate: + void OnRulesSuccessfullyLoaded() override { + if (personal_data_manager_android_) { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_GetSubKeysRequestDelegate_onSubKeysReceived( + env, jdelegate_, + personal_data_manager_android_->GetSubKeys(env, region_code_)); + } + } + + ScopedJavaGlobalRef<jobject> jdelegate_; + std::string region_code_; + base::WeakPtr<PersonalDataManagerAndroid> personal_data_manager_android_; + + DISALLOW_COPY_AND_ASSIGN(AndroidSubKeyRequesterDelegate); +}; + } // namespace PersonalDataManagerAndroid::PersonalDataManagerAndroid(JNIEnv* env, jobject obj) @@ -316,7 +351,13 @@ new autofill::ChromeMetadataSource( I18N_ADDRESS_VALIDATION_DATA_URL, personal_data_manager_->GetURLRequestContextGetter())), - ValidationRulesStorageFactory::CreateStorage()) { + ValidationRulesStorageFactory::CreateStorage()), + address_validator_( + base::MakeUnique<autofill::ChromeMetadataSource>( + I18N_ADDRESS_VALIDATION_DATA_URL, + personal_data_manager_->GetURLRequestContextGetter()), + ValidationRulesStorageFactory::CreateStorage(), + this) { personal_data_manager_->AddObserver(this); } @@ -697,7 +738,7 @@ return base::Time::Now().ToTimeT(); } -void PersonalDataManagerAndroid::LoadRulesForRegion( +void PersonalDataManagerAndroid::LoadRulesForAddressNormalization( JNIEnv* env, const base::android::JavaParamRef<jobject>& unused_obj, const base::android::JavaParamRef<jstring>& jregion_code) { @@ -705,6 +746,13 @@ ConvertJavaStringToUTF8(env, jregion_code)); } +void PersonalDataManagerAndroid::LoadRulesForSubKeys( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& unused_obj, + const base::android::JavaParamRef<jstring>& jregion_code) { + address_validator_.LoadRules(ConvertJavaStringToUTF8(env, jregion_code)); +} + void PersonalDataManagerAndroid::StartAddressNormalization( JNIEnv* env, const JavaParamRef<jobject>& unused_obj, @@ -738,6 +786,53 @@ return !personal_data_manager_->GetCreditCards().empty(); } +base::android::ScopedJavaLocalRef<jobjectArray> +PersonalDataManagerAndroid::GetSubKeys(JNIEnv* env, + const std::string& region_code) { + std::vector<std::string> sub_keys = + address_validator_.GetRegionSubKeys(region_code); + return base::android::ToJavaArrayOfStrings(env, sub_keys); +} + +void PersonalDataManagerAndroid::OnAddressRulesLoaded( + const std::string& region_code, + bool success) { + // if |success| == false, AddressValidator::GetRegionSubKeys will return an + // empty list of sub-keys. => No need to check for |success|. + // Check if there is any sub-key request for that region code. + if (!pending_subkey_region_code_.compare(region_code)) + pending_subkey_request_->OnRulesSuccessfullyLoaded(); + pending_subkey_region_code_.clear(); + pending_subkey_request_.reset(); +} + +void PersonalDataManagerAndroid::StartRegionSubKeysRequest( + JNIEnv* env, + const JavaParamRef<jobject>& unused_obj, + const JavaParamRef<jstring>& jregion_code, + const JavaParamRef<jobject>& jdelegate) { + const std::string region_code = ConvertJavaStringToUTF8(env, jregion_code); + std::unique_ptr<SubKeyRequestDelegate> requester = + base::MakeUnique<AndroidSubKeyRequesterDelegate>( + env, jdelegate, region_code, AsWeakPtr()); + + if (AreRulesLoadedForRegion(region_code)) { + requester->OnRulesSuccessfullyLoaded(); + } else { + // Setup the variables so that the sub-keys request is sent, when the rules + // are loaded. + pending_subkey_region_code_ = region_code; + pending_subkey_request_ = std::move(requester); + } +} + +void PersonalDataManagerAndroid::CancelPendingGetSubKeys( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& unused_obj) { + pending_subkey_region_code_.clear(); + pending_subkey_request_.reset(); +} + ScopedJavaLocalRef<jobjectArray> PersonalDataManagerAndroid::GetProfileGUIDs( JNIEnv* env, const std::vector<AutofillProfile*>& profiles) { @@ -760,7 +855,7 @@ bool PersonalDataManagerAndroid::AreRulesLoadedForRegion( const std::string& region_code) { - return address_normalizer_.AreRulesLoadedForRegion(region_code); + return address_validator_.AreRulesLoadedForRegion(region_code); } ScopedJavaLocalRef<jobjectArray> PersonalDataManagerAndroid::GetProfileLabels(
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.h b/chrome/browser/autofill/android/personal_data_manager_android.h index 801e8b6c..3dd7936 100644 --- a/chrome/browser/autofill/android/personal_data_manager_android.h +++ b/chrome/browser/autofill/android/personal_data_manager_android.h
@@ -12,14 +12,25 @@ #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/personal_data_manager_observer.h" #include "components/payments/core/address_normalizer.h" +#include "third_party/libaddressinput/chromium/chrome_address_validator.h" namespace autofill { // Android wrapper of the PersonalDataManager which provides access from the // Java layer. Note that on Android, there's only a single profile, and // therefore a single instance of this wrapper. -class PersonalDataManagerAndroid : public PersonalDataManagerObserver { +class PersonalDataManagerAndroid + : public PersonalDataManagerObserver, + public LoadRulesListener, + public base::SupportsWeakPtr<PersonalDataManagerAndroid> { public: + // The interface for the sub-key request. + class SubKeyRequestDelegate { + public: + virtual void OnRulesSuccessfullyLoaded() = 0; + virtual ~SubKeyRequestDelegate() {} + }; + // Registers the JNI bindings for this class. static bool Register(JNIEnv* env); @@ -284,7 +295,14 @@ // Starts loading the address validation rules for the specified // |region_code|. - void LoadRulesForRegion( + void LoadRulesForAddressNormalization( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& unused_obj, + const base::android::JavaParamRef<jstring>& region_code); + + // Starts loading the rules for the specified |region_code| for the further + // sub-key request. + void LoadRulesForSubKeys( JNIEnv* env, const base::android::JavaParamRef<jobject>& unused_obj, const base::android::JavaParamRef<jstring>& region_code); @@ -312,6 +330,31 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& unused_obj); + // Gets the sub-keys for the region with |jregion_code| code, if the + // |jregion_code| rules have finished loading. Otherwise, sets up a task to + // get the sub-keys, when the rules are loaded. + void StartRegionSubKeysRequest( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& unused_obj, + const base::android::JavaParamRef<jstring>& jregion_code, + const base::android::JavaParamRef<jobject>& jdelegate); + + // Gets the sub-keys of the rule associated with |jregion_code|. Should only + // be called when the rules are loaded. + base::android::ScopedJavaLocalRef<jobjectArray> GetSubKeys( + JNIEnv* env, + const std::string& jregion_code); + + // Callback of the sub-keys request. + // This is called when the sub-keys are loaded. + void OnAddressRulesLoaded(const std::string& region_code, + bool success) override; + + // Cancels the pending sub-key request task. + void CancelPendingGetSubKeys( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& unused_obj); + private: ~PersonalDataManagerAndroid() override; @@ -362,6 +405,13 @@ // The address validator used to normalize addresses. payments::AddressNormalizer address_normalizer_; + // The address validator used for sub-key request. + AddressValidator address_validator_; + + // The region code and the request for the pending sub-key request. + std::unique_ptr<SubKeyRequestDelegate> pending_subkey_request_; + std::string pending_subkey_region_code_; + DISALLOW_COPY_AND_ASSIGN(PersonalDataManagerAndroid); };
diff --git a/chrome/browser/chromeos/libc_close_tracking.cc b/chrome/browser/chromeos/libc_close_tracking.cc index 260a116..cdbde3f 100644 --- a/chrome/browser/chromeos/libc_close_tracking.cc +++ b/chrome/browser/chromeos/libc_close_tracking.cc
@@ -11,6 +11,7 @@ #include <unordered_map> #include "base/debug/crash_logging.h" +#include "base/debug/debugging_flags.h" #include "base/debug/stack_trace.h" #include "base/logging.h" #include "base/macros.h" @@ -119,7 +120,7 @@ // Capture stack for successful close. if (ret == 0) { -#if HAVE_TRACE_STACK_FRAME_POINTERS && !defined(MEMORY_SANITIZER) +#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) && !defined(MEMORY_SANITIZER) // Use TraceStackFramePointers because the backtrack() based default // capturing gets only the last stack frame and is not useful. // With the exception of when MSAN is enabled. See comments for why
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.cc b/chrome/browser/chromeos/login/ui/webui_login_view.cc index 594d1a8..5508d0a 100644 --- a/chrome/browser/chromeos/login/ui/webui_login_view.cc +++ b/chrome/browser/chromeos/login/ui/webui_login_view.cc
@@ -457,10 +457,12 @@ return true; ash::SystemTray* tray = ash::Shell::Get()->GetPrimarySystemTray(); - if (tray && tray->GetWidget()->IsVisible()) { + if (tray && tray->GetWidget()->IsVisible() && tray->visible()) { tray->SetNextFocusableView(this); ash::Shell::Get()->focus_cycler()->RotateFocus( reverse ? ash::FocusCycler::BACKWARD : ash::FocusCycler::FORWARD); + } else { + AboutToRequestFocusFromTabTraversal(reverse); } return true;
diff --git a/chrome/browser/content_settings/content_settings_internal_extension_provider.cc b/chrome/browser/content_settings/content_settings_internal_extension_provider.cc index d153e10..bd58d07 100644 --- a/chrome/browser/content_settings/content_settings_internal_extension_provider.cc +++ b/chrome/browser/content_settings/content_settings_internal_extension_provider.cc
@@ -10,7 +10,6 @@ #include "chrome/browser/pdf/pdf_extension_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_content_client.h" -#include "chrome/common/extensions/api/plugins/plugins_handler.h" #include "components/content_settings/core/browser/content_settings_rule.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_pattern.h" @@ -23,6 +22,7 @@ #include "extensions/common/extension.h" #include "extensions/common/extension_set.h" #include "extensions/common/features/simple_feature.h" +#include "extensions/common/manifest_handlers/plugins_handler.h" using extensions::UnloadedExtensionInfo;
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 6ef51a2..cc6a1797 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -487,8 +487,6 @@ "chrome_mojo_service_registration.h", "chrome_process_manager_delegate.cc", "chrome_process_manager_delegate.h", - "chrome_requirements_checker.cc", - "chrome_requirements_checker.h", "chrome_url_request_util.cc", "chrome_url_request_util.h", "clipboard_extension_helper_chromeos.cc",
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc index 9d52108..8fd3eff 100644 --- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc +++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
@@ -10,7 +10,6 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/bookmark_app_helper.h" #include "chrome/browser/extensions/chrome_extension_function_details.h" -#include "chrome/browser/extensions/chrome_requirements_checker.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/launch_util.h" @@ -225,11 +224,6 @@ web_contents, browser_context, extension, callback)); } -std::unique_ptr<extensions::RequirementsChecker> -ChromeManagementAPIDelegate::CreateRequirementsChecker() const { - return base::MakeUnique<extensions::ChromeRequirementsChecker>(); -} - std::unique_ptr<extensions::UninstallDialogDelegate> ChromeManagementAPIDelegate::UninstallFunctionDelegate( extensions::ManagementUninstallFunctionBase* function,
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.h b/chrome/browser/extensions/api/management/chrome_management_api_delegate.h index 6c12736..dec9423 100644 --- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.h +++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.h
@@ -31,8 +31,6 @@ content::BrowserContext* browser_context, const extensions::Extension* extension, const base::Callback<void(bool)>& callback) const override; - std::unique_ptr<extensions::RequirementsChecker> CreateRequirementsChecker() - const override; std::unique_ptr<extensions::UninstallDialogDelegate> UninstallFunctionDelegate( extensions::ManagementUninstallFunctionBase* function,
diff --git a/chrome/browser/extensions/api/storage/settings_apitest.cc b/chrome/browser/extensions/api/storage/settings_apitest.cc index 07ea411..e0c56008a 100644 --- a/chrome/browser/extensions/api/storage/settings_apitest.cc +++ b/chrome/browser/extensions/api/storage/settings_apitest.cc
@@ -113,10 +113,8 @@ } syncer::SyncableService* GetSyncableService() { - return settings_sync_util::GetSyncableServiceProvider(browser()->profile(), - kModelType) - .Run() - .get(); + return settings_sync_util::GetSyncableService(browser()->profile(), + kModelType); } void InitSync(syncer::SyncChangeProcessor* sync_processor) {
diff --git a/chrome/browser/extensions/api/storage/settings_sync_util.cc b/chrome/browser/extensions/api/storage/settings_sync_util.cc index 36169c8..e29718c 100644 --- a/chrome/browser/extensions/api/storage/settings_sync_util.cc +++ b/chrome/browser/extensions/api/storage/settings_sync_util.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/extensions/api/storage/settings_sync_util.h" -#include "base/bind.h" #include "base/json/json_writer.h" #include "base/values.h" #include "chrome/browser/extensions/api/storage/sync_value_store_cache.h" @@ -14,10 +13,7 @@ #include "content/public/browser/browser_thread.h" #include "extensions/browser/api/storage/storage_frontend.h" -using base::WeakPtr; using content::BrowserThread; -using syncer::ModelType; -using syncer::SyncableService; namespace extensions { @@ -48,19 +44,13 @@ extension_id, key, value, specifics->mutable_extension_setting()); } -WeakPtr<SyncableService> GetSyncableService(WeakPtr<SyncValueStoreCache> cache, - ModelType type) { - DCHECK_CURRENTLY_ON(BrowserThread::FILE); - return cache.get() ? cache->GetSyncableService(type)->AsWeakPtr() - : WeakPtr<SyncableService>(); -} - } // namespace -syncer::SyncData CreateData(const std::string& extension_id, - const std::string& key, - const base::Value& value, - ModelType type) { +syncer::SyncData CreateData( + const std::string& extension_id, + const std::string& key, + const base::Value& value, + syncer::ModelType type) { sync_pb::EntitySpecifics specifics; switch (type) { case syncer::EXTENSION_SETTINGS: @@ -87,29 +77,32 @@ extension_id + "/" + key, key, specifics); } -syncer::SyncChange CreateAdd(const std::string& extension_id, - const std::string& key, - const base::Value& value, - ModelType type) { +syncer::SyncChange CreateAdd( + const std::string& extension_id, + const std::string& key, + const base::Value& value, + syncer::ModelType type) { return syncer::SyncChange( FROM_HERE, syncer::SyncChange::ACTION_ADD, CreateData(extension_id, key, value, type)); } -syncer::SyncChange CreateUpdate(const std::string& extension_id, - const std::string& key, - const base::Value& value, - ModelType type) { +syncer::SyncChange CreateUpdate( + const std::string& extension_id, + const std::string& key, + const base::Value& value, + syncer::ModelType type) { return syncer::SyncChange( FROM_HERE, syncer::SyncChange::ACTION_UPDATE, CreateData(extension_id, key, value, type)); } -syncer::SyncChange CreateDelete(const std::string& extension_id, - const std::string& key, - ModelType type) { +syncer::SyncChange CreateDelete( + const std::string& extension_id, + const std::string& key, + syncer::ModelType type) { base::DictionaryValue no_value; return syncer::SyncChange( FROM_HERE, @@ -117,17 +110,14 @@ CreateData(extension_id, key, no_value, type)); } -syncer::SyncClient::ServiceProvider GetSyncableServiceProvider( - content::BrowserContext* context, - ModelType type) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); +syncer::SyncableService* GetSyncableService(content::BrowserContext* context, + syncer::ModelType type) { + DCHECK_CURRENTLY_ON(BrowserThread::FILE); DCHECK(type == syncer::APP_SETTINGS || type == syncer::EXTENSION_SETTINGS); StorageFrontend* frontend = StorageFrontend::Get(context); SyncValueStoreCache* sync_cache = static_cast<SyncValueStoreCache*>( frontend->GetValueStoreCache(settings_namespace::SYNC)); - // We must rely on our caller to guarantee that sync_cache->AsWeakPtr() is a - // valid call right now, and that shutdown has not begun. - return base::Bind(&GetSyncableService, sync_cache->AsWeakPtr(), type); + return sync_cache->GetSyncableService(type); } } // namespace settings_sync_util
diff --git a/chrome/browser/extensions/api/storage/settings_sync_util.h b/chrome/browser/extensions/api/storage/settings_sync_util.h index 12bb7ee..4e23bae 100644 --- a/chrome/browser/extensions/api/storage/settings_sync_util.h +++ b/chrome/browser/extensions/api/storage/settings_sync_util.h
@@ -5,9 +5,6 @@ #ifndef CHROME_BROWSER_EXTENSIONS_API_STORAGE_SETTINGS_SYNC_UTIL_H_ #define CHROME_BROWSER_EXTENSIONS_API_STORAGE_SETTINGS_SYNC_UTIL_H_ -#include <string> - -#include "components/sync/driver/sync_client.h" #include "components/sync/model/sync_change.h" #include "components/sync/model/sync_data.h" @@ -19,6 +16,10 @@ class BrowserContext; } +namespace syncer { +class SyncableService; +} + namespace extensions { namespace settings_sync_util { @@ -52,9 +53,8 @@ // Returns the sync service for settings. Must be called on the FILE thread. // |type| must be either APP_SETTINGS or EXTENSION_SETTINGS. -syncer::SyncClient::ServiceProvider GetSyncableServiceProvider( - content::BrowserContext* context, - syncer::ModelType type); +syncer::SyncableService* GetSyncableService(content::BrowserContext* context, + syncer::ModelType type); } // namespace settings_sync_util
diff --git a/chrome/browser/extensions/api/storage/sync_value_store_cache.cc b/chrome/browser/extensions/api/storage/sync_value_store_cache.cc index 33267b80..0a440ee 100644 --- a/chrome/browser/extensions/api/storage/sync_value_store_cache.cc +++ b/chrome/browser/extensions/api/storage/sync_value_store_cache.cc
@@ -35,7 +35,7 @@ const scoped_refptr<ValueStoreFactory>& factory, const scoped_refptr<SettingsObserverList>& observers, const base::FilePath& profile_path) - : initialized_(false), weak_ptr_factory_(this) { + : initialized_(false) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // This post is safe since the destructor can only be invoked from the @@ -52,10 +52,6 @@ DCHECK_CURRENTLY_ON(BrowserThread::FILE); } -base::WeakPtr<SyncValueStoreCache> SyncValueStoreCache::AsWeakPtr() { - return weak_ptr_factory_.GetWeakPtr(); -} - syncer::SyncableService* SyncValueStoreCache::GetSyncableService( syncer::ModelType type) const { DCHECK_CURRENTLY_ON(BrowserThread::FILE);
diff --git a/chrome/browser/extensions/api/storage/sync_value_store_cache.h b/chrome/browser/extensions/api/storage/sync_value_store_cache.h index 2984522..62805823 100644 --- a/chrome/browser/extensions/api/storage/sync_value_store_cache.h +++ b/chrome/browser/extensions/api/storage/sync_value_store_cache.h
@@ -6,12 +6,10 @@ #define CHROME_BROWSER_EXTENSIONS_API_STORAGE_SYNC_VALUE_STORE_CACHE_H_ #include <memory> -#include <string> #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" #include "components/sync/model/syncable_service.h" #include "extensions/browser/api/storage/settings_observer.h" #include "extensions/browser/api/storage/value_store_cache.h" @@ -38,8 +36,6 @@ const base::FilePath& profile_path); ~SyncValueStoreCache() override; - base::WeakPtr<SyncValueStoreCache> AsWeakPtr(); - syncer::SyncableService* GetSyncableService(syncer::ModelType type) const; // ValueStoreCache implementation: @@ -56,7 +52,6 @@ bool initialized_; std::unique_ptr<SyncStorageBackend> app_backend_; std::unique_ptr<SyncStorageBackend> extension_backend_; - base::WeakPtrFactory<SyncValueStoreCache> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(SyncValueStoreCache); };
diff --git a/chrome/browser/extensions/chrome_requirements_checker.cc b/chrome/browser/extensions/chrome_requirements_checker.cc deleted file mode 100644 index 3aeacef..0000000 --- a/chrome/browser/extensions/chrome_requirements_checker.cc +++ /dev/null
@@ -1,89 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/extensions/chrome_requirements_checker.h" - -#include "base/bind.h" -#include "build/build_config.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/gpu_feature_checker.h" -#include "extensions/common/extension.h" -#include "extensions/common/manifest.h" -#include "extensions/common/manifest_handlers/requirements_info.h" -#include "gpu/config/gpu_feature_type.h" -#include "ui/base/l10n/l10n_util.h" - -namespace extensions { - -ChromeRequirementsChecker::ChromeRequirementsChecker() - : pending_requirement_checks_(0), weak_ptr_factory_(this) { -} - -ChromeRequirementsChecker::~ChromeRequirementsChecker() { -} - -void ChromeRequirementsChecker::Check( - const scoped_refptr<const Extension>& extension, - const RequirementsCheckedCallback& callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - callback_ = callback; - const RequirementsInfo& requirements = - RequirementsInfo::GetRequirements(extension.get()); - - if (requirements.npapi) { -#if defined(OS_POSIX) && !defined(OS_MACOSX) - errors_.push_back( - l10n_util::GetStringUTF8(IDS_EXTENSION_NPAPI_NOT_SUPPORTED)); -#endif - } - - if (requirements.window_shape) { -#if !defined(USE_AURA) - errors_.push_back( - l10n_util::GetStringUTF8(IDS_EXTENSION_WINDOW_SHAPE_NOT_SUPPORTED)); -#endif - } - - if (requirements.webgl) { - ++pending_requirement_checks_; - webgl_checker_ = content::GpuFeatureChecker::Create( - gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL, - base::Bind(&ChromeRequirementsChecker::SetWebGLAvailability, - weak_ptr_factory_.GetWeakPtr())); - } - - if (pending_requirement_checks_ == 0) { - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - base::Bind(callback_, errors_)); - // Reset the callback so any ref-counted bound parameters will get released. - callback_.Reset(); - return; - } - // Running the GPU checkers down here removes any race condition that arises - // from the use of pending_requirement_checks_. - if (webgl_checker_.get()) - webgl_checker_->CheckGpuFeatureAvailability(); -} - -void ChromeRequirementsChecker::SetWebGLAvailability(bool available) { - if (!available) { - errors_.push_back( - l10n_util::GetStringUTF8(IDS_EXTENSION_WEBGL_NOT_SUPPORTED)); - } - MaybeRunCallback(); -} - -void ChromeRequirementsChecker::MaybeRunCallback() { - if (--pending_requirement_checks_ == 0) { - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - base::Bind(callback_, errors_)); - // Reset the callback so any ref-counted bound parameters will get released. - callback_.Reset(); - errors_.clear(); - } -} - -} // namespace extensions
diff --git a/chrome/browser/extensions/chrome_requirements_checker.h b/chrome/browser/extensions/chrome_requirements_checker.h deleted file mode 100644 index 07304e9..0000000 --- a/chrome/browser/extensions/chrome_requirements_checker.h +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_EXTENSIONS_CHROME_REQUIREMENTS_CHECKER_H_ -#define CHROME_BROWSER_EXTENSIONS_CHROME_REQUIREMENTS_CHECKER_H_ - -#include <vector> - -#include "base/callback.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "extensions/browser/requirements_checker.h" - -namespace content { -class GpuFeatureChecker; -} - -namespace extensions { -class Extension; - -// Validates the 'requirements' extension manifest field. This is an -// asynchronous process that involves several threads, but the public interface -// of this class (including constructor and destructor) must only be used on -// the UI thread. -class ChromeRequirementsChecker : public RequirementsChecker { - public: - ChromeRequirementsChecker(); - ~ChromeRequirementsChecker() override; - - private: - // RequirementsChecker: - void Check(const scoped_refptr<const Extension>& extension, - const RequirementsCheckedCallback& callback) override; - - // Callbacks for the GpuFeatureChecker. - void SetWebGLAvailability(bool available); - - void MaybeRunCallback(); - - std::vector<std::string> errors_; - - // Every requirement that needs to be resolved asynchronously will add to - // this counter. When the counter is depleted, the callback will be run. - int pending_requirement_checks_; - - scoped_refptr<content::GpuFeatureChecker> webgl_checker_; - - RequirementsCheckedCallback callback_; - - base::WeakPtrFactory<ChromeRequirementsChecker> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(ChromeRequirementsChecker); -}; - -} // namespace extensions - -#endif // CHROME_BROWSER_EXTENSIONS_CHROME_REQUIREMENTS_CHECKER_H_
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index beb79a7..05462ce 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc
@@ -526,12 +526,11 @@ return; // Check for requirement errors. - if (!install_checker_->requirement_errors().empty()) { + if (!install_checker_->requirements_error_message().empty()) { if (error_on_unsupported_requirements_) { ReportFailureFromUIThread( CrxInstallError(CrxInstallError::ERROR_DECLINED, - base::UTF8ToUTF16(base::JoinString( - install_checker_->requirement_errors(), " ")))); + install_checker_->requirements_error_message())); return; } install_flags_ |= kInstallFlagHasRequirementErrors; @@ -569,9 +568,8 @@ // Note: |client_| can be NULL in unit_tests! if (extension()->from_webstore() && client_) client_->install_ui()->SetSkipPostInstallUI(true); - ReportFailureFromUIThread( - CrxInstallError(CrxInstallError::ERROR_DECLINED, - base::UTF8ToUTF16(install_checker_->policy_error()))); + ReportFailureFromUIThread(CrxInstallError( + CrxInstallError::ERROR_DECLINED, install_checker_->policy_error())); return; }
diff --git a/chrome/browser/extensions/extension_install_checker.cc b/chrome/browser/extensions/extension_install_checker.cc index 8117973..d529647e 100644 --- a/chrome/browser/extensions/extension_install_checker.cc +++ b/chrome/browser/extensions/extension_install_checker.cc
@@ -10,11 +10,11 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/blacklist.h" #include "chrome/browser/extensions/blacklist_check.h" -#include "chrome/browser/extensions/chrome_requirements_checker.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/policy_check.h" +#include "extensions/browser/requirements_checker.h" namespace extensions { @@ -72,7 +72,7 @@ void ExtensionInstallChecker::CheckManagementPolicy() { // In tests, this check may already be stubbed. if (!policy_check_) - policy_check_ = base::MakeUnique<PolicyCheck>(profile_, extension_.get()); + policy_check_ = base::MakeUnique<PolicyCheck>(profile_, extension_); policy_check_->Start( base::BindOnce(&ExtensionInstallChecker::OnManagementPolicyCheckDone, weak_ptr_factory_.GetWeakPtr())); @@ -82,7 +82,7 @@ PreloadCheck::Errors errors) { if (!errors.empty()) { DCHECK_EQ(1u, errors.count(PreloadCheck::DISALLOWED_BY_POLICY)); - policy_error_ = base::UTF16ToUTF8(policy_check_->GetErrorMessage()); + policy_error_ = policy_check_->GetErrorMessage(); } running_checks_ &= ~CHECK_MANAGEMENT_POLICY; @@ -90,17 +90,19 @@ } void ExtensionInstallChecker::CheckRequirements() { - requirements_checker_ = base::MakeUnique<ChromeRequirementsChecker>(); - requirements_checker_->Check( - extension_, base::Bind(&ExtensionInstallChecker::OnRequirementsCheckDone, - weak_ptr_factory_.GetWeakPtr())); + // In tests, this check may already be stubbed. + if (!requirements_check_) + requirements_check_ = base::MakeUnique<RequirementsChecker>(extension_); + requirements_check_->Start( + base::BindOnce(&ExtensionInstallChecker::OnRequirementsCheckDone, + weak_ptr_factory_.GetWeakPtr())); } void ExtensionInstallChecker::OnRequirementsCheckDone( - const std::vector<std::string>& errors) { + PreloadCheck::Errors errors) { DCHECK(is_running()); - requirement_errors_ = errors; + requirements_error_message_ = requirements_check_->GetErrorMessage(); running_checks_ &= ~CHECK_REQUIREMENTS; MaybeInvokeCallback(); @@ -109,8 +111,8 @@ void ExtensionInstallChecker::CheckBlacklistState() { // In tests, this check may already be stubbed. if (!blacklist_check_) { - blacklist_check_ = base::MakeUnique<BlacklistCheck>( - Blacklist::Get(profile_), extension_.get()); + blacklist_check_ = + base::MakeUnique<BlacklistCheck>(Blacklist::Get(profile_), extension_); } blacklist_check_->Start( base::BindOnce(&ExtensionInstallChecker::OnBlacklistStateCheckDone, @@ -140,7 +142,7 @@ int failed_mask = 0; if (blacklist_error_ == PreloadCheck::BLACKLISTED_ID) failed_mask |= CHECK_BLACKLIST; - if (!requirement_errors_.empty()) + if (!requirements_error_message_.empty()) failed_mask |= CHECK_REQUIREMENTS; if (!policy_error_.empty()) failed_mask |= CHECK_MANAGEMENT_POLICY; @@ -153,7 +155,7 @@ // If we are failing fast, discard any pending results. blacklist_check_.reset(); policy_check_.reset(); - requirements_checker_.reset(); + requirements_check_.reset(); weak_ptr_factory_.InvalidateWeakPtrs(); base::ResetAndReturn(&callback_).Run(failed_mask); }
diff --git a/chrome/browser/extensions/extension_install_checker.h b/chrome/browser/extensions/extension_install_checker.h index 17da2427..767c466 100644 --- a/chrome/browser/extensions/extension_install_checker.h +++ b/chrome/browser/extensions/extension_install_checker.h
@@ -20,8 +20,6 @@ namespace extensions { -class RequirementsChecker; - // Performs common checks for validating whether an extension may be installed. // This class should be Start()-ed at most once. class ExtensionInstallChecker { @@ -60,10 +58,9 @@ // Returns true if any checks are currently running. bool is_running() const { return running_checks_ != 0; } - // Returns the requirement violations. A non-empty list is considered to be - // a check failure. - const std::vector<std::string>& requirement_errors() const { - return requirement_errors_; + // Returns the error message for requirement violations, if any were found. + const base::string16& requirements_error_message() const { + return requirements_error_message_; } // Returns the blacklist error of the extension. Note that there is only an @@ -71,7 +68,7 @@ PreloadCheck::Error blacklist_error() const { return blacklist_error_; } // Returns whether management policy permits installation of the extension. - const std::string& policy_error() const { return policy_error_; } + const base::string16& policy_error() const { return policy_error_; } void SetBlacklistCheckForTesting(std::unique_ptr<PreloadCheck> policy_check) { blacklist_check_ = std::move(policy_check); @@ -79,13 +76,17 @@ void SetPolicyCheckForTesting(std::unique_ptr<PreloadCheck> policy_check) { policy_check_ = std::move(policy_check); } + void SetRequirementsCheckForTesting( + std::unique_ptr<PreloadCheck> requirements_check) { + requirements_check_ = std::move(requirements_check); + } protected: virtual void CheckManagementPolicy(); void OnManagementPolicyCheckDone(PreloadCheck::Errors errors); virtual void CheckRequirements(); - void OnRequirementsCheckDone(const std::vector<std::string>& errors); + void OnRequirementsCheckDone(PreloadCheck::Errors errors); virtual void CheckBlacklistState(); void OnBlacklistStateCheckDone(PreloadCheck::Errors errors); @@ -100,8 +101,8 @@ scoped_refptr<const Extension> extension_; // Checks requirements specified in the manifest. - std::unique_ptr<RequirementsChecker> requirements_checker_; - std::vector<std::string> requirement_errors_; + std::unique_ptr<PreloadCheck> requirements_check_; + base::string16 requirements_error_message_; // Checks if the extension is blacklisted. std::unique_ptr<PreloadCheck> blacklist_check_; @@ -109,7 +110,7 @@ // Checks whether management policies allow the extension to be installed. std::unique_ptr<PreloadCheck> policy_check_; - std::string policy_error_; + base::string16 policy_error_; // Bitmask of enabled checks. int enabled_checks_;
diff --git a/chrome/browser/extensions/extension_install_checker_unittest.cc b/chrome/browser/extensions/extension_install_checker_unittest.cc index 36307ff..5c4238a4 100644 --- a/chrome/browser/extensions/extension_install_checker_unittest.cc +++ b/chrome/browser/extensions/extension_install_checker_unittest.cc
@@ -34,41 +34,13 @@ ~ExtensionInstallCheckerForTest() override {} - void set_requirements_error(const std::string& error) { - requirements_error_ = error; - } - bool is_async() const { return is_async_; } void set_is_async(bool is_async) { is_async_ = is_async; } - protected: - void MockCheckRequirements() { - if (!is_running()) - return; - std::vector<std::string> errors; - if (!requirements_error_.empty()) - errors.push_back(requirements_error_); - OnRequirementsCheckDone(errors); - } - - void CheckRequirements() override { - if (is_async_) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&ExtensionInstallCheckerForTest::MockCheckRequirements, - base::Unretained(this))); - } else { - MockCheckRequirements(); - } - } - private: // Whether to run the requirements and blacklist checks asynchronously, as // they often do in ExtensionInstallChecker. bool is_async_ = false; - - // Dummy error for testing. - std::string requirements_error_; }; class CheckObserver { @@ -121,29 +93,41 @@ checker->SetPolicyCheckForTesting(std::move(policy_check)); } + void SetRequirementsError(ExtensionInstallCheckerForTest* checker, + PreloadCheck::Error error, + const std::string& message) { + auto requirements_check = base::MakeUnique<PreloadCheckStub>(); + requirements_check->set_is_async(checker->is_async()); + if (error != PreloadCheck::NONE) { + requirements_check->AddError(error); + requirements_check->set_error_message(base::UTF8ToUTF16(message)); + } + checker->SetRequirementsCheckForTesting(std::move(requirements_check)); + } + protected: void SetAllPass(ExtensionInstallCheckerForTest* checker) { SetBlacklistError(checker, PreloadCheck::NONE); SetPolicyError(checker, PreloadCheck::NONE, ""); - checker->set_requirements_error(""); + SetRequirementsError(checker, PreloadCheck::NONE, ""); } void SetAllErrors(ExtensionInstallCheckerForTest* checker) { SetBlacklistError(checker, kBlacklistError); SetPolicyError(checker, PreloadCheck::DISALLOWED_BY_POLICY, kDummyPolicyError); - checker->set_requirements_error(kDummyRequirementsError); + SetRequirementsError(checker, PreloadCheck::NPAPI_NOT_SUPPORTED, + kDummyRequirementsError); } void ExpectRequirementsPass(const ExtensionInstallCheckerForTest& checker) { - EXPECT_TRUE(checker.requirement_errors().empty()); + EXPECT_EQ(base::string16(), checker.requirements_error_message()); } void ExpectRequirementsError(const char* expected_error, const ExtensionInstallCheckerForTest& checker) { - EXPECT_FALSE(checker.requirement_errors().empty()); - EXPECT_EQ(std::string(expected_error), - checker.requirement_errors().front()); + EXPECT_EQ(base::UTF8ToUTF16(expected_error), + checker.requirements_error_message()); } void ExpectRequirementsError(const ExtensionInstallCheckerForTest& checker) { @@ -165,7 +149,7 @@ void ExpectPolicyError(const char* expected_error, const ExtensionInstallCheckerForTest& checker) { EXPECT_FALSE(checker.policy_error().empty()); - EXPECT_EQ(std::string(expected_error), checker.policy_error()); + EXPECT_EQ(base::UTF8ToUTF16(expected_error), checker.policy_error()); } void ExpectPolicyError(const ExtensionInstallCheckerForTest& checker) {
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 06617e6d..9338f19 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -654,7 +654,9 @@ extensions::UnpackedInstaller::Create(this)->LoadFromCommandLine( base::FilePath(t.token()), &extension_id, false /*only-allow-apps*/); // Extension id is added to whitelist after its extension is loaded - // because code is executed asynchronously. + // because code is executed asynchronously. TODO(michaelpg): Remove this + // assumption so loading extensions does not have to be asynchronous: + // crbug.com/708354. if (switch_name == switches::kDisableExtensionsExcept) disable_flag_exempted_extensions_.insert(extension_id); }
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index ee94ed9..d1e8c5e4 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -78,7 +78,6 @@ #include "chrome/browser/ui/global_error/global_error_service_factory.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/extensions/api/plugins/plugins_handler.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h" #include "chrome/common/pref_names.h" @@ -123,6 +122,7 @@ #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/manifest_handlers/permissions_parser.h" +#include "extensions/common/manifest_handlers/plugins_handler.h" #include "extensions/common/manifest_url_handlers.h" #include "extensions/common/permissions/permission_set.h" #include "extensions/common/permissions/permissions_data.h"
diff --git a/chrome/browser/extensions/plugin_manager.cc b/chrome/browser/extensions/plugin_manager.cc index 0b9d50e..688f79f 100644 --- a/chrome/browser/extensions/plugin_manager.cc +++ b/chrome/browser/extensions/plugin_manager.cc
@@ -2,21 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/extensions/plugin_manager.h" + #include "base/files/file_path.h" #include "base/lazy_instance.h" #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/plugin_manager.h" #include "chrome/browser/plugins/chrome_plugin_service_filter.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_paths.h" -#include "chrome/common/extensions/api/plugins/plugins_handler.h" #include "content/public/browser/plugin_service.h" #include "content/public/common/pepper_plugin_info.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" #include "extensions/common/manifest_handlers/mime_types_handler.h" +#include "extensions/common/manifest_handlers/plugins_handler.h" #include "url/gurl.h" #if !defined(DISABLE_NACL)
diff --git a/chrome/browser/extensions/requirements_checker_browsertest.cc b/chrome/browser/extensions/requirements_checker_browsertest.cc deleted file mode 100644 index d8d40e4a..0000000 --- a/chrome/browser/extensions/requirements_checker_browsertest.cc +++ /dev/null
@@ -1,136 +0,0 @@ -// Copyright (c) 2012 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 <vector> - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" -#include "base/path_service.h" -#include "base/strings/string_util.h" -#include "build/build_config.h" -#include "chrome/browser/extensions/chrome_requirements_checker.h" -#include "chrome/browser/extensions/extension_browsertest.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/grit/generated_resources.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/gpu_data_manager.h" -#include "content/public/test/test_utils.h" -#include "extensions/common/extension.h" -#include "extensions/common/file_util.h" -#include "ui/base/l10n/l10n_util.h" - -namespace extensions { - -class RequirementsCheckerBrowserTest : public ExtensionBrowserTest { - public: - RequirementsCheckerBrowserTest() - : checker_(new ChromeRequirementsChecker()) {} - - scoped_refptr<const Extension> LoadExtensionFromDirName( - const std::string& extension_dir_name) { - base::FilePath extension_path; - std::string load_error; - PathService::Get(chrome::DIR_TEST_DATA, &extension_path); - extension_path = extension_path.AppendASCII("requirements_checker") - .AppendASCII(extension_dir_name); - scoped_refptr<const Extension> extension = file_util::LoadExtension( - extension_path, Manifest::UNPACKED, 0, &load_error); - CHECK_EQ(0U, load_error.length()); - return extension; - } - - void ValidateRequirementErrors( - const std::vector<std::string>& expected_errors, - const std::vector<std::string>& actual_errors) { - ASSERT_EQ(expected_errors, actual_errors); - } - - protected: - std::unique_ptr<RequirementsChecker> checker_; -}; - -IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, CheckEmptyExtension) { - scoped_refptr<const Extension> extension( - LoadExtensionFromDirName("no_requirements")); - ASSERT_TRUE(extension.get()); - checker_->Check(extension, base::Bind( - &RequirementsCheckerBrowserTest::ValidateRequirementErrors, - base::Unretained(this), std::vector<std::string>())); - content::RunAllBlockingPoolTasksUntilIdle(); -} - -IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, CheckNpapiExtension) { - scoped_refptr<const Extension> extension( - LoadExtensionFromDirName("require_npapi")); - ASSERT_TRUE(extension.get()); - - std::vector<std::string> expected_errors; -#if defined(OS_POSIX) && !defined(OS_MACOSX) - expected_errors.push_back(l10n_util::GetStringUTF8( - IDS_EXTENSION_NPAPI_NOT_SUPPORTED)); -#endif - - checker_->Check(extension, base::Bind( - &RequirementsCheckerBrowserTest::ValidateRequirementErrors, - base::Unretained(this), expected_errors)); - content::RunAllBlockingPoolTasksUntilIdle(); -} - -IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, - CheckWindowShapeExtension) { - scoped_refptr<const Extension> extension( - LoadExtensionFromDirName("require_window_shape")); - ASSERT_TRUE(extension.get()); - - std::vector<std::string> expected_errors; -#if !defined(USE_AURA) - expected_errors.push_back(l10n_util::GetStringUTF8( - IDS_EXTENSION_WINDOW_SHAPE_NOT_SUPPORTED)); -#endif // !defined(USE_AURA) - - checker_->Check(extension, base::Bind( - &RequirementsCheckerBrowserTest::ValidateRequirementErrors, - base::Unretained(this), expected_errors)); - content::RunAllBlockingPoolTasksUntilIdle(); -} - -IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, DisallowWebGL) { - scoped_refptr<const Extension> extension( - LoadExtensionFromDirName("require_3d")); - ASSERT_TRUE(extension.get()); - - content::GpuDataManager::GetInstance()->BlacklistWebGLForTesting(); - content::RunAllBlockingPoolTasksUntilIdle(); - - std::vector<std::string> expected_errors; - expected_errors.push_back(l10n_util::GetStringUTF8( - IDS_EXTENSION_WEBGL_NOT_SUPPORTED)); - - checker_->Check(extension, base::Bind( - &RequirementsCheckerBrowserTest::ValidateRequirementErrors, - base::Unretained(this), expected_errors)); - content::RunAllBlockingPoolTasksUntilIdle(); -} - -IN_PROC_BROWSER_TEST_F(RequirementsCheckerBrowserTest, Check3DExtension) { - scoped_refptr<const Extension> extension( - LoadExtensionFromDirName("require_3d")); - ASSERT_TRUE(extension.get()); - - std::vector<std::string> expected_errors; - - if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL)) { - expected_errors.push_back(l10n_util::GetStringUTF8( - IDS_EXTENSION_WEBGL_NOT_SUPPORTED)); - } - - checker_->Check(extension, base::Bind( - &RequirementsCheckerBrowserTest::ValidateRequirementErrors, - base::Unretained(this), expected_errors)); - content::RunAllBlockingPoolTasksUntilIdle(); -} - -} // namespace extensions
diff --git a/chrome/browser/extensions/unpacked_installer.cc b/chrome/browser/extensions/unpacked_installer.cc index 148113f3..0d93fcc 100644 --- a/chrome/browser/extensions/unpacked_installer.cc +++ b/chrome/browser/extensions/unpacked_installer.cc
@@ -8,7 +8,9 @@ #include "base/callback.h" #include "base/files/file_util.h" #include "base/memory/ptr_util.h" +#include "base/strings/string16.h" #include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" #include "base/threading/thread_restrictions.h" #include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/extension_install_checker.h" @@ -18,7 +20,6 @@ #include "chrome/browser/extensions/permissions_updater.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/extensions/extension_install_ui_factory.h" -#include "chrome/common/extensions/api/plugins/plugins_handler.h" #include "components/crx_file/id_util.h" #include "components/sync/model/string_ordinal.h" #include "content/public/browser/browser_thread.h" @@ -30,6 +31,7 @@ #include "extensions/common/extension_l10n_util.h" #include "extensions/common/file_util.h" #include "extensions/common/manifest.h" +#include "extensions/common/manifest_handlers/plugins_handler.h" #include "extensions/common/manifest_handlers/shared_module_info.h" #include "extensions/common/permissions/permissions_data.h" @@ -253,14 +255,12 @@ void UnpackedInstaller::OnInstallChecksComplete(int failed_checks) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!install_checker_->policy_error().empty()) { - ReportExtensionLoadError(install_checker_->policy_error()); - return; - } + base::string16 error_message = install_checker_->policy_error(); + if (error_message.empty()) + error_message = install_checker_->requirements_error_message(); - if (!install_checker_->requirement_errors().empty()) { - ReportExtensionLoadError( - base::JoinString(install_checker_->requirement_errors(), " ")); + if (!error_message.empty()) { + ReportExtensionLoadError(base::UTF16ToUTF8(error_message)); return; }
diff --git a/chrome/browser/mac/keychain_reauthorize.h b/chrome/browser/mac/keychain_reauthorize.h index 63f22fa5..d94488f 100644 --- a/chrome/browser/mac/keychain_reauthorize.h +++ b/chrome/browser/mac/keychain_reauthorize.h
@@ -32,8 +32,9 @@ void KeychainReauthorizeIfNeeded(NSString* pref_key, int max_tries); // A wrapper to call KeychainReauthorizeIfNeeded under a local autorelease pool. -// This is used to call the function from the keychain_reauthorization binary in -// the keystone_install.sh script. +// This is used by the keychain_reauthorization stub executable, which is run at +// update time or at browser launch. The name cannot be changed to indicate that +// it is not only run at update because the stub is already built and signed. __attribute__((visibility("default"))) void KeychainReauthorizeIfNeededAtUpdate( NSString* pref_key, int max_tries);
diff --git a/chrome/browser/mac/keychain_reauthorize.mm b/chrome/browser/mac/keychain_reauthorize.mm index 3c9b3283..edcad407 100644 --- a/chrome/browser/mac/keychain_reauthorize.mm +++ b/chrome/browser/mac/keychain_reauthorize.mm
@@ -7,16 +7,26 @@ #import <Foundation/Foundation.h> #include <Security/Security.h> +#include <crt_externs.h> +#include <errno.h> +#include <spawn.h> #include <string.h> #include <vector> +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/logging.h" +#include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" #include "base/mac/mac_logging.h" #include "base/mac/scoped_cftyperef.h" #include "base/metrics/histogram_macros.h" +#include "base/path_service.h" +#include "base/posix/eintr_wrapper.h" #include "base/scoped_generic.h" +#include "base/strings/sys_string_conversions.h" #include "components/os_crypt/keychain_password_mac.h" #include "crypto/apple_keychain.h" @@ -126,9 +136,30 @@ return true; } +// This performs the re-reauthorization from the stub executable. +void KeychainReauthorizeFromStub(NSString* pref_key) { + NSUserDefaults* user_defaults = [NSUserDefaults standardUserDefaults]; + + NSString* success_pref_key = [pref_key stringByAppendingString:@"Success"]; + BOOL success_value = [user_defaults boolForKey:success_pref_key]; + if (success_value) + return; + + bool success = KeychainReauthorize(); + if (!success) + return; + + [user_defaults setBool:YES forKey:success_pref_key]; + [user_defaults synchronize]; +} + } // namespace void KeychainReauthorizeIfNeeded(NSString* pref_key, int max_tries) { +#if defined(GOOGLE_CHROME_BUILD) + // Only launch the stub executable when running in the browser. + DCHECK(base::mac::AmIBundled()); + NSUserDefaults* user_defaults = [NSUserDefaults standardUserDefaults]; int pref_value = [user_defaults integerForKey:pref_key]; @@ -142,39 +173,63 @@ if (pref_value > 0) { // Logs the number of previous tries that didn't complete. - if (base::mac::AmIBundled()) { - UMA_HISTOGRAM_SPARSE_SLOWLY("OSX.KeychainReauthorizeIfNeeded", - pref_value); - } else { - UMA_HISTOGRAM_SPARSE_SLOWLY("OSX.KeychainReauthorizeIfNeededAtUpdate", - pref_value); - } + UMA_HISTOGRAM_SPARSE_SLOWLY("OSX.KeychainReauthorizeIfNeeded", pref_value); } ++pref_value; [user_defaults setInteger:pref_value forKey:pref_key]; [user_defaults synchronize]; - bool success = KeychainReauthorize(); - if (!success) + NSBundle* main_bundle = base::mac::OuterBundle(); + std::string identifier = + base::SysNSStringToUTF8([main_bundle bundleIdentifier]); + std::string bundle_path = base::SysNSStringToUTF8([main_bundle bundlePath]); + + base::FilePath reauth_binary = base::FilePath(bundle_path) + .Append("Contents") + .Append("Helpers") + .Append(identifier); + + std::string framework_path = + base::SysNSStringToUTF8([base::mac::FrameworkBundle() executablePath]); + + std::vector<std::string> argv = {reauth_binary.value(), framework_path}; + std::vector<char*> argv_cstr; + argv_cstr.reserve(argv.size() + 1); + for (size_t i = 0; i < argv.size(); ++i) { + argv_cstr.push_back(const_cast<char*>(argv[i].c_str())); + } + argv_cstr.push_back(nullptr); + + pid_t pid; + char** new_environ = *_NSGetEnviron(); + errno = posix_spawn(&pid, reauth_binary.value().c_str(), nullptr, nullptr, + &argv_cstr[0], new_environ); + if (errno != 0) { + PLOG(ERROR) << "posix_spawn"; return; + } else { + // If execution does not block on the helper stub, there is a + // race condition between it and Chrome creating a new keychain entry. + int status; + if (HANDLE_EINTR(waitpid(pid, &status, 0)) != pid || status != 0) { + return; + } + } - [user_defaults setBool:YES forKey:success_pref_key]; - [user_defaults synchronize]; - + // Find out if the re-authorization succeeded by querying cfprefs. + bool stub_result = [user_defaults boolForKey:success_pref_key]; // Logs the try number (1, 2) that succeeded. - if (base::mac::AmIBundled()) { + if (stub_result) { UMA_HISTOGRAM_SPARSE_SLOWLY("OSX.KeychainReauthorizeIfNeededSuccess", pref_value); - } else { - UMA_HISTOGRAM_SPARSE_SLOWLY( - "OSX.KeychainReauthorizeIfNeededAtUpdateSuccess", pref_value); } +#endif // defined(GOOGLE_CHROME_BUILD) } void KeychainReauthorizeIfNeededAtUpdate(NSString* pref_key, int max_tries) { @autoreleasepool { - KeychainReauthorizeIfNeeded(pref_key, max_tries); + KeychainReauthorizeFromStub(pref_key); } }
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc index 3c2cd1a..f192c9b 100644 --- a/chrome/browser/media/encrypted_media_browsertest.cc +++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -294,8 +294,6 @@ RegisterPepperCdm(command_line, kClearKeyCdmBaseDirectory, kClearKeyCdmAdapterFileName, kClearKeyCdmDisplayName, kClearKeyCdmPepperMimeType); - // Need to tell CdmHostFile(s) to ignore missing CDM host files in tests. - command_line->AppendSwitch(switches::kIgnoreMissingCdmHostFile); command_line->AppendSwitchASCII(switches::kEnableFeatures, media::kExternalClearKeyForTesting.name); }
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list.cc b/chrome/browser/media/webrtc/native_desktop_media_list.cc index 7db6e32..d6039e1 100644 --- a/chrome/browser/media/webrtc/native_desktop_media_list.cc +++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
@@ -27,6 +27,10 @@ #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" #endif // defined(USE_X11) && !defined(OS_CHROMEOS) +#if defined(USE_AURA) +#include "ui/snapshot/snapshot_aura.h" +#endif + using content::BrowserThread; using content::DesktopMediaID; @@ -342,7 +346,7 @@ gfx::Rect(thumbnail_size_), window_rect.size()); pending_aura_capture_requests_++; - ui::GrabWindowSnapshotAndScaleAsync( + ui::GrabWindowSnapshotAndScaleAsyncAura( window, window_rect, scaled_rect.size(), BrowserThread::GetBlockingPool(), base::Bind(&NativeDesktopMediaList::OnAuraThumbnailCaptured, weak_factory_.GetWeakPtr(), id));
diff --git a/chrome/browser/page_load_metrics/experiments/delay_navigation_throttle.cc b/chrome/browser/page_load_metrics/experiments/delay_navigation_throttle.cc index 503641a..bc32e8f 100644 --- a/chrome/browser/page_load_metrics/experiments/delay_navigation_throttle.cc +++ b/chrome/browser/page_load_metrics/experiments/delay_navigation_throttle.cc
@@ -6,6 +6,7 @@ #include "base/memory/ptr_util.h" #include "base/metrics/field_trial_params.h" +#include "base/metrics/histogram_macros.h" #include "base/rand_util.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/profiles/profile.h" @@ -15,6 +16,13 @@ namespace { +const char kHistogramNavigationDelaySpecified[] = + "DelayNavigationThrottle.Delay.Specified"; +const char kHistogramNavigationDelayActual[] = + "DelayNavigationThrottle.Delay.Actual"; +const char kHistogramNavigationDelayDelta[] = + "DelayNavigationThrottle.Delay.Delta"; + base::TimeDelta GetNavigationDelayFromParams() { double delay_probability = base::GetFieldTrialParamByFeatureAsDouble( kDelayNavigationFeature, @@ -100,6 +108,8 @@ content::NavigationThrottle::ThrottleCheckResult DelayNavigationThrottle::WillStartRequest() { + UMA_HISTOGRAM_TIMES(kHistogramNavigationDelaySpecified, navigation_delay_); + delay_start_time_ = base::TimeTicks::Now(); task_runner_->PostDelayedTask( FROM_HERE, base::Bind(&DelayNavigationThrottle::OnDelayComplete, @@ -109,5 +119,9 @@ } void DelayNavigationThrottle::OnDelayComplete() { + base::TimeDelta actual_delay = base::TimeTicks::Now() - delay_start_time_; + base::TimeDelta delay_delta = actual_delay - navigation_delay_; + UMA_HISTOGRAM_TIMES(kHistogramNavigationDelayActual, actual_delay); + UMA_HISTOGRAM_TIMES(kHistogramNavigationDelayDelta, delay_delta.magnitude()); navigation_handle()->Resume(); }
diff --git a/chrome/browser/page_load_metrics/experiments/delay_navigation_throttle.h b/chrome/browser/page_load_metrics/experiments/delay_navigation_throttle.h index cea38df1..6456f3a2 100644 --- a/chrome/browser/page_load_metrics/experiments/delay_navigation_throttle.h +++ b/chrome/browser/page_load_metrics/experiments/delay_navigation_throttle.h
@@ -60,6 +60,9 @@ const scoped_refptr<base::TaskRunner> task_runner_; const base::TimeDelta navigation_delay_; + // The time we added a delay to this navigation. + base::TimeTicks delay_start_time_; + // This has to be the last member of the class. base::WeakPtrFactory<DelayNavigationThrottle> weak_ptr_factory_;
diff --git a/chrome/browser/resources/settings/search_page/search_page.js b/chrome/browser/resources/settings/search_page/search_page.js index 01f0016..edcf246 100644 --- a/chrome/browser/resources/settings/search_page/search_page.js +++ b/chrome/browser/resources/settings/search_page/search_page.js
@@ -54,16 +54,14 @@ // Omnibox search engine var updateSearchEngines = function(searchEngines) { this.set('searchEngines_', searchEngines.defaults); + this.requestHotwordInfoUpdate_(); }.bind(this); this.browserProxy_.getSearchEnginesList().then(updateSearchEngines); cr.addWebUIListener('search-engines-changed', updateSearchEngines); - // Hotword (OK Google) + // Hotword (OK Google) listener cr.addWebUIListener( 'hotword-info-update', this.hotwordInfoUpdate_.bind(this)); - this.browserProxy_.getHotwordInfo().then(function(hotwordInfo) { - this.hotwordInfoUpdate_(hotwordInfo); - }.bind(this)); // Google Now cards in the launcher cr.addWebUIListener( @@ -101,6 +99,13 @@ !!this.hotwordSearchEnablePref_.value); }, + /** @private */ + requestHotwordInfoUpdate_: function() { + this.browserProxy_.getHotwordInfo().then(function(hotwordInfo) { + this.hotwordInfoUpdate_(hotwordInfo); + }.bind(this)); + }, + /** * @param {!SearchPageHotwordInfo} hotwordInfo * @private
diff --git a/chrome/browser/speech/extension_api/tts_extension_apitest.cc b/chrome/browser/speech/extension_api/tts_extension_apitest.cc index eb5cfbfd..9911653e 100644 --- a/chrome/browser/speech/extension_api/tts_extension_apitest.cc +++ b/chrome/browser/speech/extension_api/tts_extension_apitest.cc
@@ -411,7 +411,13 @@ ASSERT_TRUE(RunExtensionTest("tts_engine/register_engine")) << message_; } -IN_PROC_BROWSER_TEST_F(TtsApiTest, EngineError) { +// https://crbug.com/709115 tracks test flakiness. +#if defined(OS_POSIX) +#define MAYBE_EngineError DISABLED_EngineError +#else +#define MAYBE_EngineError EngineError +#endif +IN_PROC_BROWSER_TEST_F(TtsApiTest, MAYBE_EngineError) { EXPECT_CALL(mock_platform_impl_, IsSpeaking()); EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillRepeatedly(Return(true));
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index 2670cc4..6a48990 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -120,75 +120,21 @@ #include "components/sync_wifi/wifi_credential_syncable_service_factory.h" #endif // defined(OS_CHROMEOS) -using base::Callback; -using base::WeakPtr; +using content::BrowserThread; #if BUILDFLAG(ENABLE_EXTENSIONS) using browser_sync::ExtensionDataTypeController; using browser_sync::ExtensionSettingDataTypeController; #endif // BUILDFLAG(ENABLE_EXTENSIONS) using browser_sync::SearchEngineDataTypeController; -using content::BrowserThread; using syncer::AsyncDirectoryTypeController; -using syncer::SyncableService; - -using ServiceProvider = syncer::SyncClient::ServiceProvider; namespace browser_sync { namespace { - #if defined(OS_WIN) const base::FilePath::CharType kLoopbackServerBackendFilename[] = FILE_PATH_LITERAL("profile.pb"); #endif // defined(OS_WIN) - -// The following are a set of functions to facilitate returning SyncableServices -// and SyncBridges. Non-UI model types sometimes have difficulties providing a -// WeakPtr to their integration object on the UI thread. By instead returning a -// Callback we are able to give model types a little bit of flexibility. - -// The preferred and simpler approach is to to retrieve your corresponding -// WeakPtr on the UI thread, which is where GetSyncableServiceForType() and -// GetSyncBridgeForModelType() are invoked. A simple Callback that just captures -// the WeakPtr can easy be returned. Trampoline() is all that's really required -// for this, with WrapInCallback() and WrapInProvider() adding syntactic sugar. -// All UI thread model types should be able to follow this pattern. - -// The other approach is capturing an intermediate thread safe object that is -// subsequently used on the model thread. Most model types that follow this -// pattern do things a little bit uniquely, but a common problem is not having -// a method that's going to return exactly the right type. For example, needing -// to up-cast or grab a WeakPtr after the model type specific functions are run -// in a Callback. - -template <typename T> -T Trampoline(T arg) { - return arg; -} - -template <typename T> -Callback<T()> WrapInCallback(T arg) { - return base::Bind(&Trampoline<T>, arg); -} - -WeakPtr<SyncableService> ServiceAsWeakPtr(SyncableService* ptr) { - return ptr ? ptr->AsWeakPtr() : WeakPtr<SyncableService>(); -} - -ServiceProvider WrapInProvider(SyncableService* service) { - return WrapInCallback(ServiceAsWeakPtr(service)); -} - -template <typename T> -WeakPtr<SyncableService> CallbackResultAsWeakPtr(Callback<T()> callback) { - return ServiceAsWeakPtr(callback.Run()); -} - -template <typename T> -ServiceProvider WrapInWeakPtrCallback(Callback<T()> callback) { - return base::Bind(&CallbackResultAsWeakPtr<T>, callback); -} - } // namespace // Chrome implementation of SyncSessionsClient. Needs to be in a separate class @@ -353,7 +299,7 @@ history::HistoryService* ChromeSyncClient::GetHistoryService() { DCHECK_CURRENTLY_ON(BrowserThread::UI); return HistoryServiceFactory::GetForProfile( - profile_, ServiceAccessType::IMPLICIT_ACCESS); + profile_, ServiceAccessType::EXPLICIT_ACCESS); } bool ChromeSyncClient::HasPasswordStore() { @@ -376,7 +322,7 @@ return base::Bind( #if defined(OS_ANDROID) &ChromeSyncClient::RegisterAndroidDataTypes, -#else // defined(OS_ANDROID) +#else &ChromeSyncClient::RegisterDesktopDataTypes, #endif // defined(OS_ANDROID) weak_ptr_factory_.GetWeakPtr()); @@ -403,135 +349,144 @@ return sync_sessions_client_.get(); } -ServiceProvider ChromeSyncClient::GetSyncableServiceForType( - syncer::ModelType type) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); +base::WeakPtr<syncer::SyncableService> +ChromeSyncClient::GetSyncableServiceForType(syncer::ModelType type) { if (!profile_) { // For tests. - return WrapInProvider(nullptr); + return base::WeakPtr<syncer::SyncableService>(); } switch (type) { case syncer::DEVICE_INFO: - return WrapInProvider(ProfileSyncServiceFactory::GetForProfile(profile_) - ->GetDeviceInfoSyncableService()); + return ProfileSyncServiceFactory::GetForProfile(profile_) + ->GetDeviceInfoSyncableService() + ->AsWeakPtr(); case syncer::PREFERENCES: + return PrefServiceSyncableFromProfile(profile_) + ->GetSyncableService(syncer::PREFERENCES) + ->AsWeakPtr(); case syncer::PRIORITY_PREFERENCES: - return WrapInProvider( - PrefServiceSyncableFromProfile(profile_)->GetSyncableService(type)); + return PrefServiceSyncableFromProfile(profile_) + ->GetSyncableService(syncer::PRIORITY_PREFERENCES) + ->AsWeakPtr(); case syncer::AUTOFILL: case syncer::AUTOFILL_PROFILE: case syncer::AUTOFILL_WALLET_DATA: case syncer::AUTOFILL_WALLET_METADATA: { - if (!web_data_service_) { - return WrapInProvider(nullptr); - } else if (type == syncer::AUTOFILL) { - return WrapInWeakPtrCallback(base::Bind( - &autofill::AutocompleteSyncableService::FromWebDataService, - base::RetainedRef(web_data_service_))); + if (!web_data_service_) + return base::WeakPtr<syncer::SyncableService>(); + if (type == syncer::AUTOFILL) { + return autofill::AutocompleteSyncableService::FromWebDataService( + web_data_service_.get())->AsWeakPtr(); } else if (type == syncer::AUTOFILL_PROFILE) { - return WrapInWeakPtrCallback(base::Bind( - &autofill::AutofillProfileSyncableService::FromWebDataService, - base::RetainedRef(web_data_service_))); + return autofill::AutofillProfileSyncableService::FromWebDataService( + web_data_service_.get())->AsWeakPtr(); } else if (type == syncer::AUTOFILL_WALLET_METADATA) { - return WrapInWeakPtrCallback( - base::Bind(&autofill::AutofillWalletMetadataSyncableService:: - FromWebDataService, - base::RetainedRef(web_data_service_))); - } else { - return WrapInWeakPtrCallback(base::Bind( - &autofill::AutofillWalletSyncableService::FromWebDataService, - base::RetainedRef(web_data_service_))); + return autofill::AutofillWalletMetadataSyncableService:: + FromWebDataService(web_data_service_.get())->AsWeakPtr(); } + return autofill::AutofillWalletSyncableService::FromWebDataService( + web_data_service_.get())->AsWeakPtr(); } case syncer::SEARCH_ENGINES: - return WrapInProvider(TemplateURLServiceFactory::GetForProfile(profile_)); + return TemplateURLServiceFactory::GetForProfile(profile_)->AsWeakPtr(); #if BUILDFLAG(ENABLE_EXTENSIONS) case syncer::APPS: case syncer::EXTENSIONS: - return WrapInProvider(ExtensionSyncService::Get(profile_)); + return ExtensionSyncService::Get(profile_)->AsWeakPtr(); case syncer::APP_SETTINGS: case syncer::EXTENSION_SETTINGS: - return extensions::settings_sync_util::GetSyncableServiceProvider( - profile_, type); + return extensions::settings_sync_util::GetSyncableService(profile_, type) + ->AsWeakPtr(); #endif // BUILDFLAG(ENABLE_EXTENSIONS) #if BUILDFLAG(ENABLE_APP_LIST) case syncer::APP_LIST: - return WrapInProvider( - app_list::AppListSyncableServiceFactory::GetForProfile(profile_)); + return app_list::AppListSyncableServiceFactory::GetForProfile(profile_)-> + AsWeakPtr(); #endif // BUILDFLAG(ENABLE_APP_LIST) #if !defined(OS_ANDROID) case syncer::THEMES: - return WrapInProvider(ThemeServiceFactory::GetForProfile(profile_) - ->GetThemeSyncableService()); + return ThemeServiceFactory::GetForProfile(profile_)-> + GetThemeSyncableService()->AsWeakPtr(); #endif // !defined(OS_ANDROID) - case syncer::HISTORY_DELETE_DIRECTIVES: - return WrapInProvider(GetHistoryService()); - case syncer::TYPED_URLS: { + case syncer::HISTORY_DELETE_DIRECTIVES: { history::HistoryService* history = GetHistoryService(); - return WrapInProvider(history ? history->GetTypedUrlSyncableService() - : nullptr); + return history ? history->AsWeakPtr() + : base::WeakPtr<history::HistoryService>(); + } + case syncer::TYPED_URLS: { + // We request history service with explicit access here because this + // codepath is executed on backend thread while HistoryServiceFactory + // checks preference value in implicit mode and PrefService expectes calls + // only from UI thread. + history::HistoryService* history = HistoryServiceFactory::GetForProfile( + profile_, ServiceAccessType::EXPLICIT_ACCESS); + if (!history) + return base::WeakPtr<history::TypedUrlSyncableService>(); + return history->GetTypedUrlSyncableService()->AsWeakPtr(); } #if BUILDFLAG(ENABLE_SPELLCHECK) case syncer::DICTIONARY: - return WrapInProvider(SpellcheckServiceFactory::GetForContext(profile_) - ->GetCustomDictionary()); + return SpellcheckServiceFactory::GetForContext(profile_)-> + GetCustomDictionary()->AsWeakPtr(); #endif // BUILDFLAG(ENABLE_SPELLCHECK) case syncer::FAVICON_IMAGES: - case syncer::FAVICON_TRACKING: - return WrapInProvider(ProfileSyncServiceFactory::GetForProfile(profile_) - ->GetFaviconCache()); + case syncer::FAVICON_TRACKING: { + sync_sessions::FaviconCache* favicons = + ProfileSyncServiceFactory::GetForProfile(profile_)->GetFaviconCache(); + return favicons ? favicons->AsWeakPtr() + : base::WeakPtr<syncer::SyncableService>(); + } #if BUILDFLAG(ENABLE_SUPERVISED_USERS) case syncer::SUPERVISED_USER_SETTINGS: - return WrapInProvider( - SupervisedUserSettingsServiceFactory::GetForProfile(profile_)); + return SupervisedUserSettingsServiceFactory::GetForProfile(profile_)-> + AsWeakPtr(); #if !defined(OS_ANDROID) case syncer::SUPERVISED_USERS: - return WrapInProvider( - SupervisedUserSyncServiceFactory::GetForProfile(profile_)); + return SupervisedUserSyncServiceFactory::GetForProfile(profile_)-> + AsWeakPtr(); case syncer::SUPERVISED_USER_SHARED_SETTINGS: - return WrapInProvider( - SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext( - profile_)); + return SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext( + profile_)->AsWeakPtr(); #endif // !defined(OS_ANDROID) case syncer::SUPERVISED_USER_WHITELISTS: - return WrapInProvider( - SupervisedUserServiceFactory::GetForProfile(profile_) - ->GetWhitelistService()); + return SupervisedUserServiceFactory::GetForProfile(profile_) + ->GetWhitelistService() + ->AsWeakPtr(); #endif // BUILDFLAG(ENABLE_SUPERVISED_USERS) case syncer::ARTICLES: { - dom_distiller::DomDistillerService* distiller_service = + dom_distiller::DomDistillerService* service = dom_distiller::DomDistillerServiceFactory::GetForBrowserContext( profile_); - return WrapInProvider(distiller_service - ? distiller_service->GetSyncableService() - : nullptr); + if (service) + return service->GetSyncableService()->AsWeakPtr(); + return base::WeakPtr<syncer::SyncableService>(); } - case syncer::SESSIONS: - return WrapInProvider(ProfileSyncServiceFactory::GetForProfile(profile_) - ->GetSessionsSyncableService()); - case syncer::PASSWORDS: + case syncer::SESSIONS: { + return ProfileSyncServiceFactory::GetForProfile(profile_)-> + GetSessionsSyncableService()->AsWeakPtr(); + } + case syncer::PASSWORDS: { return password_store_.get() - ? base::Bind(&password_manager::PasswordStore:: - GetPasswordSyncableService, - base::RetainedRef(password_store_)) - : WrapInProvider(nullptr); + ? password_store_->GetPasswordSyncableService() + : base::WeakPtr<syncer::SyncableService>(); + } #if defined(OS_CHROMEOS) case syncer::WIFI_CREDENTIALS: - return WrapInProvider( - sync_wifi::WifiCredentialSyncableServiceFactory::GetForBrowserContext( - profile_)); + return sync_wifi::WifiCredentialSyncableServiceFactory:: + GetForBrowserContext(profile_) + ->AsWeakPtr(); case syncer::ARC_PACKAGE: - return WrapInProvider(arc::ArcPackageSyncableService::Get(profile_)); + return arc::ArcPackageSyncableService::Get(profile_)->AsWeakPtr(); #endif // defined(OS_CHROMEOS) default: // The following datatypes still need to be transitioned to the // syncer::SyncableService API: // Bookmarks NOTREACHED(); - return WrapInProvider(nullptr); + return base::WeakPtr<syncer::SyncableService>(); } } -WeakPtr<syncer::ModelTypeSyncBridge> +base::WeakPtr<syncer::ModelTypeSyncBridge> ChromeSyncClient::GetSyncBridgeForModelType(syncer::ModelType type) { switch (type) { case syncer::DEVICE_INFO: @@ -541,7 +496,7 @@ case syncer::READING_LIST: // Reading List is only supported on iOS at the moment. NOTREACHED(); - return WeakPtr<syncer::ModelTypeSyncBridge>(); + return base::WeakPtr<syncer::ModelTypeSyncBridge>(); case syncer::AUTOFILL: return autofill::AutocompleteSyncBridge::FromWebDataService( web_data_service_.get()); @@ -557,7 +512,7 @@ return base::WeakPtr<syncer::ModelTypeSyncBridge>(); default: NOTREACHED(); - return WeakPtr<syncer::ModelTypeSyncBridge>(); + return base::WeakPtr<syncer::ModelTypeSyncBridge>(); } }
diff --git a/chrome/browser/sync/chrome_sync_client.h b/chrome/browser/sync/chrome_sync_client.h index 38b540a8..83e10fa 100644 --- a/chrome/browser/sync/chrome_sync_client.h +++ b/chrome/browser/sync/chrome_sync_client.h
@@ -53,7 +53,8 @@ BookmarkUndoService* GetBookmarkUndoServiceIfExists() override; scoped_refptr<syncer::ExtensionsActivity> GetExtensionsActivity() override; sync_sessions::SyncSessionsClient* GetSyncSessionsClient() override; - ServiceProvider GetSyncableServiceForType(syncer::ModelType type) override; + base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( + syncer::ModelType type) override; base::WeakPtr<syncer::ModelTypeSyncBridge> GetSyncBridgeForModelType( syncer::ModelType type) override; scoped_refptr<syncer::ModelSafeWorker> CreateModelWorkerForGroup(
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h index 184242a..5a3ff16 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h
@@ -44,6 +44,13 @@ @property(nonatomic, readwrite, assign) int startingChildIndex; @property(nonatomic, readwrite, assign) BOOL drawFolderArrow; +// Returns the width of a cell for the given node and image for +// display on the bookmark bar (meaning no arrow for folder +// nodes). Used for laying out bookmark bar without creating +// live cells. ++ (CGFloat)cellWidthForNode:(const bookmarks::BookmarkNode*)node + image:(NSImage*)image; + // Create a button cell which draws with a theme. + (id)buttonCellForNode:(const bookmarks::BookmarkNode*)node text:(NSString*)text @@ -87,6 +94,8 @@ - (void)setTextColor:(NSColor*)color; - (BOOL)isFolderButtonCell; +- (void)setBookmarkNode:(const bookmarks::BookmarkNode*)node + image:(NSImage*)image; @end
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm index 7bf527a..9335cf7 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm
@@ -35,6 +35,9 @@ const int kDefaultFontSize = 12; +// Kerning value for the title text. +const CGFloat kKernAmount = 0.2; + }; // namespace // TODO(lgrey): Bake setting the chevron image into this @@ -65,7 +68,7 @@ @end -@interface BookmarkButtonCell(Private) +@interface BookmarkButtonCell (Private) // Returns YES if the cell is the offTheSide button cell. - (BOOL)isOffTheSideButtonCell; - (void)configureBookmarkButtonCell; @@ -112,6 +115,24 @@ return [[[OffTheSideButtonCell alloc] init] autorelease]; } ++ (CGFloat)cellWidthForNode:(const bookmarks::BookmarkNode*)node + image:(NSImage*)image { + NSString* title = + [self cleanTitle:base::SysUTF16ToNSString(node->GetTitle())]; + CGFloat width = kIconLeftPadding + [image size].width; + if ([title length] > 0) { + CGSize titleSize = [title sizeWithAttributes:@{ + NSParagraphStyleAttributeName : [self paragraphStyleForBookmarkBarCell], + NSKernAttributeName : @(kKernAmount), + NSFontAttributeName : [self fontForBookmarkBarCell], + }]; + width += kIconTextSpacer + std::ceil(titleSize.width) + kTextRightPadding; + } else { + width += kIconLeftPadding; + } + return width; +} + - (id)initForNode:(const BookmarkNode*)node text:(NSString*)text image:(NSImage*)image @@ -120,7 +141,7 @@ menuController_ = menuController; [self configureBookmarkButtonCell]; [self setTextColor:[NSColor blackColor]]; - [self setBookmarkNode:node]; + [self setBookmarkNode:node image:image]; // When opening a bookmark folder, the default behavior is that the // favicon is greyed when menu item is hovered with the mouse cursor. // When using NSNoCellMask, the favicon won't be greyed when menu item @@ -130,15 +151,6 @@ // It makes the behavior of the bookmark folder consistent with hovering // on the bookmark bar. [self setHighlightsBy:NSNoCellMask]; - - if (node) { - NSString* title = base::SysUTF16ToNSString(node->GetTitle()); - [self setBookmarkCellText:title image:image]; - } else { - [self setEmpty:YES]; - [self setBookmarkCellText:l10n_util::GetNSString(IDS_MENU_EMPTY_SUBMENU) - image:nil]; - } } return self; @@ -185,7 +197,7 @@ [self setShowsBorderOnlyWhileMouseInside:YES]; [self setControlSize:NSSmallControlSize]; [self setAlignment:NSLeftTextAlignment]; - [self setFont:[NSFont systemFontOfSize:kDefaultFontSize]]; + [self setFont:[[self class] fontForBookmarkBarCell]]; [self setBordered:NO]; [self setBezeled:NO]; [self setWraps:NO]; @@ -220,12 +232,8 @@ - (void)setBookmarkCellText:(NSString*)title image:(NSImage*)image { - title = [title stringByReplacingOccurrencesOfString:@"\n" - withString:@" "]; - title = [title stringByReplacingOccurrencesOfString:@"\r" - withString:@" "]; - - if ([title length]) { + title = [[self class] cleanTitle:title]; + if ([title length] && ![self isOffTheSideButtonCell]) { [self setImagePosition:NSImageLeft]; [self setTitle:title]; } else if ([self isFolderButtonCell]) { @@ -245,7 +253,19 @@ } - (void)setBookmarkNode:(const BookmarkNode*)node { + [self setBookmarkNode:node image:nil]; +} + +- (void)setBookmarkNode:(const BookmarkNode*)node image:(NSImage*)image { [self setRepresentedObject:[NSValue valueWithPointer:node]]; + if (node) { + NSString* title = base::SysUTF16ToNSString(node->GetTitle()); + [self setBookmarkCellText:title image:image]; + } else { + [self setEmpty:YES]; + [self setBookmarkCellText:l10n_util::GetNSString(IDS_MENU_EMPTY_SUBMENU) + image:nil]; + } } - (const BookmarkNode*)bookmarkNode { @@ -315,10 +335,7 @@ } - (NSDictionary*)titleTextAttributes { - base::scoped_nsobject<NSMutableParagraphStyle> style( - [NSMutableParagraphStyle new]); - [style setAlignment:NSNaturalTextAlignment]; - [style setLineBreakMode:NSLineBreakByTruncatingTail]; + NSParagraphStyle* style = [[self class] paragraphStyleForBookmarkBarCell]; NSColor* textColor = textColor_.get(); if (!textColor) { textColor = [NSColor blackColor]; @@ -328,14 +345,14 @@ } NSFont* theFont = [self font]; if (!theFont) { - theFont = [NSFont systemFontOfSize:kDefaultFontSize]; + theFont = [[self class] fontForBookmarkBarCell]; } return @{ - NSFontAttributeName : theFont, - NSForegroundColorAttributeName : textColor, - NSParagraphStyleAttributeName : style.get(), - NSKernAttributeName : [NSNumber numberWithFloat:0.2] + NSFontAttributeName : theFont, + NSForegroundColorAttributeName : textColor, + NSParagraphStyleAttributeName : style, + NSKernAttributeName : @(kKernAmount), }; } @@ -441,5 +458,23 @@ return 0.0; } ++ (NSFont*)fontForBookmarkBarCell { + return [NSFont systemFontOfSize:kDefaultFontSize]; +} + ++ (NSParagraphStyle*)paragraphStyleForBookmarkBarCell { + NSMutableParagraphStyle* style = [[NSMutableParagraphStyle alloc] init]; + [style setAlignment:NSNaturalTextAlignment]; + [style setLineBreakMode:NSLineBreakByTruncatingTail]; + return [style autorelease]; +} + +// Returns |title| with newlines and line feeds replaced with +// spaces. ++ (NSString*)cleanTitle:(NSString*)title { + title = [title stringByReplacingOccurrencesOfString:@"\n" withString:@" "]; + title = [title stringByReplacingOccurrencesOfString:@"\r" withString:@" "]; + return title; +} @end
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell_unittest.mm index e820fc14..32b0de8 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell_unittest.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell_unittest.mm
@@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#import "chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h" #include "base/mac/scoped_nsobject.h" +#include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" -#import "chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.h" #include "chrome/browser/ui/cocoa/test/cocoa_profile_test.h" #import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h" #include "chrome/test/base/testing_profile.h" @@ -121,6 +122,7 @@ node = model->other_node(); [cell setBookmarkNode:node]; EXPECT_EQ(node, [cell bookmarkNode]); + EXPECT_EQ(node->GetTitle(), base::SysNSStringToUTF16([cell title])); } TEST_F(BookmarkButtonCellTest, BookmarkMouseForwarding) { @@ -213,4 +215,34 @@ EXPECT_TRUE([[BookmarkButtonCell offTheSideButtonCell] isKindOfClass:offTheSideButtonCellClass]); } + +// Ensure the |cellWidthForNode:image:| class method reports the same +// width as an instantiated cell with the same node and image. +TEST_F(BookmarkButtonCellTest, CellWidthForNode) { + BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile()); + + const BookmarkNode* bar = model->bookmark_bar_node(); + const BookmarkNode* node_a = + model->AddURL(bar, bar->child_count(), base::ASCIIToUTF16("A cell"), + GURL("http://www.google.com")); + const BookmarkNode* node_b = + model->AddURL(bar, bar->child_count(), + base::ASCIIToUTF16("This cell has a longer title "), + GURL("http://www.google.com/a")); + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + base::scoped_nsobject<NSImage> image( + rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).CopyNSImage()); + CGFloat width_for_node_a = + [BookmarkButtonCell cellWidthForNode:node_a image:image]; + CGFloat width_for_node_b = + [BookmarkButtonCell cellWidthForNode:node_b image:image]; + base::scoped_nsobject<BookmarkButtonCell> bookmark_cell( + [[BookmarkButtonCell alloc] initForNode:node_a + text:nil + image:image + menuController:nil]); + EXPECT_CGFLOAT_EQ([bookmark_cell cellSize].width, width_for_node_a); + [bookmark_cell setBookmarkNode:node_b image:image]; + EXPECT_CGFLOAT_EQ([bookmark_cell cellSize].width, width_for_node_b); +} } // namespace
diff --git a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm index d1dbc29..41cd17d 100644 --- a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm +++ b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm
@@ -383,8 +383,8 @@ const ContentSettingBubbleModel::RadioItems& radio_items = radio_group.radio_items; for (size_t ii = 0; ii < radio_group.radio_items.size(); ++ii) { - NSCell* radioCell = [allowBlockRadioGroup_ cellWithTag: ii + 1]; - [radioCell setTitle:base::SysUTF8ToNSString(radio_items[ii])]; + NSCell* radioCell = [allowBlockRadioGroup_ cellWithTag:ii + 1]; + [radioCell setTitle:base::SysUTF16ToNSString(radio_items[ii])]; } // Layout radio group labels post-localization. @@ -473,17 +473,17 @@ NSRect frame = NSMakeRect( NSMinX(radioFrame), topLinkY - kLinkLineHeight * row, 200, kLinkHeight); if (listItem.has_link) { - NSButton* button = - [self hyperlinkButtonWithFrame:frame - title:base::SysUTF8ToNSString(listItem.title) - icon:image - referenceFrame:radioFrame]; + NSButton* button = [self + hyperlinkButtonWithFrame:frame + title:base::SysUTF16ToNSString(listItem.title) + icon:image + referenceFrame:radioFrame]; [button setAutoresizingMask:NSViewMinYMargin]; [[self bubble] addSubview:button]; popupLinks_[button] = row++; } else { NSTextField* label = - LabelWithFrame(base::SysUTF8ToNSString(listItem.title), frame); + LabelWithFrame(base::SysUTF16ToNSString(listItem.title), frame); SetControlSize(label, NSSmallControlSize); [label setAutoresizingMask:NSViewMinYMargin]; [[self bubble] addSubview:label]; @@ -510,7 +510,7 @@ kGeoClearButtonHeight); NSButton* button = [[NSButton alloc] initWithFrame:buttonFrame]; control.reset(button); - [button setTitle:base::SysUTF8ToNSString(content.custom_link)]; + [button setTitle:base::SysUTF16ToNSString(content.custom_link)]; [button setTarget:self]; [button setAction:@selector(clearGeolocationForCurrentHost:)]; [button setBezelStyle:NSRoundRectBezelStyle]; @@ -519,7 +519,7 @@ } else { // Add the notification that settings will be cleared on next reload. control.reset([LabelWithFrame( - base::SysUTF8ToNSString(content.custom_link), frame) retain]); + base::SysUTF16ToNSString(content.custom_link), frame) retain]); SetControlSize(control.get(), NSSmallControlSize); } @@ -555,7 +555,7 @@ // Add the domain list's title. NSTextField* title = - LabelWithFrame(base::SysUTF8ToNSString(i->title), frame); + LabelWithFrame(base::SysUTF16ToNSString(i->title), frame); SetControlSize(title, NSSmallControlSize); [contentsContainer_ addSubview:title]; @@ -592,7 +592,7 @@ // |labelFrame| will be resized later on in this function. NSRect labelFrame = NSMakeRect(NSMinX(radioFrame), 0, 0, 0); NSTextField* label = LabelWithFrame( - base::SysUTF8ToNSString(map_entry.second.label), labelFrame); + base::SysUTF16ToNSString(map_entry.second.label), labelFrame); SetControlSize(label, NSSmallControlSize); NSCell* cell = [label cell]; [cell setAlignment:NSRightTextAlignment]; @@ -685,7 +685,7 @@ kMIDISysExClearButtonHeight); NSButton* button = [[NSButton alloc] initWithFrame:buttonFrame]; control.reset(button); - [button setTitle:base::SysUTF8ToNSString(content.custom_link)]; + [button setTitle:base::SysUTF16ToNSString(content.custom_link)]; [button setTarget:self]; [button setAction:@selector(clearMIDISysExForCurrentHost:)]; [button setBezelStyle:NSRoundRectBezelStyle]; @@ -694,7 +694,7 @@ } else { // Add the notification that settings will be cleared on next reload. control.reset([LabelWithFrame( - base::SysUTF8ToNSString(content.custom_link), frame) retain]); + base::SysUTF16ToNSString(content.custom_link), frame) retain]); SetControlSize(control.get(), NSSmallControlSize); } @@ -730,7 +730,7 @@ // Add the domain list's title. NSTextField* title = - LabelWithFrame(base::SysUTF8ToNSString(i->title), frame); + LabelWithFrame(base::SysUTF16ToNSString(i->title), frame); SetControlSize(title, NSSmallControlSize); [contentsContainer_ addSubview:title]; @@ -769,7 +769,7 @@ - (void)initManageDoneButtons { const ContentSettingBubbleModel::BubbleContent& content = contentSettingBubbleModel_->bubble_content(); - [manageButton_ setTitle:base::SysUTF8ToNSString(content.manage_text)]; + [manageButton_ setTitle:base::SysUTF16ToNSString(content.manage_text)]; [GTMUILocalizerAndLayoutTweaker sizeToFitView:[manageButton_ superview]]; CGFloat actualWidth = NSWidth([[[self window] contentView] frame]);
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index 9983e5c2..5b61709 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -180,7 +180,7 @@ {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_PPAPI_BROKER_BUBBLE_MANAGE_LINK}, {CONTENT_SETTINGS_TYPE_MIDI_SYSEX, IDS_MIDI_SYSEX_BUBBLE_MANAGE_LINK}, }; - set_manage_text(l10n_util::GetStringUTF8( + set_manage_text(l10n_util::GetStringUTF16( GetIdForContentType(kLinkIDs, arraysize(kLinkIDs), content_type()))); } @@ -207,7 +207,7 @@ int custom_link_id = GetIdForContentType(kCustomIDs, arraysize(kCustomIDs), content_type()); if (custom_link_id) - set_custom_link(l10n_util::GetStringUTF8(custom_link_id)); + set_custom_link(l10n_util::GetStringUTF16(custom_link_id)); } void ContentSettingSimpleBubbleModel::OnCustomLinkClicked() { @@ -297,14 +297,14 @@ {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_NO_ACTION}, }; - std::string radio_allow_label; + base::string16 radio_allow_label; if (allowed) { int resource_id = GetIdForContentType(kAllowedAllowIDs, arraysize(kAllowedAllowIDs), content_type()); - radio_allow_label = l10n_util::GetStringUTF8(resource_id); + radio_allow_label = l10n_util::GetStringUTF16(resource_id); } else { - radio_allow_label = l10n_util::GetStringFUTF8( + radio_allow_label = l10n_util::GetStringFUTF16( GetIdForContentType(kBlockedAllowIDs, arraysize(kBlockedAllowIDs), content_type()), display_host); @@ -323,16 +323,14 @@ {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_BLOCK}, }; - std::string radio_block_label; + base::string16 radio_block_label; if (allowed) { - int resource_id = GetIdForContentType(kAllowedBlockIDs, - arraysize(kAllowedBlockIDs), - content_type()); - radio_block_label = l10n_util::GetStringFUTF8(resource_id, display_host); + int resource_id = GetIdForContentType( + kAllowedBlockIDs, arraysize(kAllowedBlockIDs), content_type()); + radio_block_label = l10n_util::GetStringFUTF16(resource_id, display_host); } else { - radio_block_label = l10n_util::GetStringUTF8( - GetIdForContentType(kBlockedBlockIDs, arraysize(kBlockedBlockIDs), - content_type())); + radio_block_label = l10n_util::GetStringUTF16(GetIdForContentType( + kBlockedBlockIDs, arraysize(kBlockedBlockIDs), content_type())); } radio_group.radio_items.push_back(radio_allow_label); @@ -468,7 +466,7 @@ // If the setting is not managed by the user, hide the "Manage..." link. if (info.source != SETTING_SOURCE_USER) - set_manage_text(std::string()); + set_manage_text(base::string16()); // The user cannot manually run Flash on the BLOCK setting when either holds: // - The setting is from Policy. User cannot override admin intent. @@ -479,7 +477,7 @@ PluginUtils::ShouldPreferHtmlOverPlugins(map)); if (!run_blocked) { - set_custom_link(l10n_util::GetStringUTF8(IDS_BLOCKED_PLUGINS_LOAD_ALL)); + set_custom_link(l10n_util::GetStringUTF16(IDS_BLOCKED_PLUGINS_LOAD_ALL)); // Disable the "Run all plugins this time" link if the user already clicked // on the link and ran all plugins. set_custom_link_enabled( @@ -499,12 +497,12 @@ ListItem plugin_item( ui::ResourceBundle::GetSharedInstance().GetImageNamed( IDR_BLOCKED_PLUGINS), - base::UTF16ToUTF8(blocked_plugin), false, 0); + blocked_plugin, false, 0); add_list_item(plugin_item); } } - set_learn_more_link(l10n_util::GetStringUTF8(IDS_LEARN_MORE)); + set_learn_more_link(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); content_settings::RecordPluginsAction( content_settings::PLUGINS_ACTION_DISPLAYED_BUBBLE); @@ -575,10 +573,13 @@ auto* helper = PopupBlockerTabHelper::FromWebContents(web_contents); std::map<int32_t, GURL> blocked_popups = helper->GetBlockedPopupRequests(); for (const std::pair<int32_t, GURL>& blocked_popup : blocked_popups) { - std::string title(blocked_popup.second.spec()); + base::string16 title; // The pop-up may not have a valid URL. - if (title.empty()) - title = l10n_util::GetStringUTF8(IDS_TAB_LOADING_TITLE); + if (blocked_popup.second.spec().empty()) + title = l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE); + else + title = base::UTF8ToUTF16(blocked_popup.second.spec()); + ListItem popup_item(ui::ResourceBundle::GetSharedInstance().GetImageNamed( IDR_DEFAULT_FAVICON), title, true, blocked_popup.first); @@ -706,11 +707,9 @@ RadioGroup radio_group; radio_group.url = url; - base::string16 display_host_utf16 = - url_formatter::FormatUrlForSecurityDisplay(url); - std::string display_host(base::UTF16ToUTF8(display_host_utf16)); + base::string16 display_host = url_formatter::FormatUrlForSecurityDisplay(url); if (display_host.empty()) - display_host = url.spec(); + display_host = base::UTF8ToUTF16(url.spec()); DCHECK(CameraAccessed() || MicrophoneAccessed()); int radio_allow_label_id = 0; @@ -754,10 +753,10 @@ (CameraAccessed() && content_settings->IsContentBlocked( CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) ? 1 : 0; - std::string radio_allow_label = l10n_util::GetStringFUTF8( - radio_allow_label_id, base::UTF8ToUTF16(display_host)); - std::string radio_block_label = - l10n_util::GetStringUTF8(radio_block_label_id); + base::string16 radio_allow_label = + l10n_util::GetStringFUTF16(radio_allow_label_id, display_host); + base::string16 radio_block_label = + l10n_util::GetStringUTF16(radio_block_label_id); radio_group.default_item = selected_item_; radio_group.radio_items.push_back(radio_allow_label); @@ -828,7 +827,7 @@ if (MicrophoneAccessed()) { MediaMenu mic_menu; - mic_menu.label = l10n_util::GetStringUTF8(IDS_MEDIA_SELECTED_MIC_LABEL); + mic_menu.label = l10n_util::GetStringUTF16(IDS_MEDIA_SELECTED_MIC_LABEL); if (!microphones.empty()) { std::string preferred_mic; if (requested_microphone.empty()) { @@ -853,7 +852,7 @@ dispatcher->GetVideoCaptureDevices(); MediaMenu camera_menu; camera_menu.label = - l10n_util::GetStringUTF8(IDS_MEDIA_SELECTED_CAMERA_LABEL); + l10n_util::GetStringUTF16(IDS_MEDIA_SELECTED_CAMERA_LABEL); if (!cameras.empty()) { std::string preferred_camera; if (requested_camera.empty()) { @@ -889,15 +888,15 @@ return; } - set_manage_text(l10n_util::GetStringUTF8(link_id)); + set_manage_text(l10n_util::GetStringUTF16(link_id)); } void ContentSettingMediaStreamBubbleModel::SetCustomLink() { TabSpecificContentSettings* content_settings = TabSpecificContentSettings::FromWebContents(web_contents()); if (content_settings->IsMicrophoneCameraStateChanged()) { - set_custom_link(l10n_util::GetStringUTF8( - IDS_MEDIASTREAM_SETTING_CHANGED_MESSAGE)); + set_custom_link( + l10n_util::GetStringUTF16(IDS_MEDIASTREAM_SETTING_CHANGED_MESSAGE)); } } @@ -955,7 +954,7 @@ const std::set<std::string>& hosts, int title_id) { if (!hosts.empty()) { DomainList domain_list; - domain_list.title = l10n_util::GetStringUTF8(title_id); + domain_list.title = l10n_util::GetStringUTF16(title_id); domain_list.hosts = hosts; add_domain_list(domain_list); } @@ -978,12 +977,12 @@ IDS_GEOLOCATION_BUBBLE_SECTION_DENIED); if (tab_state_flags & ContentSettingsUsagesState::TABSTATE_HAS_EXCEPTION) { - set_custom_link(l10n_util::GetStringUTF8( - IDS_GEOLOCATION_BUBBLE_CLEAR_LINK)); + set_custom_link( + l10n_util::GetStringUTF16(IDS_GEOLOCATION_BUBBLE_CLEAR_LINK)); set_custom_link_enabled(true); } else if (tab_state_flags & ContentSettingsUsagesState::TABSTATE_HAS_CHANGED) { - set_custom_link(l10n_util::GetStringUTF8( + set_custom_link(l10n_util::GetStringUTF16( IDS_GEOLOCATION_BUBBLE_REQUIRE_RELOAD_TO_CLEAR)); } } @@ -1120,14 +1119,14 @@ base::UTF8ToUTF16(previous_handler_.url().host()))); } - std::string radio_allow_label = - l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_ACCEPT); - std::string radio_deny_label = - l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_DENY); - std::string radio_ignore_label = - l10n_util::GetStringUTF8(IDS_REGISTER_PROTOCOL_HANDLER_IGNORE); + base::string16 radio_allow_label = + l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_ACCEPT); + base::string16 radio_deny_label = + l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_DENY); + base::string16 radio_ignore_label = + l10n_util::GetStringUTF16(IDS_REGISTER_PROTOCOL_HANDLER_IGNORE); - GURL url = web_contents->GetURL(); + const GURL& url = web_contents->GetURL(); RadioGroup radio_group; radio_group.url = url; @@ -1246,7 +1245,7 @@ void ContentSettingSubresourceFilterBubbleModel::SetManageText() { set_manage_text( - l10n_util::GetStringUTF8(IDS_FILTERED_DECEPTIVE_CONTENT_PROMPT_RELOAD)); + l10n_util::GetStringUTF16(IDS_FILTERED_DECEPTIVE_CONTENT_PROMPT_RELOAD)); set_show_manage_text_as_checkbox(true); } @@ -1311,7 +1310,7 @@ const std::set<std::string>& hosts, int title_id) { if (!hosts.empty()) { DomainList domain_list; - domain_list.title = l10n_util::GetStringUTF8(title_id); + domain_list.title = l10n_util::GetStringUTF16(title_id); domain_list.hosts = hosts; add_domain_list(domain_list); } @@ -1334,12 +1333,12 @@ IDS_MIDI_SYSEX_BUBBLE_DENIED); if (tab_state_flags & ContentSettingsUsagesState::TABSTATE_HAS_EXCEPTION) { - set_custom_link(l10n_util::GetStringUTF8( - IDS_MIDI_SYSEX_BUBBLE_CLEAR_LINK)); + set_custom_link( + l10n_util::GetStringUTF16(IDS_MIDI_SYSEX_BUBBLE_CLEAR_LINK)); set_custom_link_enabled(true); } else if (tab_state_flags & ContentSettingsUsagesState::TABSTATE_HAS_CHANGED) { - set_custom_link(l10n_util::GetStringUTF8( + set_custom_link(l10n_util::GetStringUTF16( IDS_MIDI_SYSEX_BUBBLE_REQUIRE_RELOAD_TO_CLEAR)); } } @@ -1413,16 +1412,16 @@ switch (download_request_limiter->GetDownloadStatus(web_contents())) { case DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS: radio_group.radio_items.push_back( - l10n_util::GetStringUTF8(IDS_ALLOWED_DOWNLOAD_NO_ACTION)); + l10n_util::GetStringUTF16(IDS_ALLOWED_DOWNLOAD_NO_ACTION)); radio_group.radio_items.push_back( - l10n_util::GetStringFUTF8(IDS_ALLOWED_DOWNLOAD_BLOCK, display_host)); + l10n_util::GetStringFUTF16(IDS_ALLOWED_DOWNLOAD_BLOCK, display_host)); radio_group.default_item = kAllowButtonIndex; break; case DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED: - radio_group.radio_items.push_back(l10n_util::GetStringFUTF8( + radio_group.radio_items.push_back(l10n_util::GetStringFUTF16( IDS_BLOCKED_DOWNLOAD_UNBLOCK, display_host)); radio_group.radio_items.push_back( - l10n_util::GetStringUTF8(IDS_BLOCKED_DOWNLOAD_NO_ACTION)); + l10n_util::GetStringUTF16(IDS_BLOCKED_DOWNLOAD_NO_ACTION)); radio_group.default_item = 1; break; default: @@ -1471,7 +1470,7 @@ } void ContentSettingDownloadsBubbleModel::SetManageText() { - set_manage_text(l10n_util::GetStringUTF8(IDS_BLOCKED_DOWNLOADS_LINK)); + set_manage_text(l10n_util::GetStringUTF16(IDS_BLOCKED_DOWNLOADS_LINK)); } void ContentSettingDownloadsBubbleModel::OnManageLinkClicked() {
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.h b/chrome/browser/ui/content_settings/content_setting_bubble_model.h index f290390c..727b721 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.h +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.h
@@ -14,6 +14,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/strings/string16.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" #include "chrome/common/custom_handlers/protocol_handler.h" #include "components/content_settings/core/common/content_settings.h" @@ -66,25 +67,25 @@ struct ListItem { ListItem(const gfx::Image& image, - const std::string& title, + const base::string16& title, bool has_link, int32_t item_id) : image(image), title(title), has_link(has_link), item_id(item_id) {} gfx::Image image; - std::string title; + base::string16 title; bool has_link; int32_t item_id; }; typedef std::vector<ListItem> ListItems; - typedef std::vector<std::string> RadioItems; + typedef std::vector<base::string16> RadioItems; struct RadioGroup { RadioGroup(); ~RadioGroup(); GURL url; - std::string title; + base::string16 title; RadioItems radio_items; int default_item; }; @@ -94,7 +95,7 @@ DomainList(const DomainList& other); ~DomainList(); - std::string title; + base::string16 title; std::set<std::string> hosts; }; @@ -103,7 +104,7 @@ MediaMenu(const MediaMenu& other); ~MediaMenu(); - std::string label; + base::string16 label; content::MediaStreamDevice default_device; content::MediaStreamDevice selected_device; bool disabled; @@ -120,12 +121,12 @@ RadioGroup radio_group; bool radio_group_enabled = false; std::vector<DomainList> domain_lists; - std::string custom_link; + base::string16 custom_link; bool custom_link_enabled = false; - std::string manage_text; + base::string16 manage_text; bool show_manage_text_as_checkbox = false; MediaMenuMap media_menus; - std::string learn_more_link; + base::string16 learn_more_link; base::string16 done_button_text; private: @@ -216,13 +217,13 @@ void add_domain_list(const DomainList& domain_list) { bubble_content_.domain_lists.push_back(domain_list); } - void set_custom_link(const std::string& link) { + void set_custom_link(const base::string16& link) { bubble_content_.custom_link = link; } void set_custom_link_enabled(bool enabled) { bubble_content_.custom_link_enabled = enabled; } - void set_manage_text(const std::string& text) { + void set_manage_text(const base::string16& text) { bubble_content_.manage_text = text; } void set_show_manage_text_as_checkbox(bool show_manage_text_as_checkbox) { @@ -234,7 +235,7 @@ void set_selected_device(const content::MediaStreamDevice& device) { bubble_content_.media_menus[device.type].selected_device = device; } - void set_learn_more_link(const std::string& link) { + void set_learn_more_link(const base::string16& link) { bubble_content_.learn_more_link = link; } void set_done_button_text(const base::string16& done_button_text) {
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc index 3c1d9667..0a7c7b8 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
@@ -131,12 +131,12 @@ EXPECT_NE(title, bubble_content_2.title); ASSERT_EQ(2U, bubble_content_2.radio_group.radio_items.size()); EXPECT_EQ(bubble_content_2.radio_group.radio_items[0], - l10n_util::GetStringUTF8(IDS_ALLOWED_COOKIES_NO_ACTION)); - EXPECT_EQ(bubble_content_2.radio_group.radio_items[1], - l10n_util::GetStringFUTF8( - IDS_ALLOWED_COOKIES_BLOCK, - url_formatter::FormatUrlForSecurityDisplay( - web_contents()->GetURL()))); + l10n_util::GetStringUTF16(IDS_ALLOWED_COOKIES_NO_ACTION)); + EXPECT_EQ( + bubble_content_2.radio_group.radio_items[1], + l10n_util::GetStringFUTF16(IDS_ALLOWED_COOKIES_BLOCK, + url_formatter::FormatUrlForSecurityDisplay( + web_contents()->GetURL()))); EXPECT_FALSE(bubble_content_2.custom_link.empty()); EXPECT_TRUE(bubble_content_2.custom_link_enabled); EXPECT_FALSE(bubble_content_2.manage_text.empty()); @@ -170,12 +170,12 @@ l10n_util::GetStringUTF16(IDS_MICROPHONE_CAMERA_ALLOWED)); EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); EXPECT_EQ(bubble_content.radio_group.radio_items[0], - l10n_util::GetStringFUTF8( + l10n_util::GetStringFUTF16( IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION, url_formatter::FormatUrlForSecurityDisplay(security_origin))); - EXPECT_EQ(bubble_content.radio_group.radio_items[1], - l10n_util::GetStringUTF8( - IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK)); + EXPECT_EQ( + bubble_content.radio_group.radio_items[1], + l10n_util::GetStringUTF16(IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK)); EXPECT_EQ(0, bubble_content.radio_group.default_item); EXPECT_TRUE(bubble_content.custom_link.empty()); EXPECT_FALSE(bubble_content.custom_link_enabled); @@ -319,8 +319,9 @@ content_setting_bubble_model->bubble_content(); // Test that the reload hint is displayed. EXPECT_FALSE(bubble_content.custom_link_enabled); - EXPECT_EQ(bubble_content.custom_link, l10n_util::GetStringUTF8( - IDS_MEDIASTREAM_SETTING_CHANGED_MESSAGE)); + EXPECT_EQ( + bubble_content.custom_link, + l10n_util::GetStringUTF16(IDS_MEDIASTREAM_SETTING_CHANGED_MESSAGE)); EXPECT_EQ(0, bubble_content.radio_group.default_item); // Restore the radio setting (to block). @@ -468,8 +469,9 @@ content_setting_bubble_model->bubble_content(); // Test that the reload hint is displayed. EXPECT_FALSE(bubble_content.custom_link_enabled); - EXPECT_EQ(bubble_content.custom_link, l10n_util::GetStringUTF8( - IDS_MEDIASTREAM_SETTING_CHANGED_MESSAGE)); + EXPECT_EQ( + bubble_content.custom_link, + l10n_util::GetStringUTF16(IDS_MEDIASTREAM_SETTING_CHANGED_MESSAGE)); } // Simulate that yet another audio stream capture request was initiated. @@ -529,12 +531,11 @@ l10n_util::GetStringUTF16(IDS_MICROPHONE_ACCESSED)); EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); EXPECT_EQ(bubble_content.radio_group.radio_items[0], - l10n_util::GetStringFUTF8( + l10n_util::GetStringFUTF16( IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION, url_formatter::FormatUrlForSecurityDisplay(security_origin))); EXPECT_EQ(bubble_content.radio_group.radio_items[1], - l10n_util::GetStringUTF8( - IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK)); + l10n_util::GetStringUTF16(IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK)); EXPECT_EQ(0, bubble_content.radio_group.default_item); EXPECT_TRUE(bubble_content.custom_link.empty()); EXPECT_FALSE(bubble_content.custom_link_enabled); @@ -560,12 +561,11 @@ l10n_util::GetStringUTF16(IDS_MICROPHONE_BLOCKED)); EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size()); EXPECT_EQ(new_bubble_content.radio_group.radio_items[0], - l10n_util::GetStringFUTF8( + l10n_util::GetStringFUTF16( IDS_BLOCKED_MEDIASTREAM_MIC_ASK, url_formatter::FormatUrlForSecurityDisplay(security_origin))); EXPECT_EQ(new_bubble_content.radio_group.radio_items[1], - l10n_util::GetStringUTF8( - IDS_BLOCKED_MEDIASTREAM_MIC_NO_ACTION)); + l10n_util::GetStringUTF16(IDS_BLOCKED_MEDIASTREAM_MIC_NO_ACTION)); EXPECT_EQ(1, new_bubble_content.radio_group.default_item); EXPECT_TRUE(new_bubble_content.custom_link.empty()); EXPECT_FALSE(new_bubble_content.custom_link_enabled); @@ -602,12 +602,11 @@ l10n_util::GetStringUTF16(IDS_CAMERA_ACCESSED)); EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); EXPECT_EQ(bubble_content.radio_group.radio_items[0], - l10n_util::GetStringFUTF8( + l10n_util::GetStringFUTF16( IDS_ALLOWED_MEDIASTREAM_CAMERA_NO_ACTION, url_formatter::FormatUrlForSecurityDisplay(security_origin))); EXPECT_EQ(bubble_content.radio_group.radio_items[1], - l10n_util::GetStringUTF8( - IDS_ALLOWED_MEDIASTREAM_CAMERA_BLOCK)); + l10n_util::GetStringUTF16(IDS_ALLOWED_MEDIASTREAM_CAMERA_BLOCK)); EXPECT_EQ(0, bubble_content.radio_group.default_item); EXPECT_TRUE(bubble_content.custom_link.empty()); EXPECT_FALSE(bubble_content.custom_link_enabled); @@ -633,12 +632,12 @@ l10n_util::GetStringUTF16(IDS_CAMERA_BLOCKED)); EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size()); EXPECT_EQ(new_bubble_content.radio_group.radio_items[0], - l10n_util::GetStringFUTF8( + l10n_util::GetStringFUTF16( IDS_BLOCKED_MEDIASTREAM_CAMERA_ASK, url_formatter::FormatUrlForSecurityDisplay(security_origin))); - EXPECT_EQ(new_bubble_content.radio_group.radio_items[1], - l10n_util::GetStringUTF8( - IDS_BLOCKED_MEDIASTREAM_CAMERA_NO_ACTION)); + EXPECT_EQ( + new_bubble_content.radio_group.radio_items[1], + l10n_util::GetStringUTF16(IDS_BLOCKED_MEDIASTREAM_CAMERA_NO_ACTION)); EXPECT_EQ(1, new_bubble_content.radio_group.default_item); EXPECT_TRUE(new_bubble_content.custom_link.empty()); EXPECT_FALSE(new_bubble_content.custom_link_enabled); @@ -677,12 +676,11 @@ l10n_util::GetStringUTF16(IDS_MICROPHONE_ACCESSED)); EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); EXPECT_EQ(bubble_content.radio_group.radio_items[0], - l10n_util::GetStringFUTF8( + l10n_util::GetStringFUTF16( IDS_ALLOWED_MEDIASTREAM_MIC_NO_ACTION, url_formatter::FormatUrlForSecurityDisplay(security_origin))); EXPECT_EQ(bubble_content.radio_group.radio_items[1], - l10n_util::GetStringUTF8( - IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK)); + l10n_util::GetStringUTF16(IDS_ALLOWED_MEDIASTREAM_MIC_BLOCK)); EXPECT_EQ(0, bubble_content.radio_group.default_item); EXPECT_EQ(1U, bubble_content.media_menus.size()); EXPECT_EQ(content::MEDIA_DEVICE_AUDIO_CAPTURE, @@ -706,12 +704,12 @@ l10n_util::GetStringUTF16(IDS_MICROPHONE_CAMERA_ALLOWED)); EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size()); EXPECT_EQ(new_bubble_content.radio_group.radio_items[0], - l10n_util::GetStringFUTF8( + l10n_util::GetStringFUTF16( IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_NO_ACTION, url_formatter::FormatUrlForSecurityDisplay(security_origin))); - EXPECT_EQ(new_bubble_content.radio_group.radio_items[1], - l10n_util::GetStringUTF8( - IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK)); + EXPECT_EQ( + new_bubble_content.radio_group.radio_items[1], + l10n_util::GetStringUTF16(IDS_ALLOWED_MEDIASTREAM_MIC_AND_CAMERA_BLOCK)); EXPECT_EQ(0, new_bubble_content.radio_group.default_item); EXPECT_EQ(2U, new_bubble_content.media_menus.size()); } @@ -733,8 +731,7 @@ content_setting_bubble_model->bubble_content(); EXPECT_FALSE(bubble_content.title.empty()); ASSERT_EQ(1U, bubble_content.list_items.size()); - EXPECT_EQ(plugin_name, - base::ASCIIToUTF16(bubble_content.list_items[0].title)); + EXPECT_EQ(plugin_name, bubble_content.list_items[0].title); EXPECT_EQ(0U, bubble_content.radio_group.radio_items.size()); EXPECT_FALSE(bubble_content.custom_link.empty()); EXPECT_TRUE(bubble_content.custom_link_enabled); @@ -758,8 +755,8 @@ base::string16 title = bubble_content.title; EXPECT_FALSE(title.empty()); ASSERT_EQ(2U, bubble_content.radio_group.radio_items.size()); - std::string radio1 = bubble_content.radio_group.radio_items[0]; - std::string radio2 = bubble_content.radio_group.radio_items[1]; + base::string16 radio1 = bubble_content.radio_group.radio_items[0]; + base::string16 radio2 = bubble_content.radio_group.radio_items[1]; EXPECT_FALSE(bubble_content.custom_link_enabled); EXPECT_FALSE(bubble_content.manage_text.empty()); @@ -826,9 +823,9 @@ std::unique_ptr<ContentSettingBubbleModel> content_setting_bubble_model( ContentSettingBubbleModel::CreateContentSettingBubbleModel( nullptr, web_contents(), profile(), CONTENT_SETTINGS_TYPE_IMAGES)); - std::string title = + base::string16 title = content_setting_bubble_model->bubble_content().radio_group.radio_items[0]; - ASSERT_NE(std::string::npos, title.find(file_url)); + ASSERT_NE(base::string16::npos, title.find(base::UTF8ToUTF16(file_url))); } TEST_F(ContentSettingBubbleModelTest, RegisterProtocolHandler) { @@ -958,7 +955,7 @@ EXPECT_FALSE(bubble_content.custom_link_enabled); EXPECT_EQ( bubble_content.manage_text, - l10n_util::GetStringUTF8(IDS_FILTERED_DECEPTIVE_CONTENT_PROMPT_RELOAD)); + l10n_util::GetStringUTF16(IDS_FILTERED_DECEPTIVE_CONTENT_PROMPT_RELOAD)); EXPECT_EQ(0U, bubble_content.media_menus.size()); }
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc index 2c0aeccb..c477ba1e 100644 --- a/chrome/browser/ui/views/content_setting_bubble_contents.cc +++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -255,8 +255,7 @@ } if (!bubble_content.learn_more_link.empty()) { - learn_more_link_ = - new views::Link(base::UTF8ToUTF16(bubble_content.learn_more_link)); + learn_more_link_ = new views::Link(bubble_content.learn_more_link); learn_more_link_->set_listener(this); learn_more_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT); layout->AddView(learn_more_link_); @@ -282,7 +281,7 @@ layout->AddPaddingRow(0, related_control_vertical_spacing); layout->StartRow(0, kItemListColumnSetId); if (list_item.has_link) { - views::Link* link = new views::Link(base::UTF8ToUTF16(list_item.title)); + views::Link* link = new views::Link(list_item.title); link->set_listener(this); link->SetElideBehavior(gfx::ELIDE_MIDDLE); list_item_links_[link] = row; @@ -292,7 +291,7 @@ views::ImageView* icon = new views::ImageView(); icon->SetImage(list_item.image.AsImageSkia()); layout->AddView(icon); - layout->AddView(new views::Label(base::UTF8ToUTF16(list_item.title))); + layout->AddView(new views::Label(list_item.title)); } row++; bubble_content_empty = false; @@ -318,8 +317,7 @@ for (ContentSettingBubbleModel::RadioItems::const_iterator i( radio_group.radio_items.begin()); i != radio_group.radio_items.end(); ++i) { - views::RadioButton* radio = - new views::RadioButton(base::UTF8ToUTF16(*i), 0); + views::RadioButton* radio = new views::RadioButton(*i, 0); radio->SetEnabled(bubble_content.radio_group_enabled); radio->set_listener(this); if (layout_delegate->IsHarmonyMode()) { @@ -363,8 +361,7 @@ layout->AddPaddingRow(0, related_control_vertical_spacing); layout->StartRow(0, kMediaMenuColumnSetId); - views::Label* label = - new views::Label(base::UTF8ToUTF16(i->second.label)); + views::Label* label = new views::Label(i->second.label); label->SetHorizontalAlignment(gfx::ALIGN_LEFT); layout->AddView(label); @@ -390,7 +387,7 @@ bubble_content.domain_lists.begin()); i != bubble_content.domain_lists.end(); ++i) { layout->StartRow(0, kSingleColumnSetId); - views::Label* section_title = new views::Label(base::UTF8ToUTF16(i->title)); + views::Label* section_title = new views::Label(i->title); section_title->SetMultiLine(true); section_title->SetHorizontalAlignment(gfx::ALIGN_LEFT); layout->AddView(section_title, 1, 1, GridLayout::FILL, GridLayout::LEADING); @@ -405,8 +402,7 @@ } if (!bubble_content.custom_link.empty()) { - custom_link_ = - new views::Link(base::UTF8ToUTF16(bubble_content.custom_link)); + custom_link_ = new views::Link(bubble_content.custom_link); custom_link_->SetEnabled(bubble_content.custom_link_enabled); custom_link_->set_listener(this); if (!bubble_content_empty) @@ -417,8 +413,7 @@ } if (bubble_content.show_manage_text_as_checkbox) { - manage_checkbox_ = - new views::Checkbox(base::UTF8ToUTF16(bubble_content.manage_text)); + manage_checkbox_ = new views::Checkbox(bubble_content.manage_text); manage_checkbox_->set_listener(this); layout->AddPaddingRow(0, related_control_vertical_spacing); layout->StartRow(0, indented_kSingleColumnSetId); @@ -443,7 +438,7 @@ if (bubble_content.show_manage_text_as_checkbox) return nullptr; - manage_link_ = new views::Link(base::UTF8ToUTF16(bubble_content.manage_text)); + manage_link_ = new views::Link(bubble_content.manage_text); manage_link_->set_listener(this); return manage_link_; }
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.h b/chrome/browser/ui/views/content_setting_bubble_contents.h index 830b8ce1..c02aa1f 100644 --- a/chrome/browser/ui/views/content_setting_bubble_contents.h +++ b/chrome/browser/ui/views/content_setting_bubble_contents.h
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/strings/string16.h" #include "components/content_settings/core/common/content_settings_types.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/common/media_stream_request.h"
diff --git a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc index a654ae2..2923fbe2 100644 --- a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc +++ b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" #include "chrome/browser/ui/views/payments/payment_request_views_util.h" #include "chrome/grit/generated_resources.h" @@ -193,6 +194,8 @@ response.cvc = cvc; unmask_delegate_->OnUnmaskResponse(response); } + + dialog()->ShowProcessingSpinner(); } } // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc index 7e6b2160..9ab08ea4 100644 --- a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc +++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
@@ -20,8 +20,13 @@ #include "chrome/browser/ui/views/payments/shipping_option_view_controller.h" #include "components/constrained_window/constrained_window_views.h" #include "components/payments/content/payment_request.h" +#include "components/strings/grit/components_strings.h" #include "content/public/browser/browser_thread.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/views/background.h" +#include "ui/views/controls/label.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/layout/grid_layout.h" namespace chrome { @@ -63,6 +68,8 @@ view_stack_.set_owned_by_client(); AddChildView(&view_stack_); + SetupSpinnerOverlay(); + ShowInitialPaymentSheet(); } @@ -228,6 +235,11 @@ observer_for_testing_->OnEditorViewUpdated(); } +void PaymentRequestDialogView::ShowProcessingSpinner() { + throbber_.Start(); + throbber_overlay_.SetVisible(true); +} + void PaymentRequestDialogView::ShowInitialPaymentSheet() { view_stack_.Push(CreateViewAndInstallController( base::MakeUnique<PaymentSheetViewController>( @@ -238,6 +250,44 @@ observer_for_testing_->OnDialogOpened(); } +void PaymentRequestDialogView::SetupSpinnerOverlay() { + throbber_.set_owned_by_client(); + + throbber_overlay_.set_owned_by_client(); + throbber_overlay_.SetPaintToLayer(); + throbber_overlay_.SetVisible(false); + // The throbber overlay has to have a solid white background to hide whatever + // would be under it. + throbber_overlay_.set_background( + views::Background::CreateSolidBackground(SK_ColorWHITE)); + + std::unique_ptr<views::GridLayout> layout = + base::MakeUnique<views::GridLayout>(&throbber_overlay_); + views::ColumnSet* throbber_columns = layout->AddColumnSet(0); + throbber_columns->AddPaddingColumn(0.5, 0); + throbber_columns->AddColumn(views::GridLayout::Alignment::CENTER, + views::GridLayout::Alignment::TRAILING, 0, + views::GridLayout::SizeType::USE_PREF, 0, 0); + throbber_columns->AddPaddingColumn(0.5, 0); + + views::ColumnSet* label_columns = layout->AddColumnSet(1); + label_columns->AddPaddingColumn(0.5, 0); + label_columns->AddColumn(views::GridLayout::Alignment::CENTER, + views::GridLayout::Alignment::LEADING, 0, + views::GridLayout::SizeType::USE_PREF, 0, 0); + label_columns->AddPaddingColumn(0.5, 0); + + layout->StartRow(0.5, 0); + layout->AddView(&throbber_); + + layout->StartRow(0.5, 1); + layout->AddView(new views::Label( + l10n_util::GetStringUTF16(IDS_PAYMENTS_PROCESSING_MESSAGE))); + + throbber_overlay_.SetLayoutManager(layout.release()); + AddChildView(&throbber_overlay_); +} + gfx::Size PaymentRequestDialogView::GetPreferredSize() const { return gfx::Size(kDialogWidth, kDialogHeight); }
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.h b/chrome/browser/ui/views/payments/payment_request_dialog_view.h index 85db903..03b3645e 100644 --- a/chrome/browser/ui/views/payments/payment_request_dialog_view.h +++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
@@ -12,6 +12,7 @@ #include "chrome/browser/ui/views/payments/view_stack.h" #include "components/payments/content/payment_request_dialog.h" #include "components/payments/content/payment_request_spec.h" +#include "ui/views/controls/throbber.h" #include "ui/views/window/dialog_delegate.h" namespace payments { @@ -100,10 +101,15 @@ result_delegate, content::WebContents* web_contents) override; + // Shows a full dialog spinner with the "processing" label that doesn't offer + // a way of closing the dialog. + void ShowProcessingSpinner(); + ViewStack* view_stack_for_testing() { return &view_stack_; } private: void ShowInitialPaymentSheet(); + void SetupSpinnerOverlay(); // views::View gfx::Size GetPreferredSize() const override; @@ -118,6 +124,11 @@ ControllerMap controller_map_; ViewStack view_stack_; + // A full dialog overlay that shows a spinner and the "processing" label. It's + // hidden until ShowProcessingSpinner is called. + views::View throbber_overlay_; + views::Throbber throbber_; + // May be null. ObserverForTest* observer_for_testing_;
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index b9be3b0..79e8128d 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -252,8 +252,6 @@ "extensions/api/notifications/notification_style.h", "extensions/api/omnibox/omnibox_handler.cc", "extensions/api/omnibox/omnibox_handler.h", - "extensions/api/plugins/plugins_handler.cc", - "extensions/api/plugins/plugins_handler.h", "extensions/api/speech/tts_engine_manifest_handler.cc", "extensions/api/speech/tts_engine_manifest_handler.h", "extensions/api/spellcheck/spellcheck_handler.cc",
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index fe15824..30c9bba 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -22,7 +22,7 @@ #if defined(OS_MACOSX) // Enables Javascript execution via AppleScript. const base::Feature kAppleScriptExecuteJavaScript{ - "AppleScriptExecuteJavaScript", base::FEATURE_DISABLED_BY_DEFAULT}; + "AppleScriptExecuteJavaScript", base::FEATURE_ENABLED_BY_DEFAULT}; // Use the Toolkit-Views Task Manager window. const base::Feature kViewsTaskManager{"ViewsTaskManager",
diff --git a/chrome/common/extensions/chrome_manifest_handlers.cc b/chrome/common/extensions/chrome_manifest_handlers.cc index ca7ecf5..a047f72 100644 --- a/chrome/common/extensions/chrome_manifest_handlers.cc +++ b/chrome/common/extensions/chrome_manifest_handlers.cc
@@ -7,7 +7,6 @@ #include "build/build_config.h" #include "chrome/common/extensions/api/commands/commands_handler.h" #include "chrome/common/extensions/api/omnibox/omnibox_handler.h" -#include "chrome/common/extensions/api/plugins/plugins_handler.h" #include "chrome/common/extensions/api/speech/tts_engine_manifest_handler.h" #include "chrome/common/extensions/api/spellcheck/spellcheck_handler.h" #include "chrome/common/extensions/api/storage/storage_schema_manifest_handler.h" @@ -26,7 +25,6 @@ #include "chrome/common/extensions/manifest_handlers/ui_overrides_handler.h" #include "extensions/common/manifest_handlers/app_isolation_info.h" #include "extensions/common/manifest_handlers/options_page_info.h" -#include "extensions/common/manifest_handlers/requirements_info.h" #include "extensions/common/manifest_url_handlers.h" #if defined(OS_CHROMEOS) @@ -53,8 +51,6 @@ (new MinimumChromeVersionChecker)->Register(); (new OmniboxHandler)->Register(); (new OptionsPageManifestHandler)->Register(); - (new PluginsHandler)->Register(); - (new RequirementsHandler)->Register(); // Depends on plugins. (new SettingsOverridesHandler)->Register(); (new SpellcheckHandler)->Register(); (new StorageSchemaManifestHandler)->Register();
diff --git a/chrome/common/extensions/sync_helper.cc b/chrome/common/extensions/sync_helper.cc index 5e216f91..9152450f 100644 --- a/chrome/common/extensions/sync_helper.cc +++ b/chrome/common/extensions/sync_helper.cc
@@ -5,7 +5,6 @@ #include "chrome/common/extensions/sync_helper.h" #include "base/logging.h" -#include "chrome/common/extensions/api/plugins/plugins_handler.h" #include "chrome/common/extensions/extension_constants.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" @@ -13,6 +12,7 @@ #include "extensions/common/features/feature.h" #include "extensions/common/features/feature_provider.h" #include "extensions/common/manifest.h" +#include "extensions/common/manifest_handlers/plugins_handler.h" #include "extensions/common/manifest_url_handlers.h" #include "extensions/common/permissions/permissions_data.h"
diff --git a/chrome/common/extensions/sync_type_unittest.cc b/chrome/common/extensions/sync_type_unittest.cc index 2ac283b4..512ad30 100644 --- a/chrome/common/extensions/sync_type_unittest.cc +++ b/chrome/common/extensions/sync_type_unittest.cc
@@ -4,13 +4,13 @@ #include "base/files/file_path.h" #include "build/build_config.h" -#include "chrome/common/extensions/api/plugins/plugins_handler.h" #include "chrome/common/extensions/sync_helper.h" #include "extensions/common/error_utils.h" #include "extensions/common/extension.h" #include "extensions/common/features/simple_feature.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_constants.h" +#include "extensions/common/manifest_handlers/plugins_handler.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h"
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index ac39ffe9..778daa9 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1545,7 +1545,6 @@ "../browser/extensions/process_management_browsertest.cc", "../browser/extensions/process_manager_browsertest.cc", "../browser/extensions/renderer_initialization_browsertest.cc", - "../browser/extensions/requirements_checker_browsertest.cc", "../browser/extensions/sandboxed_pages_apitest.cc", "../browser/extensions/service_worker_apitest.cc", "../browser/extensions/shared_module_apitest.cc",
diff --git a/chrome/test/data/requirements_checker/no_requirements/manifest.json b/chrome/test/data/requirements_checker/no_requirements/manifest.json deleted file mode 100644 index a464131..0000000 --- a/chrome/test/data/requirements_checker/no_requirements/manifest.json +++ /dev/null
@@ -1,5 +0,0 @@ -{ - "name": "RequirementsChecker Browser Test", - "version": "1.0", - "manifest_version": 2 -}
diff --git a/chrome/test/data/requirements_checker/require_3d/manifest.json b/chrome/test/data/requirements_checker/require_3d/manifest.json deleted file mode 100644 index c5cbf5d..0000000 --- a/chrome/test/data/requirements_checker/require_3d/manifest.json +++ /dev/null
@@ -1,10 +0,0 @@ -{ - "name": "RequirementsChecker Browser Test", - "version": "1.0", - "manifest_version": 2, - "requirements": { - "3D": { - "features": ["webgl", "css3d"] - } - } -}
diff --git a/chrome/test/data/requirements_checker/require_npapi/manifest.json b/chrome/test/data/requirements_checker/require_npapi/manifest.json deleted file mode 100644 index 90835ac2b..0000000 --- a/chrome/test/data/requirements_checker/require_npapi/manifest.json +++ /dev/null
@@ -1,10 +0,0 @@ -{ - "name": "RequirementsChecker Browser Test", - "version": "1.0", - "manifest_version": 2, - "requirements": { - "plugins": { - "npapi": true - } - } -}
diff --git a/chrome/test/data/requirements_checker/require_window_shape/manifest.json b/chrome/test/data/requirements_checker/require_window_shape/manifest.json deleted file mode 100644 index 0e145dc..0000000 --- a/chrome/test/data/requirements_checker/require_window_shape/manifest.json +++ /dev/null
@@ -1,10 +0,0 @@ -{ - "name": "RequirementsChecker Browser Test", - "version": "1.0", - "manifest_version": 2, - "requirements": { - "window": { - "shape": true - } - } -}
diff --git a/chrome/test/data/webui/settings/search_page_test.js b/chrome/test/data/webui/settings/search_page_test.js index a8394f17..e763544 100644 --- a/chrome/test/data/webui/settings/search_page_test.js +++ b/chrome/test/data/webui/settings/search_page_test.js
@@ -101,7 +101,9 @@ // Tests the UI when Hotword 'alwaysOn' is true. test('HotwordAlwaysOn', function() { - return browserProxy.whenCalled('getHotwordInfo').then(function() { + return browserProxy.whenCalled('getSearchEnginesList').then(function() { + return browserProxy.whenCalled('getHotwordInfo'); + }).then(function() { Polymer.dom.flush(); assertTrue(page.hotwordInfo_.allowed); assertTrue(page.hotwordInfo_.alwaysOn); @@ -123,7 +125,9 @@ // Tests the UI when Hotword 'alwaysOn' is false. test('HotwordNotAlwaysOn', function() { - return browserProxy.whenCalled('getHotwordInfo').then(function() { + return browserProxy.whenCalled('getSearchEnginesList').then(function() { + return browserProxy.whenCalled('getHotwordInfo'); + }).then(function() { browserProxy.setHotwordInfo({ allowed: true, enabled: false,
diff --git a/components/arc/common/power.mojom b/components/arc/common/power.mojom index 195c7c82..f2fc4d87 100644 --- a/components/arc/common/power.mojom +++ b/components/arc/common/power.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Next min version: 3 +// Next min version: 4 module arc.mojom; @@ -19,7 +19,7 @@ DIM = 1 }; -// Next method ID: 3 +// Next method ID: 4 interface PowerHost { // Acquire and release wake locks on the host side. OnAcquireDisplayWakeLock@0(DisplayWakeLockType type); @@ -27,9 +27,13 @@ // Checks if there is a display on. [MinVersion=1] IsDisplayOn@2() => (bool is_on); + + // Request that the screen brightness be changed to |percent|. + // |percent| is of the range [0, 100] + [MinVersion=3] OnScreenBrightnessUpdateRequest@3(double percent); }; -// Next method ID: 4 +// Next method ID: 5 interface PowerInstance { // Establishes full-duplex communication with the host. Init@0(PowerHost host_ptr); @@ -43,4 +47,8 @@ // Called when the system has just resumed. [MinVersion=2] Resume@3(); + + // Update Android brightness settings. + // |percent| is of the range [0, 100] + [MinVersion=3] UpdateScreenBrightnessSettings@4(double percent); };
diff --git a/components/arc/power/arc_power_bridge.cc b/components/arc/power/arc_power_bridge.cc index ec4906f..1e0ad9c 100644 --- a/components/arc/power/arc_power_bridge.cc +++ b/components/arc/power/arc_power_bridge.cc
@@ -17,7 +17,7 @@ namespace arc { ArcPowerBridge::ArcPowerBridge(ArcBridgeService* bridge_service) - : ArcService(bridge_service), binding_(this) { + : ArcService(bridge_service), binding_(this), weak_ptr_factory_(this) { arc_bridge_service()->power()->AddObserver(this); } @@ -34,6 +34,11 @@ ash::Shell::Get()->display_configurator()->AddObserver(this); chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> AddObserver(this); + chromeos::DBusThreadManager::Get() + ->GetPowerManagerClient() + ->GetScreenBrightnessPercent( + base::Bind(&ArcPowerBridge::UpdateAndroidScreenBrightness, + weak_ptr_factory_.GetWeakPtr())); } void ArcPowerBridge::OnInstanceClosed() { @@ -63,6 +68,10 @@ power_instance->Resume(); } +void ArcPowerBridge::BrightnessChanged(int level, bool user_initiated) { + UpdateAndroidScreenBrightness(static_cast<double>(level)); +} + void ArcPowerBridge::OnPowerStateChanged( chromeos::DisplayPowerState power_state) { mojom::PowerInstance* power_instance = ARC_GET_INSTANCE_FOR_METHOD( @@ -125,6 +134,12 @@ callback.Run(ash::Shell::Get()->display_configurator()->IsDisplayOn()); } +void ArcPowerBridge::OnScreenBrightnessUpdateRequest(double percent) { + chromeos::DBusThreadManager::Get() + ->GetPowerManagerClient() + ->SetScreenBrightnessPercent(percent, true); +} + void ArcPowerBridge::ReleaseAllDisplayWakeLocks() { if (!chromeos::PowerPolicyController::IsInitialized()) { LOG(WARNING) << "PowerPolicyController is not available"; @@ -139,4 +154,12 @@ wake_locks_.clear(); } +void ArcPowerBridge::UpdateAndroidScreenBrightness(double percent) { + mojom::PowerInstance* power_instance = ARC_GET_INSTANCE_FOR_METHOD( + arc_bridge_service()->power(), UpdateScreenBrightnessSettings); + if (!power_instance) + return; + power_instance->UpdateScreenBrightnessSettings(percent); +} + } // namespace arc
diff --git a/components/arc/power/arc_power_bridge.h b/components/arc/power/arc_power_bridge.h index c459cff..328ded9 100644 --- a/components/arc/power/arc_power_bridge.h +++ b/components/arc/power/arc_power_bridge.h
@@ -37,6 +37,7 @@ // chromeos::PowerManagerClient::Observer overrides. void SuspendImminent() override; void SuspendDone(const base::TimeDelta& sleep_duration) override; + void BrightnessChanged(int level, bool user_initiated) override; // DisplayConfigurator::Observer overrides. void OnPowerStateChanged(chromeos::DisplayPowerState power_state) override; @@ -45,9 +46,11 @@ void OnAcquireDisplayWakeLock(mojom::DisplayWakeLockType type) override; void OnReleaseDisplayWakeLock(mojom::DisplayWakeLockType type) override; void IsDisplayOn(const IsDisplayOnCallback& callback) override; + void OnScreenBrightnessUpdateRequest(double percent) override; private: void ReleaseAllDisplayWakeLocks(); + void UpdateAndroidScreenBrightness(double percent); mojo::Binding<mojom::PowerHost> binding_; @@ -55,6 +58,8 @@ // held by ARC. std::multimap<mojom::DisplayWakeLockType, int> wake_locks_; + base::WeakPtrFactory<ArcPowerBridge> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(ArcPowerBridge); };
diff --git a/components/autofill/core/browser/form_group.cc b/components/autofill/core/browser/form_group.cc index 417f08a..1f248ccf 100644 --- a/components/autofill/core/browser/form_group.cc +++ b/components/autofill/core/browser/form_group.cc
@@ -57,4 +57,14 @@ return true; } +bool FormGroup::HasInfo(ServerFieldType type) const { + return HasInfo(AutofillType(type)); +} + +bool FormGroup::HasInfo(const AutofillType& type) const { + // Use "en-US" as a placeholder locale. We are only interested in emptiness, + // not in the presentation of the string. + return !GetInfo(type, "en-US").empty(); +} + } // namespace autofill
diff --git a/components/autofill/core/browser/form_group.h b/components/autofill/core/browser/form_group.h index 86bd453..c3d9cd14 100644 --- a/components/autofill/core/browser/form_group.h +++ b/components/autofill/core/browser/form_group.h
@@ -53,6 +53,10 @@ const base::string16& value, const std::string& app_locale); + // Returns true iff the string associated with |type| is nonempty. + bool HasInfo(ServerFieldType type) const; + bool HasInfo(const AutofillType& type) const; + protected: // AutofillProfile needs to call into GetSupportedTypes() for objects of // non-AutofillProfile type, for which mere inheritance is insufficient.
diff --git a/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc b/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc index fdcbfdf..f883c97 100644 --- a/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc +++ b/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc
@@ -28,6 +28,7 @@ sync_client, syncer::GROUP_DB, std::move(db_thread)), + sync_client_(sync_client), web_data_service_(web_data_service), callback_registered_(false) {}
diff --git a/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h b/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h index 9f88388..6dd5fd5 100644 --- a/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h +++ b/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h
@@ -43,6 +43,9 @@ // Callback to notify that WebDatabase has loaded. void WebDatabaseLoaded(); + // A pointer to the sync client. + syncer::SyncClient* const sync_client_; + // A reference to the AutofillWebDataService for this controller. scoped_refptr<autofill::AutofillWebDataService> web_data_service_;
diff --git a/components/browser_sync/profile_sync_test_util.cc b/components/browser_sync/profile_sync_test_util.cc index 90cdff6..ee186d14 100644 --- a/components/browser_sync/profile_sync_test_util.cc +++ b/components/browser_sync/profile_sync_test_util.cc
@@ -20,8 +20,6 @@ #include "components/sync/engine/ui_model_worker.h" #include "net/url_request/url_request_test_util.h" -using ServiceProvider = syncer::SyncClient::ServiceProvider; - namespace browser_sync { namespace { @@ -47,7 +45,8 @@ PrefService* GetPrefService() override; sync_sessions::SyncSessionsClient* GetSyncSessionsClient() override; autofill::PersonalDataManager* GetPersonalDataManager() override; - ServiceProvider GetSyncableServiceForType(syncer::ModelType type) override; + base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( + syncer::ModelType type) override; syncer::SyncService* GetSyncService() override; scoped_refptr<syncer::ModelSafeWorker> CreateModelWorkerForGroup( syncer::ModelSafeGroup group) override; @@ -110,11 +109,11 @@ return personal_data_manager_; } -ServiceProvider BundleSyncClient::GetSyncableServiceForType( - syncer::ModelType type) { +base::WeakPtr<syncer::SyncableService> +BundleSyncClient::GetSyncableServiceForType(syncer::ModelType type) { if (get_syncable_service_callback_.is_null()) return syncer::FakeSyncClient::GetSyncableServiceForType(type); - return base::Bind(get_syncable_service_callback_, type); + return get_syncable_service_callback_.Run(type); } syncer::SyncService* BundleSyncClient::GetSyncService() {
diff --git a/components/cronet/android/test/javaperftests/src/org/chromium/net/CronetPerfTestActivity.java b/components/cronet/android/test/javaperftests/src/org/chromium/net/CronetPerfTestActivity.java index 340b065..7ab6e72 100644 --- a/components/cronet/android/test/javaperftests/src/org/chromium/net/CronetPerfTestActivity.java +++ b/components/cronet/android/test/javaperftests/src/org/chromium/net/CronetPerfTestActivity.java
@@ -199,12 +199,10 @@ } try { - JSONObject quicParams = new JSONObject().put("host_whitelist", host); JSONObject hostResolverParams = CronetTestUtil.generateHostResolverRules(getConfigString("HOST_IP")); JSONObject experimentalOptions = new JSONObject() - .put("QUIC", quicParams) .put("HostResolverRules", hostResolverParams); cronetEngineBuilder.setExperimentalOptions(experimentalOptions.toString()); } catch (JSONException e) {
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java index 5d7749f..e83523b 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamQuicTest.java
@@ -36,7 +36,7 @@ QuicTestServer.startQuicTestServer(getContext()); builder.enableQuic(true); - JSONObject quicParams = new JSONObject().put("host_whitelist", "test.example.com"); + JSONObject quicParams = new JSONObject(); if (enabled == QuicBidirectionalStreams.DISABLED) { quicParams.put("quic_disable_bidirectional_streams", true); }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/PkpTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/PkpTest.java index d89e625..120c5df3 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/PkpTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/PkpTest.java
@@ -393,10 +393,8 @@ mBuilder.enableQuic(true); mBuilder.addQuicHint(QuicTestServer.getServerHost(), QuicTestServer.getServerPort(), QuicTestServer.getServerPort()); - JSONObject quicParams = new JSONObject().put("host_whitelist", "test.example.com"); JSONObject hostResolverParams = CronetTestUtil.generateHostResolverRules(); JSONObject experimentalOptions = new JSONObject() - .put("QUIC", quicParams) .put("HostResolverRules", hostResolverParams); mBuilder.setExperimentalOptions(experimentalOptions.toString()); mBuilder.setStoragePath(CronetTestFramework.getTestStorage(getContext()));
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java index ca8f6f7..a0958c2b 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
@@ -47,7 +47,6 @@ // TODO(mgersh): Enable connection migration once it works, see http://crbug.com/634910 JSONObject quicParams = new JSONObject() .put("connection_options", "PACE,IW10,FOO,DEADBEEF") - .put("host_whitelist", "test.example.com") .put("max_server_configs_stored_in_properties", 2) .put("delay_tcp_race", true) .put("idle_connection_timeout_seconds", 300) @@ -119,10 +118,8 @@ builder.setStoragePath(CronetTestFramework.getTestStorage(getContext())); builder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK, 1000 * 1024); builder.enableQuic(true); - JSONObject quicParams = new JSONObject().put("host_whitelist", "test.example.com"); JSONObject hostResolverParams = CronetTestUtil.generateHostResolverRules(); JSONObject experimentalOptions = new JSONObject() - .put("QUIC", quicParams) .put("HostResolverRules", hostResolverParams); builder.setExperimentalOptions(experimentalOptions.toString()); CronetTestUtil.setMockCertVerifierForTesting(
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/QuicUploadTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/QuicUploadTest.java index 200b74a..d874848 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/QuicUploadTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/QuicUploadTest.java
@@ -38,11 +38,8 @@ QuicTestServer.startQuicTestServer(getContext()); builder.enableQuic(true); - JSONObject quicParams = - new JSONObject().put("host_whitelist", QuicTestServer.getServerHost()); JSONObject hostResolverParams = CronetTestUtil.generateHostResolverRules(); JSONObject experimentalOptions = new JSONObject() - .put("QUIC", quicParams) .put("HostResolverRules", hostResolverParams); builder.setExperimentalOptions(experimentalOptions.toString());
diff --git a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/QuicTest.java b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/QuicTest.java index 5719a93..6c91b0a3 100644 --- a/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/QuicTest.java +++ b/components/cronet/android/test/smoketests/src/org/chromium/net/smoke/QuicTest.java
@@ -45,8 +45,6 @@ JSONObject quicParams = new JSONObject().put("delay_tcp_race", true); JSONObject experimentalOptions = new JSONObject().put("QUIC", quicParams); mTestSupport.addHostResolverRules(experimentalOptions); - experimentalOptions.put("host_whitelist", url.getHost()); - mCronetEngineBuilder.setExperimentalOptions(experimentalOptions.toString()); initCronetEngine();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc index b36fd93..26385ac 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
@@ -19,14 +19,12 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h" #include "components/data_reduction_proxy/core/browser/data_use_group.h" #include "components/data_reduction_proxy/core/browser/data_use_group_provider.h" -#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.h" #include "components/data_reduction_proxy/core/common/lofi_decider.h" #include "net/base/load_flags.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" -#include "net/nqe/effective_connection_type.h" #include "net/nqe/network_quality_estimator.h" #include "net/proxy/proxy_info.h" #include "net/proxy/proxy_server.h" @@ -122,11 +120,9 @@ const net::HttpRequestHeaders& headers) { if (via_chrome_proxy) { DCHECK(headers.HasHeader(chrome_proxy_header())); - DCHECK(headers.HasHeader(chrome_proxy_ect_header())); } else { DCHECK(!headers.HasHeader(chrome_proxy_header())); DCHECK(!headers.HasHeader(chrome_proxy_accept_transform_header())); - DCHECK(!headers.HasHeader(chrome_proxy_ect_header())); } } @@ -211,8 +207,6 @@ ->MaybeSetAcceptTransformHeader( *request, data_reduction_proxy_config_->lofi_off(), headers); } - - MaybeAddChromeProxyECTHeader(headers, *request); } void DataReductionProxyNetworkDelegate::OnBeforeSendHeadersInternal( @@ -261,7 +255,6 @@ // Chrome-Proxy-Accept-Transform header. lofi_decider->RemoveAcceptTransformHeader(headers); } - RemoveChromeProxyECTHeader(headers); VerifyHttpRequestHeaders(false, *headers); return; } @@ -521,48 +514,4 @@ header_value); } -void DataReductionProxyNetworkDelegate::MaybeAddChromeProxyECTHeader( - net::HttpRequestHeaders* request_headers, - const net::URLRequest& request) const { - DCHECK(thread_checker_.CalledOnValidThread()); - - // This method should be called only when the resolved proxy was a data - // saver proxy. - DCHECK(request.url().is_valid()); - DCHECK(!request.url().SchemeIsCryptographic()); - DCHECK(request.url().SchemeIsHTTPOrHTTPS()); - - if (request_headers->HasHeader(chrome_proxy_ect_header())) - request_headers->RemoveHeader(chrome_proxy_ect_header()); - - if (request.context()->network_quality_estimator()) { - net::EffectiveConnectionType type = request.context() - ->network_quality_estimator() - ->GetEffectiveConnectionType(); - if (type > net::EFFECTIVE_CONNECTION_TYPE_OFFLINE) { - DCHECK_NE(net::EFFECTIVE_CONNECTION_TYPE_LAST, type); - request_headers->SetHeader(chrome_proxy_ect_header(), - net::GetNameForEffectiveConnectionType(type)); - return; - } - } - request_headers->SetHeader(chrome_proxy_ect_header(), - net::GetNameForEffectiveConnectionType( - net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN)); - - static_assert(net::EFFECTIVE_CONNECTION_TYPE_OFFLINE + 1 == - net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G, - "ECT enum value is not handled."); - static_assert(net::EFFECTIVE_CONNECTION_TYPE_4G + 1 == - net::EFFECTIVE_CONNECTION_TYPE_LAST, - "ECT enum value is not handled."); -} - -void DataReductionProxyNetworkDelegate::RemoveChromeProxyECTHeader( - net::HttpRequestHeaders* request_headers) const { - DCHECK(thread_checker_.CalledOnValidThread()); - - request_headers->RemoveHeader(chrome_proxy_ect_header()); -} - } // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h index f32107b..f36cea45 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
@@ -157,17 +157,6 @@ net::HttpRequestHeaders* request_headers, const net::URLRequest& request) const; - // May add chrome-proxy-ect header to |request_headers| if adding of - // chrome-proxy-ect is enabled via field trial and a valid estimate of - // network quality is available. This method should be called only when the - // resolved proxy for |request| is a data saver proxy. - void MaybeAddChromeProxyECTHeader(net::HttpRequestHeaders* request_headers, - const net::URLRequest& request) const; - - // Removes the chrome-proxy-ect header from |request_headers|. - void RemoveChromeProxyECTHeader( - net::HttpRequestHeaders* request_headers) const; - // All raw Data Reduction Proxy pointers must outlive |this|. DataReductionProxyConfig* data_reduction_proxy_config_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc index 038119c..a02808c 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -228,79 +228,6 @@ test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess(); } - // Build the sockets by adding appropriate mock data for - // |effective_connection_types.size()| number of requests. Data for - // chrome-Proxy-ect header is added to the mock data if |expect_ect_header| - // is true. |reads_list|, |mock_writes| and |writes_list| should be empty, and - // are owned by the caller. - void BuildSocket(const std::string& response_headers, - const std::string& response_body, - bool expect_ect_header, - const std::vector<net::EffectiveConnectionType>& - effective_connection_types, - std::vector<net::MockRead>* reads_list, - std::vector<std::string>* mock_writes, - std::vector<net::MockWrite>* writes_list) { - EXPECT_LT(0u, effective_connection_types.size()); - EXPECT_TRUE(reads_list->empty()); - EXPECT_TRUE(mock_writes->empty()); - EXPECT_TRUE(writes_list->empty()); - - for (size_t i = 0; i < effective_connection_types.size(); ++i) { - reads_list->push_back(net::MockRead(response_headers.c_str())); - reads_list->push_back(net::MockRead(response_body.c_str())); - } - reads_list->push_back(net::MockRead(net::SYNCHRONOUS, net::OK)); - - std::string prefix = std::string("GET ") - .append(kTestURL) - .append(" HTTP/1.1\r\n") - .append("Host: ") - .append(GURL(kTestURL).host()) - .append( - "\r\n" - "Proxy-Connection: keep-alive\r\n" - "User-Agent:\r\n" - "Accept-Encoding: gzip, deflate\r\n" - "Accept-Language: en-us,fr\r\n"); - - if (io_data()->test_request_options()->GetHeaderValueForTesting().empty()) { - // Force regeneration of Chrome-Proxy header. - io_data()->test_request_options()->SetSecureSession("123"); - } - - EXPECT_FALSE( - io_data()->test_request_options()->GetHeaderValueForTesting().empty()); - - std::string suffix = - std::string("Chrome-Proxy: ") + - io_data()->test_request_options()->GetHeaderValueForTesting() + - std::string("\r\n\r\n"); - - mock_socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider_); - - for (net::EffectiveConnectionType effective_connection_type : - effective_connection_types) { - std::string ect_header; - if (expect_ect_header) { - ect_header = "chrome-proxy-ect: " + - std::string(net::GetNameForEffectiveConnectionType( - effective_connection_type)) + - "\r\n"; - } - - std::string mock_write = prefix + ect_header + suffix; - mock_writes->push_back(mock_write); - writes_list->push_back(net::MockWrite(mock_writes->back().c_str())); - } - - EXPECT_FALSE(socket_); - socket_ = base::MakeUnique<net::StaticSocketDataProvider>( - reads_list->data(), reads_list->size(), writes_list->data(), - writes_list->size()); - mock_socket_factory_.AddSocketDataProvider(socket_.get()); - } - static void VerifyHeaders(bool expected_data_reduction_proxy_used, bool expected_lofi_used, const net::HttpRequestHeaders& headers) { @@ -425,10 +352,6 @@ "User-Agent:\r\n"); std::string accept_language_header("Accept-Language: en-us,fr\r\n"); - std::string ect_header = "chrome-proxy-ect: " + - std::string(net::GetNameForEffectiveConnectionType( - net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN)) + - "\r\n"; // Brotli is included in accept-encoding header only if the request went // to the network (i.e., it was not a cached response), and if data @@ -444,14 +367,13 @@ std::string("\r\n\r\n"); std::string mock_write = prefix_headers + accept_language_header + - ect_header + accept_encoding_header + - suffix_headers; + accept_encoding_header + suffix_headers; if (expect_cached || !expect_brotli) { // Order of headers is different if the headers were modified by data // reduction proxy network delegate. mock_write = prefix_headers + accept_encoding_header + - accept_language_header + ect_header + suffix_headers; + accept_language_header + suffix_headers; } net::MockWrite writes[] = {net::MockWrite(mock_write.c_str())}; @@ -508,51 +430,6 @@ } } - // Fetches a request while the effective connection type is set to - // |effective_connection_type|. Verifies that the request headers include the - // chrome-proxy-ect header only if |expect_ect_header| is true. The response - // must be served from the cache if |expect_cached| is true. - void FetchURLRequestAndVerifyECTHeader( - net::EffectiveConnectionType effective_connection_type, - bool expect_ect_header, - bool expect_cached) { - test_network_quality_estimator()->set_effective_connection_type( - effective_connection_type); - - net::TestDelegate delegate; - std::unique_ptr<net::URLRequest> request = - context_.CreateRequest(GURL(kTestURL), net::IDLE, &delegate); - - request->Start(); - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(140, request->received_response_content_length()); - EXPECT_EQ(expect_cached, request->was_cached()); - EXPECT_EQ(expect_cached, request->GetTotalSentBytes() == 0); - EXPECT_EQ(expect_cached, request->GetTotalReceivedBytes() == 0); - - net::HttpRequestHeaders sent_request_headers; - EXPECT_NE(expect_cached, - request->GetFullRequestHeaders(&sent_request_headers)); - - if (expect_cached) { - // Request headers are missing. Return since there is nothing left to - // check. - return; - } - - // Verify that chrome-proxy-ect header is present in the request headers - // only if |expect_ect_header| is true. - std::string ect_value; - EXPECT_EQ(expect_ect_header, sent_request_headers.GetHeader( - chrome_proxy_ect_header(), &ect_value)); - - if (!expect_ect_header) - return; - EXPECT_EQ(net::GetNameForEffectiveConnectionType(effective_connection_type), - ect_value); - } - void DelegateStageDone(int result) {} void NotifyNetworkDelegate(net::URLRequest* request, @@ -1286,89 +1163,6 @@ FetchURLRequestAndVerifyBrotli(nullptr, response_headers, true, true); } -// Test that effective connection type is correctly added to the request -// headers when it is enabled using field trial. The server is varying on the -// effective connection type (ECT). -TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderEnabledWithVary) { - Init(true /* use_secure_proxy */, false /* enable_brotli_globally */); - - std::string response_headers = - "HTTP/1.1 200 OK\r\n" - "Content-Length: 140\r\n" - "Via: 1.1 Chrome-Compression-Proxy\r\n" - "Cache-Control: max-age=1200\r\n" - "Vary: chrome-proxy-ect\r\n" - "x-original-content-length: 200\r\n\r\n"; - - int response_body_size = 140; - std::string response_body(base::checked_cast<size_t>(response_body_size), - ' '); - - std::vector<net::MockRead> reads_list; - std::vector<std::string> mock_writes; - std::vector<net::MockWrite> writes_list; - - std::vector<net::EffectiveConnectionType> effective_connection_types; - effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G); - effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_2G); - - BuildSocket(response_headers, response_body, true, effective_connection_types, - &reads_list, &mock_writes, &writes_list); - - // Add 2 socket providers since 2 requests in this test are fetched from the - // network. - FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, false); - - // When the ECT is set to the same value, fetching the same resource should - // result in a cache hit. - FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, true); - - // When the ECT is set to a different value, the response should not be - // served from the cache. - FetchURLRequestAndVerifyECTHeader(effective_connection_types[1], true, false); -} - -// Test that effective connection type is correctly added to the request -// headers when it is enabled using field trial. The server is not varying on -// the effective connection type (ECT). -TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderEnabledWithoutVary) { - Init(true /* use_secure_proxy */, false /* enable_brotli_globally */); - - std::string response_headers = - "HTTP/1.1 200 OK\r\n" - "Content-Length: 140\r\n" - "Via: 1.1 Chrome-Compression-Proxy\r\n" - "Cache-Control: max-age=1200\r\n" - "x-original-content-length: 200\r\n\r\n"; - - int response_body_size = 140; - std::string response_body(base::checked_cast<size_t>(response_body_size), - ' '); - - std::vector<net::MockRead> reads_list; - std::vector<std::string> mock_writes; - std::vector<net::MockWrite> writes_list; - - std::vector<net::EffectiveConnectionType> effective_connection_types; - effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G); - effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_2G); - - BuildSocket(response_headers, response_body, true, effective_connection_types, - &reads_list, &mock_writes, &writes_list); - - // Add 1 socket provider since 1 request in this test is fetched from the - // network. - FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, false); - - // When the ECT is set to the same value, fetching the same resource should - // result in a cache hit. - FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, true); - - // When the ECT is set to a different value, the response should still be - // served from the cache. - FetchURLRequestAndVerifyECTHeader(effective_connection_types[1], true, true); -} - } // namespace } // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc index b3c2f6ca..b22ead1 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
@@ -28,7 +28,6 @@ namespace { const char kChromeProxyHeader[] = "chrome-proxy"; -const char kChromeProxyECTHeader[] = "chrome-proxy-ect"; const char kChromeProxyAcceptTransformHeader[] = "chrome-proxy-accept-transform"; const char kChromeProxyContentTransformHeader[] = @@ -126,10 +125,6 @@ return kChromeProxyHeader; } -const char* chrome_proxy_ect_header() { - return kChromeProxyECTHeader; -} - const char* chrome_proxy_accept_transform_header() { return kChromeProxyAcceptTransformHeader; }
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h index 7ed898e6..b3720d4 100644 --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
@@ -68,10 +68,6 @@ // Gets the header used for data reduction proxy requests and responses. const char* chrome_proxy_header(); -// Gets the chrome-proxy-ect request header that includes the effective -// connection type. -const char* chrome_proxy_ect_header(); - // Gets the ChromeProxyAcceptTransform header name. const char* chrome_proxy_accept_transform_header();
diff --git a/components/display_compositor/BUILD.gn b/components/display_compositor/BUILD.gn index e54fb14..57b7cdd 100644 --- a/components/display_compositor/BUILD.gn +++ b/components/display_compositor/BUILD.gn
@@ -17,11 +17,6 @@ "gl_helper_readback_support.h", "gl_helper_scaling.cc", "gl_helper_scaling.h", - "gpu_compositor_frame_sink.cc", - "gpu_compositor_frame_sink.h", - "gpu_compositor_frame_sink_delegate.h", - "gpu_root_compositor_frame_sink.cc", - "gpu_root_compositor_frame_sink.h", ] configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
diff --git a/components/payments/README b/components/payments/README new file mode 100644 index 0000000..414314a4 --- /dev/null +++ b/components/payments/README
@@ -0,0 +1,35 @@ +This directory contains shared code used by multiple platforms' native +implementations of PaymentRequest. In general, business logic (i.e., logic which +manipulates data and is not specific to any particular platform's display of the +data) should live here as much as possible. + + +Internally, the directory uses the Layered Components model: + +http://www.chromium.org/developers/design-documents/layered-components-design + + +In practical terms, our division between content/ and core/ is usually just a +question of whether the contents have a dependency on Mojo: + +* ./core/ -- preferred whenever possible + +* ./content/ -- code with a Mojo dependency + +* ./content/android/ -- Android bindings for code in either core/ or content/ + + +Intended consumers of this code are organized as follows: + +* chrome/android/.../chrome/browser/payments/ -- Android UI Implementation + +* chrome/browser/ui/views/payments/ -- Desktop UI implementation + +* content/browser/android/payments -- Android bindings for PaymentApps + +* content/browser/payments/ -- PaymentApps implementation + +* ios/chrome/browser/payments/ -- iOS UI implementation + +* ios/web/payments/ and ios/web/public/payments/ -- iOS communication layer, + replacing Mojo
diff --git a/components/payments/content/payment_request_state.cc b/components/payments/content/payment_request_state.cc index 0a1a487..2f7850c 100644 --- a/components/payments/content/payment_request_state.cc +++ b/components/payments/content/payment_request_state.cc
@@ -15,6 +15,7 @@ #include "components/payments/content/payment_response_helper.h" #include "components/payments/core/autofill_payment_instrument.h" #include "components/payments/core/payment_request_delegate.h" +#include "components/payments/core/profile_util.h" namespace payments { @@ -161,12 +162,22 @@ profile_cache_.push_back( base::MakeUnique<autofill::AutofillProfile>(*profiles[i])); - // TODO(tmartino): Implement deduplication rules specific to shipping and - // contact profiles. + // TODO(tmartino): Implement deduplication rules specific to shipping + // profiles. shipping_profiles_.push_back(profile_cache_[i].get()); - contact_profiles_.push_back(profile_cache_[i].get()); } + std::vector<autofill::AutofillProfile*> raw_profiles_for_filtering( + profile_cache_.size()); + std::transform(profile_cache_.begin(), profile_cache_.end(), + raw_profiles_for_filtering.begin(), + [](const std::unique_ptr<autofill::AutofillProfile>& p) { + return p.get(); + }); + + contact_profiles_ = profile_util::FilterProfilesForContact( + raw_profiles_for_filtering, GetApplicationLocale(), *spec_); + // Create the list of available instruments. const std::vector<autofill::CreditCard*>& cards = personal_data_manager_->GetCreditCardsToSuggest(); @@ -242,32 +253,8 @@ if (spec_->request_shipping() && selected_shipping_profile_ == nullptr) return false; - // TODO(mathp): Make an encompassing class to validate contact info. - if (spec_->request_payer_name() && - (selected_contact_profile_ == nullptr || - selected_contact_profile_ - ->GetInfo(autofill::AutofillType(autofill::NAME_FULL), app_locale_) - .empty())) { - return false; - } - if (spec_->request_payer_email() && - (selected_contact_profile_ == nullptr || - selected_contact_profile_ - ->GetInfo(autofill::AutofillType(autofill::EMAIL_ADDRESS), - app_locale_) - .empty())) { - return false; - } - if (spec_->request_payer_phone() && - (selected_contact_profile_ == nullptr || - selected_contact_profile_ - ->GetInfo(autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER), - app_locale_) - .empty())) { - return false; - } - - return true; + profile_util::PaymentsProfileComparator comparator(app_locale_, *spec_); + return comparator.IsContactInfoComplete(selected_contact_profile_); } } // namespace payments
diff --git a/components/payments/core/BUILD.gn b/components/payments/core/BUILD.gn index 6b8cbc4..e330013 100644 --- a/components/payments/core/BUILD.gn +++ b/components/payments/core/BUILD.gn
@@ -24,6 +24,8 @@ "payment_request_data_util.cc", "payment_request_data_util.h", "payment_request_delegate.h", + "profile_util.cc", + "profile_util.h", "strings_util.cc", "strings_util.h", ] @@ -50,6 +52,7 @@ "payment_address_unittest.cc", "payment_method_data_unittest.cc", "payment_request_data_util_unittest.cc", + "profile_util_unittest.cc", ] deps = [
diff --git a/components/payments/core/address_normalizer.cc b/components/payments/core/address_normalizer.cc index 3114c5a..5fdd2558 100644 --- a/components/payments/core/address_normalizer.cc +++ b/components/payments/core/address_normalizer.cc
@@ -153,9 +153,8 @@ } } -void AddressNormalizer::OnAddressValidationRulesLoaded( - const std::string& region_code, - bool success) { +void AddressNormalizer::OnAddressRulesLoaded(const std::string& region_code, + bool success) { // Check if an address normalization is pending. auto it = pending_normalization_.find(region_code); if (it != pending_normalization_.end()) { @@ -166,4 +165,4 @@ } } -} // namespace payments \ No newline at end of file +} // namespace payments
diff --git a/components/payments/core/address_normalizer.h b/components/payments/core/address_normalizer.h index f3d2a24..2d5b1d5 100644 --- a/components/payments/core/address_normalizer.h +++ b/components/payments/core/address_normalizer.h
@@ -76,8 +76,8 @@ private: // Called when the validation rules for the |region_code| have finished // loading. Implementation of the LoadRulesListener interface. - void OnAddressValidationRulesLoaded(const std::string& region_code, - bool success) override; + void OnAddressRulesLoaded(const std::string& region_code, + bool success) override; // Map associating a region code to pending normalizations. std::map<std::string, std::vector<std::unique_ptr<Request>>>
diff --git a/components/payments/core/profile_util.cc b/components/payments/core/profile_util.cc new file mode 100644 index 0000000..c1149c8 --- /dev/null +++ b/components/payments/core/profile_util.cc
@@ -0,0 +1,123 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/payments/core/profile_util.h" + +#include <algorithm> + +#include "components/autofill/core/browser/autofill_profile.h" +#include "components/autofill/core/browser/field_types.h" +#include "components/payments/core/payment_options_provider.h" + +namespace payments { +namespace profile_util { + +std::vector<autofill::AutofillProfile*> FilterProfilesForContact( + const std::vector<autofill::AutofillProfile*>& profiles, + const std::string& app_locale, + const PaymentOptionsProvider& options) { + // We will be removing profiles, so we operate on a copy. + std::vector<autofill::AutofillProfile*> processed = profiles; + + PaymentsProfileComparator comparator(app_locale, options); + + // Stable sort, since profiles are expected to be passed in frecency order. + std::stable_sort( + processed.begin(), processed.end(), + std::bind(&PaymentsProfileComparator::IsContactMoreComplete, &comparator, + std::placeholders::_1, std::placeholders::_2)); + + auto it = processed.begin(); + while (it != processed.end()) { + if (comparator.GetContactCompletenessScore(*it) == 0) { + // Since profiles are sorted by completeness, this and any further + // profiles can be discarded. + processed.erase(it, processed.end()); + break; + } + + // Attempt to find a matching element in the vector before the current. + // This is quadratic, but the number of elements is generally small + // (< 10), so a more complicated algorithm would be overkill. + if (std::find_if(processed.begin(), it, + [&](autofill::AutofillProfile* prior) { + return comparator.IsContactEqualOrSuperset(*prior, **it); + }) != it) { + // Remove the subset profile. |it| will point to the next element after + // erasure. + it = processed.erase(it); + } else { + it++; + } + } + + return processed; +} + +PaymentsProfileComparator::PaymentsProfileComparator( + const std::string& app_locale, + const PaymentOptionsProvider& options) + : autofill::AutofillProfileComparator(app_locale), options_(options) {} + +PaymentsProfileComparator::~PaymentsProfileComparator() {} + +bool PaymentsProfileComparator::IsContactEqualOrSuperset( + const autofill::AutofillProfile& super, + const autofill::AutofillProfile& sub) { + if (options_.request_payer_name()) { + if (sub.HasInfo(autofill::NAME_FULL) && + !super.HasInfo(autofill::NAME_FULL)) { + return false; + } + if (!HaveMergeableNames(super, sub)) + return false; + } + if (options_.request_payer_phone()) { + if (sub.HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER) && + !super.HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER)) { + return false; + } + if (!HaveMergeablePhoneNumbers(super, sub)) + return false; + } + if (options_.request_payer_email()) { + if (sub.HasInfo(autofill::EMAIL_ADDRESS) && + !super.HasInfo(autofill::EMAIL_ADDRESS)) { + return false; + } + if (!HaveMergeableEmailAddresses(super, sub)) + return false; + } + return true; +} + +int PaymentsProfileComparator::GetContactCompletenessScore( + const autofill::AutofillProfile* profile) { + if (!profile) + return 0; + + return (options_.request_payer_name() && + profile->HasInfo(autofill::NAME_FULL)) + + (options_.request_payer_phone() && + profile->HasInfo(autofill::PHONE_HOME_WHOLE_NUMBER)) + + (options_.request_payer_email() && + profile->HasInfo(autofill::EMAIL_ADDRESS)); +} + +bool PaymentsProfileComparator::IsContactInfoComplete( + const autofill::AutofillProfile* profile) { + int desired_score = options_.request_payer_name() + + options_.request_payer_phone() + + options_.request_payer_email(); + return GetContactCompletenessScore(profile) == desired_score; +} + +bool PaymentsProfileComparator::IsContactMoreComplete( + const autofill::AutofillProfile* p1, + const autofill::AutofillProfile* p2) { + return GetContactCompletenessScore(p1) > GetContactCompletenessScore(p2); +} + +} // namespace profile_util +} // namespace payments
diff --git a/components/payments/core/profile_util.h b/components/payments/core/profile_util.h new file mode 100644 index 0000000..6693fe8 --- /dev/null +++ b/components/payments/core/profile_util.h
@@ -0,0 +1,69 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PAYMENTS_CONTENT_PROFILE_UTIL_H_ +#define COMPONENTS_PAYMENTS_CONTENT_PROFILE_UTIL_H_ + +#include <string> +#include <vector> + +#include "components/autofill/core/browser/autofill_profile_comparator.h" + +// Utility functions used for processing and filtering address profiles +// (AutofillProfile). + +namespace autofill { +class AutofillProfile; +} // namespace autofill + +namespace payments { + +class PaymentOptionsProvider; + +namespace profile_util { + +// Returns profiles for contact info, ordered by completeness and deduplicated. +// |profiles| should be passed in order of frecency, and this order will be +// preserved among equally-complete profiles. Deduplication here means that +// profiles returned are excluded if they are a subset of a more complete or +// more frecent profile. Completeness here refers only to the presence of the +// fields requested per the request_payer_* fields in |options|. +std::vector<autofill::AutofillProfile*> FilterProfilesForContact( + const std::vector<autofill::AutofillProfile*>& profiles, + const std::string& app_locale, + const PaymentOptionsProvider& options); + +// Helper class which evaluates profiles for similarity and completeness. +class PaymentsProfileComparator : public autofill::AutofillProfileComparator { + public: + PaymentsProfileComparator(const std::string& app_locale, + const PaymentOptionsProvider& options); + ~PaymentsProfileComparator(); + + // Returns true iff all of the contact info in |sub| also appears in |super|. + // Only operates on fields requested in |options|. + bool IsContactEqualOrSuperset(const autofill::AutofillProfile& super, + const autofill::AutofillProfile& sub); + + // Returns the number of contact fields requested in |options| which are + // nonempty in |profile|. + int GetContactCompletenessScore(const autofill::AutofillProfile* profile); + + // Returns true iff every contact field requested in |options| is nonempty in + // |profile|. + bool IsContactInfoComplete(const autofill::AutofillProfile* profile); + + // Comparison function suitable for sorting profiles by contact completeness + // score with std::sort. + bool IsContactMoreComplete(const autofill::AutofillProfile* p1, + const autofill::AutofillProfile* p2); + + private: + const PaymentOptionsProvider& options_; +}; + +} // namespace profile_util +} // namespace payments + +#endif // COMPONENTS_PAYMENTS_CONTENT_PROFILE_UTIL_H_ \ No newline at end of file
diff --git a/components/payments/core/profile_util_unittest.cc b/components/payments/core/profile_util_unittest.cc new file mode 100644 index 0000000..5ff1d7e --- /dev/null +++ b/components/payments/core/profile_util_unittest.cc
@@ -0,0 +1,231 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/payments/core/profile_util.h" + +#include <memory> +#include <vector> + +#include "base/guid.h" +#include "base/memory/ptr_util.h" +#include "base/strings/utf_string_conversions.h" +#include "components/autofill/core/browser/autofill_profile.h" +#include "components/autofill/core/browser/autofill_test_utils.h" +#include "components/payments/core/payment_options_provider.h" +#include "testing/gtest/include/gtest/gtest.h" + +using autofill::AutofillProfile; + +namespace payments { +namespace profile_util { + +constexpr uint32_t kRequestPayerName = 1 << 0; +constexpr uint32_t kRequestPayerEmail = 1 << 1; +constexpr uint32_t kRequestPayerPhone = 1 << 2; +constexpr uint32_t kRequestShipping = 1 << 3; + +class MockPaymentOptionsProvider : public PaymentOptionsProvider { + public: + MockPaymentOptionsProvider(uint32_t options) : options_(options) {} + + ~MockPaymentOptionsProvider() override {} + bool request_payer_name() const override { + return options_ & kRequestPayerName; + } + bool request_payer_email() const override { + return options_ & kRequestPayerEmail; + } + bool request_payer_phone() const override { + return options_ & kRequestPayerPhone; + } + bool request_shipping() const override { return options_ & kRequestShipping; } + PaymentShippingType shipping_type() const override { + return PaymentShippingType::SHIPPING; + } + + private: + uint32_t options_; +}; + +AutofillProfile CreateProfileWithContactInfo(const char* name, + const char* email, + const char* phone) { + AutofillProfile profile(base::GenerateGUID(), "http://www.example.com/"); + autofill::test::SetProfileInfo(&profile, name, "", "", email, "", "", "", "", + "", "", "", phone); + return profile; +} + +TEST(PaymentRequestProfileUtilTest, FilterProfilesForContact) { + // These profiles are subset/equal, so only the first complete one is + // included. + AutofillProfile exclude_1 = + CreateProfileWithContactInfo("Homer", "", "5551234567"); + + AutofillProfile exclude_2 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", ""); + + AutofillProfile include_1 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567"); + + AutofillProfile exclude_3 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567"); + + // This profile is different, so it should also be included. Since it is + // less complete than |include_1|, it will appear after. + AutofillProfile include_2 = + CreateProfileWithContactInfo("Marge", "marge@simpson.net", ""); + + // This profile is different, so it should also be included. Since it is + // equally complete with |include_1|, it will appear before |include_2|, but + // after |include_1| since order is preserved amongst profiles of equal + // completeness. + AutofillProfile include_3 = CreateProfileWithContactInfo( + "Bart", "eatmyshorts@simpson.net", "5551234567"); + + std::vector<AutofillProfile*> profiles = {&exclude_1, &exclude_2, &include_1, + &exclude_3, &include_2, &include_3}; + + MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerEmail | + kRequestPayerPhone); + std::vector<AutofillProfile*> filtered = + FilterProfilesForContact(profiles, "en-US", provider); + + ASSERT_EQ(3u, filtered.size()); + EXPECT_EQ(&include_1, filtered[0]); + EXPECT_EQ(&include_3, filtered[1]); + EXPECT_EQ(&include_2, filtered[2]); + + // Repeat the filter using a provider set to only request phone numbers. + // Under these rules, since all profiles have the same (or no) phone number, + // we should only see the first profile with a phone number, |exclude_1|. + MockPaymentOptionsProvider phone_only_provider(kRequestPayerPhone); + std::vector<AutofillProfile*> filtered_phones = + FilterProfilesForContact(profiles, "en-US", phone_only_provider); + ASSERT_EQ(1u, filtered_phones.size()); + EXPECT_EQ(&exclude_1, filtered_phones[0]); +} + +TEST(PaymentRequestProfileUtilTest, IsContactEqualOrSuperset) { + MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerEmail | + kRequestPayerPhone); + PaymentsProfileComparator comp("en-US", provider); + + AutofillProfile p1 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567"); + + // Candidate subset profile is equal. + AutofillProfile p2 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567"); + EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p2)); + EXPECT_TRUE(comp.IsContactEqualOrSuperset(p2, p1)); + + // Candidate subset profile has non-matching fields. + AutofillProfile p3 = CreateProfileWithContactInfo( + "Homer", "homer@springfieldnuclear.gov", "5551234567"); + EXPECT_FALSE(comp.IsContactEqualOrSuperset(p1, p3)); + EXPECT_FALSE(comp.IsContactEqualOrSuperset(p3, p1)); + + // Candidate subset profile is equal, except for missing fields. + AutofillProfile p4 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", ""); + EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p4)); + EXPECT_FALSE(comp.IsContactEqualOrSuperset(p4, p1)); + + // One field is common, but each has a field which the other is missing. + AutofillProfile p5 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", ""); + AutofillProfile p6 = CreateProfileWithContactInfo("Homer", "", "5551234567"); + EXPECT_FALSE(comp.IsContactEqualOrSuperset(p5, p6)); + EXPECT_FALSE(comp.IsContactEqualOrSuperset(p6, p5)); +} + +TEST(PaymentRequestProfileUtilTest, IsContactEqualOrSuperset_WithFieldIgnored) { + // Discrepancies in email should be ignored throughout this test. + MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerPhone); + PaymentsProfileComparator comp("en-US", provider); + + AutofillProfile p1 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567"); + + // Candidate subset profile is equal. + AutofillProfile p2 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567"); + EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p2)); + EXPECT_TRUE(comp.IsContactEqualOrSuperset(p2, p1)); + + // Email fields don't match, but profiles are still equal. + AutofillProfile p3 = CreateProfileWithContactInfo( + "Homer", "homer@springfieldnuclear.gov", "5551234567"); + EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p3)); + EXPECT_TRUE(comp.IsContactEqualOrSuperset(p3, p1)); + + // Profile without an email is mutual subset of profile with an email. + AutofillProfile p4 = CreateProfileWithContactInfo("Homer", "", "5551234567"); + EXPECT_TRUE(comp.IsContactEqualOrSuperset(p1, p4)); + EXPECT_TRUE(comp.IsContactEqualOrSuperset(p4, p1)); +} + +TEST(PaymentRequestProfileUtilTest, GetContactCompletenessScore) { + MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerPhone); + PaymentsProfileComparator comp("en-US", provider); + + // Two completeness points: One each for name and phone number, but not email + // as it was not requested. + AutofillProfile p1 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567"); + EXPECT_EQ(2, comp.GetContactCompletenessScore(&p1)); + + // One completeness point for name, no points for phone number (missing) or + // email (not requested). + AutofillProfile p2 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", ""); + EXPECT_EQ(1, comp.GetContactCompletenessScore(&p2)); + + // No completeness points, as the only field present was not requested. + AutofillProfile p3 = + CreateProfileWithContactInfo("", "homer@simpson.net", ""); + EXPECT_EQ(0, comp.GetContactCompletenessScore(&p3)); + + // Null profile returns 0. + EXPECT_EQ(0, comp.GetContactCompletenessScore(nullptr)); +} + +TEST(PaymentRequestProfileUtilTest, IsContactInfoComplete) { + MockPaymentOptionsProvider provider(kRequestPayerName | kRequestPayerEmail); + PaymentsProfileComparator comp("en-US", provider); + + // If name and email are present, return true regardless of the (ignored) + // phone value. + AutofillProfile p1 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", "5551234567"); + AutofillProfile p2 = + CreateProfileWithContactInfo("Homer", "homer@simpson.net", ""); + + EXPECT_TRUE(comp.IsContactInfoComplete(&p1)); + EXPECT_TRUE(comp.IsContactInfoComplete(&p2)); + + // If name is not present, return false regardless of the (ignored) + // phone value. + AutofillProfile p3 = + CreateProfileWithContactInfo("", "homer@simpson.net", "5551234567"); + AutofillProfile p4 = + CreateProfileWithContactInfo("", "homer@simpson.net", ""); + + EXPECT_FALSE(comp.IsContactInfoComplete(&p3)); + EXPECT_FALSE(comp.IsContactInfoComplete(&p4)); + + // If no fields are requested, any profile (even empty or null) is complete. + MockPaymentOptionsProvider empty_provider(0); + PaymentsProfileComparator empty_comp("en-US", empty_provider); + + AutofillProfile p5 = CreateProfileWithContactInfo("", "", ""); + + EXPECT_TRUE(empty_comp.IsContactInfoComplete(&p1)); + EXPECT_TRUE(empty_comp.IsContactInfoComplete(&p5)); + EXPECT_TRUE(empty_comp.IsContactInfoComplete(nullptr)); +} + +} // namespace profile_util +} // namespace payments
diff --git a/components/search_engines/search_engine_data_type_controller_unittest.cc b/components/search_engines/search_engine_data_type_controller_unittest.cc index 8da6343..a9c0721 100644 --- a/components/search_engines/search_engine_data_type_controller_unittest.cc +++ b/components/search_engines/search_engine_data_type_controller_unittest.cc
@@ -45,9 +45,9 @@ } // FakeSyncClient overrides. - ServiceProvider GetSyncableServiceForType(syncer::ModelType type) override { - return base::Bind(&syncer::SyncableService::AsWeakPtr, - base::Unretained(&syncable_service_)); + base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( + syncer::ModelType type) override { + return syncable_service_.AsWeakPtr(); } void TearDown() override { @@ -66,7 +66,7 @@ base::WrapUnique<syncer::GenericChangeProcessorFactory>( new syncer::FakeGenericChangeProcessorFactory( base::MakeUnique<syncer::FakeGenericChangeProcessor>( - syncer::SEARCH_ENGINES)))); + syncer::SEARCH_ENGINES, this)))); EXPECT_CALL(model_load_callback_, Run(_, _)); }
diff --git a/components/sync/driver/async_directory_type_controller.cc b/components/sync/driver/async_directory_type_controller.cc index 2030385..a821b21 100644 --- a/components/sync/driver/async_directory_type_controller.cc +++ b/components/sync/driver/async_directory_type_controller.cc
@@ -228,17 +228,12 @@ DCHECK_EQ(state(), ASSOCIATING); return PostTaskOnModelThread( FROM_HERE, - // TODO(skym): Sending a non-owning SyncApiComponentFactory pointer across - // threads is less than ideal. Likely safe because of the locking and - // disconnect flag in SharedChangeProcessor. This object is only ever used - // for dead attachments code anyways. base::Bind( &SharedChangeProcessor::StartAssociation, shared_change_processor_, BindToCurrentThread(base::Bind( &AsyncDirectoryTypeController::StartDone, base::AsWeakPtr(this))), - sync_client_->GetSyncableServiceForType(type()), - sync_client_->GetSyncApiComponentFactory(), processor_factory_.get(), - user_share_, base::Passed(CreateErrorHandler()))); + sync_client_, processor_factory_.get(), user_share_, + base::Passed(CreateErrorHandler()))); } ChangeProcessor* AsyncDirectoryTypeController::GetChangeProcessor() const {
diff --git a/components/sync/driver/async_directory_type_controller_unittest.cc b/components/sync/driver/async_directory_type_controller_unittest.cc index 2a30d034..7d21100 100644 --- a/components/sync/driver/async_directory_type_controller_unittest.cc +++ b/components/sync/driver/async_directory_type_controller_unittest.cc
@@ -66,8 +66,7 @@ : SharedChangeProcessor(type) {} base::WeakPtr<SyncableService> Connect( - const SyncClient::ServiceProvider&, - SyncApiComponentFactory* driver_factory, + SyncClient*, GenericChangeProcessorFactory*, UserShare*, std::unique_ptr<DataTypeErrorHandler>,
diff --git a/components/sync/driver/directory_data_type_controller.cc b/components/sync/driver/directory_data_type_controller.cc index 8ae2d034..a03ee3d 100644 --- a/components/sync/driver/directory_data_type_controller.cc +++ b/components/sync/driver/directory_data_type_controller.cc
@@ -62,7 +62,6 @@ void DirectoryDataTypeController::GetAllNodes( const AllNodesCallback& callback) { - DCHECK(CalledOnValidThread()); std::unique_ptr<base::ListValue> node_list = GetAllNodesForTypeFromDirectory( type(), sync_client_->GetSyncService()->GetUserShare()->directory.get()); callback.Run(type(), std::move(node_list)); @@ -70,7 +69,6 @@ void DirectoryDataTypeController::GetStatusCounters( const StatusCountersCallback& callback) { - DCHECK(CalledOnValidThread()); std::vector<int> num_entries_by_type(syncer::MODEL_TYPE_COUNT, 0); std::vector<int> num_to_delete_entries_by_type(syncer::MODEL_TYPE_COUNT, 0); sync_client_->GetSyncService()
diff --git a/components/sync/driver/directory_data_type_controller.h b/components/sync/driver/directory_data_type_controller.h index b9ad011..a521be1d 100644 --- a/components/sync/driver/directory_data_type_controller.h +++ b/components/sync/driver/directory_data_type_controller.h
@@ -73,7 +73,6 @@ // Function to capture and upload a stack trace when an error occurs. base::Closure dump_stack_; - // Non-owning pointer, should only be accessed on the UI thread. SyncClient* const sync_client_; private:
diff --git a/components/sync/driver/fake_generic_change_processor.cc b/components/sync/driver/fake_generic_change_processor.cc index 59f94d55..358b141 100644 --- a/components/sync/driver/fake_generic_change_processor.cc +++ b/components/sync/driver/fake_generic_change_processor.cc
@@ -12,13 +12,14 @@ namespace syncer { -FakeGenericChangeProcessor::FakeGenericChangeProcessor(ModelType type) +FakeGenericChangeProcessor::FakeGenericChangeProcessor(ModelType type, + SyncClient* sync_client) : GenericChangeProcessor(type, nullptr, base::WeakPtr<SyncableService>(), base::WeakPtr<SyncMergeResult>(), nullptr, - nullptr, + sync_client, nullptr), sync_model_has_user_created_nodes_(true), sync_model_has_user_created_nodes_success_(true) {} @@ -76,7 +77,7 @@ std::unique_ptr<DataTypeErrorHandler> error_handler, const base::WeakPtr<SyncableService>& local_service, const base::WeakPtr<SyncMergeResult>& merge_result, - SyncApiComponentFactory* driver_factory) { + SyncClient* sync_client) { return std::move(processor_); }
diff --git a/components/sync/driver/fake_generic_change_processor.h b/components/sync/driver/fake_generic_change_processor.h index 3518740..395d8db 100644 --- a/components/sync/driver/fake_generic_change_processor.h +++ b/components/sync/driver/fake_generic_change_processor.h
@@ -20,7 +20,7 @@ // A fake GenericChangeProcessor that can return arbitrary values. class FakeGenericChangeProcessor : public GenericChangeProcessor { public: - explicit FakeGenericChangeProcessor(ModelType type); + FakeGenericChangeProcessor(ModelType type, SyncClient* sync_client); ~FakeGenericChangeProcessor() override; // Setters for GenericChangeProcessor implementation results. @@ -53,7 +53,7 @@ std::unique_ptr<DataTypeErrorHandler> error_handler, const base::WeakPtr<SyncableService>& local_service, const base::WeakPtr<SyncMergeResult>& merge_result, - SyncApiComponentFactory* driver_factory) override; + SyncClient* sync_client) override; private: std::unique_ptr<FakeGenericChangeProcessor> processor_;
diff --git a/components/sync/driver/fake_sync_client.cc b/components/sync/driver/fake_sync_client.cc index d33b56a..8346be6 100644 --- a/components/sync/driver/fake_sync_client.cc +++ b/components/sync/driver/fake_sync_client.cc
@@ -6,25 +6,18 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" -#include "base/memory/weak_ptr.h" #include "components/sync/base/extensions_activity.h" #include "components/sync/base/sync_prefs.h" #include "components/sync/driver/fake_sync_service.h" namespace syncer { -using ServiceProvider = SyncClient::ServiceProvider; - namespace { void DummyRegisterPlatformTypesCallback(SyncService* sync_service, ModelTypeSet, ModelTypeSet) {} -base::WeakPtr<SyncableService> EmptyWeakPtr() { - return base::WeakPtr<SyncableService>(); -} - } // namespace FakeSyncClient::FakeSyncClient() @@ -108,8 +101,9 @@ return nullptr; } -ServiceProvider FakeSyncClient::GetSyncableServiceForType(ModelType type) { - return base::Bind(&EmptyWeakPtr); +base::WeakPtr<SyncableService> FakeSyncClient::GetSyncableServiceForType( + ModelType type) { + return base::WeakPtr<SyncableService>(); } base::WeakPtr<ModelTypeSyncBridge> FakeSyncClient::GetSyncBridgeForModelType(
diff --git a/components/sync/driver/fake_sync_client.h b/components/sync/driver/fake_sync_client.h index aff6d68f..aeb099e7 100644 --- a/components/sync/driver/fake_sync_client.h +++ b/components/sync/driver/fake_sync_client.h
@@ -41,7 +41,8 @@ invalidation::InvalidationService* GetInvalidationService() override; scoped_refptr<ExtensionsActivity> GetExtensionsActivity() override; sync_sessions::SyncSessionsClient* GetSyncSessionsClient() override; - ServiceProvider GetSyncableServiceForType(ModelType type) override; + base::WeakPtr<SyncableService> GetSyncableServiceForType( + ModelType type) override; base::WeakPtr<ModelTypeSyncBridge> GetSyncBridgeForModelType( ModelType type) override; scoped_refptr<ModelSafeWorker> CreateModelWorkerForGroup(
diff --git a/components/sync/driver/generic_change_processor.cc b/components/sync/driver/generic_change_processor.cc index 92244875..1dee59f 100644 --- a/components/sync/driver/generic_change_processor.cc +++ b/components/sync/driver/generic_change_processor.cc
@@ -16,6 +16,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "components/sync/base/unrecoverable_error_handler.h" #include "components/sync/driver/sync_api_component_factory.h" +#include "components/sync/driver/sync_client.h" #include "components/sync/model/local_change_observer.h" #include "components/sync/model/sync_change.h" #include "components/sync/model/sync_error.h" @@ -110,7 +111,7 @@ const base::WeakPtr<SyncableService>& local_service, const base::WeakPtr<SyncMergeResult>& merge_result, UserShare* user_share, - SyncApiComponentFactory* driver_factory, + SyncClient* sync_client, std::unique_ptr<AttachmentStoreForSync> attachment_store) : ChangeProcessor(std::move(error_handler)), type_(type), @@ -126,8 +127,10 @@ ReadTransaction trans(FROM_HERE, share_handle()); store_birthday = trans.GetStoreBirthday(); } - attachment_service_ = driver_factory->CreateAttachmentService( - std::move(attachment_store), *user_share, store_birthday, type, this); + attachment_service_ = + sync_client->GetSyncApiComponentFactory()->CreateAttachmentService( + std::move(attachment_store), *user_share, store_birthday, type, + this); attachment_service_weak_ptr_factory_ = base::MakeUnique<base::WeakPtrFactory<AttachmentService>>( attachment_service_.get());
diff --git a/components/sync/driver/generic_change_processor.h b/components/sync/driver/generic_change_processor.h index 6fa25e0..1979eef 100644 --- a/components/sync/driver/generic_change_processor.h +++ b/components/sync/driver/generic_change_processor.h
@@ -25,7 +25,7 @@ namespace syncer { -class SyncApiComponentFactory; +class SyncClient; class SyncData; class SyncableService; class WriteNode; @@ -58,7 +58,7 @@ const base::WeakPtr<SyncableService>& local_service, const base::WeakPtr<SyncMergeResult>& merge_result, UserShare* user_share, - SyncApiComponentFactory* driver_factory, + SyncClient* sync_client, std::unique_ptr<AttachmentStoreForSync> attachment_store); ~GenericChangeProcessor() override;
diff --git a/components/sync/driver/generic_change_processor_factory.cc b/components/sync/driver/generic_change_processor_factory.cc index 02ff37a1..bfb268b0 100644 --- a/components/sync/driver/generic_change_processor_factory.cc +++ b/components/sync/driver/generic_change_processor_factory.cc
@@ -23,11 +23,11 @@ std::unique_ptr<DataTypeErrorHandler> error_handler, const base::WeakPtr<SyncableService>& local_service, const base::WeakPtr<SyncMergeResult>& merge_result, - SyncApiComponentFactory* driver_factory) { + SyncClient* sync_client) { DCHECK(user_share); return base::MakeUnique<GenericChangeProcessor>( type, std::move(error_handler), local_service, merge_result, user_share, - driver_factory, local_service->GetAttachmentStoreForSync()); + sync_client, local_service->GetAttachmentStoreForSync()); } } // namespace syncer
diff --git a/components/sync/driver/generic_change_processor_factory.h b/components/sync/driver/generic_change_processor_factory.h index fbd82ad..0d9d7c3 100644 --- a/components/sync/driver/generic_change_processor_factory.h +++ b/components/sync/driver/generic_change_processor_factory.h
@@ -15,7 +15,7 @@ namespace syncer { class GenericChangeProcessor; -class SyncApiComponentFactory; +class SyncClient; class SyncMergeResult; class SyncableService; struct UserShare; @@ -39,7 +39,7 @@ std::unique_ptr<DataTypeErrorHandler> error_handler, const base::WeakPtr<SyncableService>& local_service, const base::WeakPtr<SyncMergeResult>& merge_result, - SyncApiComponentFactory* driver_factory); + SyncClient* sync_client); private: DISALLOW_COPY_AND_ASSIGN(GenericChangeProcessorFactory);
diff --git a/components/sync/driver/generic_change_processor_unittest.cc b/components/sync/driver/generic_change_processor_unittest.cc index 09045cc02..1bc4628e 100644 --- a/components/sync/driver/generic_change_processor_unittest.cc +++ b/components/sync/driver/generic_change_processor_unittest.cc
@@ -124,7 +124,8 @@ SyncGenericChangeProcessorTest() : syncable_service_ptr_factory_(&fake_syncable_service_), - mock_attachment_service_(nullptr) {} + mock_attachment_service_(nullptr), + sync_client_(&sync_factory_) {} void SetUp() override { // Use kType by default, but allow test cases to re-initialize with whatever @@ -166,7 +167,7 @@ type, base::MakeUnique<DataTypeErrorHandlerMock>(), syncable_service_ptr_factory_.GetWeakPtr(), merge_result_ptr_factory_->GetWeakPtr(), test_user_share_->user_share(), - &sync_factory_, attachment_store->CreateAttachmentStoreForSync()); + &sync_client_, attachment_store->CreateAttachmentStoreForSync()); mock_attachment_service_ = sync_factory_.GetMockAttachmentService(); } @@ -203,6 +204,7 @@ std::unique_ptr<TestUserShare> test_user_share_; MockAttachmentService* mock_attachment_service_; + FakeSyncClient sync_client_; MockSyncApiComponentFactory sync_factory_; std::unique_ptr<GenericChangeProcessor> change_processor_;
diff --git a/components/sync/driver/shared_change_processor.cc b/components/sync/driver/shared_change_processor.cc index 1a5ae11..6e473b5c 100644 --- a/components/sync/driver/shared_change_processor.cc +++ b/components/sync/driver/shared_change_processor.cc
@@ -12,6 +12,7 @@ #include "components/sync/driver/generic_change_processor.h" #include "components/sync/driver/generic_change_processor_factory.h" #include "components/sync/driver/shared_change_processor_ref.h" +#include "components/sync/driver/sync_client.h" #include "components/sync/model/sync_change.h" #include "components/sync/model/syncable_service.h" @@ -50,9 +51,8 @@ } void SharedChangeProcessor::StartAssociation( - const StartDoneCallback& start_done, - const SyncClient::ServiceProvider& service_provider, - SyncApiComponentFactory* driver_factory, + StartDoneCallback start_done, + SyncClient* const sync_client, GenericChangeProcessorFactory* processor_factory, UserShare* user_share, std::unique_ptr<DataTypeErrorHandler> error_handler) { @@ -67,7 +67,7 @@ // disconnected at this point, so all our accesses to the syncer from this // point on are through it. local_service_ = - Connect(service_provider, driver_factory, processor_factory, user_share, + Connect(sync_client, processor_factory, user_share, std::move(error_handler), weak_ptr_factory.GetWeakPtr()); if (!local_service_.get()) { SyncError error(FROM_HERE, SyncError::DATATYPE_ERROR, @@ -139,31 +139,31 @@ } base::WeakPtr<SyncableService> SharedChangeProcessor::Connect( - const SyncClient::ServiceProvider& service_provider, - SyncApiComponentFactory* driver_factory, + SyncClient* sync_client, GenericChangeProcessorFactory* processor_factory, UserShare* user_share, std::unique_ptr<DataTypeErrorHandler> error_handler, const base::WeakPtr<SyncMergeResult>& merge_result) { + DCHECK(sync_client); DCHECK(error_handler); backend_task_runner_ = base::SequencedTaskRunnerHandle::Get(); AutoLock lock(monitor_lock_); if (disconnected_) return base::WeakPtr<SyncableService>(); error_handler_ = std::move(error_handler); - base::WeakPtr<SyncableService> local_service = service_provider.Run(); + base::WeakPtr<SyncableService> local_service = + sync_client->GetSyncableServiceForType(type_); if (!local_service.get()) { LOG(WARNING) << "SyncableService destroyed before DTC was stopped."; disconnected_ = true; return base::WeakPtr<SyncableService>(); } - generic_change_processor_ = - processor_factory - ->CreateGenericChangeProcessor(type_, user_share, - error_handler_->Copy(), local_service, - merge_result, driver_factory) - .release(); + generic_change_processor_ = processor_factory + ->CreateGenericChangeProcessor( + type_, user_share, error_handler_->Copy(), + local_service, merge_result, sync_client) + .release(); // If available, propagate attachment service to the syncable service. std::unique_ptr<AttachmentService> attachment_service = generic_change_processor_->GetAttachmentService();
diff --git a/components/sync/driver/shared_change_processor.h b/components/sync/driver/shared_change_processor.h index 05755f8..280ad5e 100644 --- a/components/sync/driver/shared_change_processor.h +++ b/components/sync/driver/shared_change_processor.h
@@ -16,7 +16,6 @@ #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" #include "components/sync/driver/data_type_controller.h" -#include "components/sync/driver/sync_client.h" #include "components/sync/engine/model_safe_worker.h" #include "components/sync/model/data_type_error_handler.h" #include "components/sync/model/sync_change_processor.h" @@ -30,7 +29,7 @@ class ChangeProcessor; class GenericChangeProcessor; class GenericChangeProcessorFactory; -class SyncApiComponentFactory; +class SyncClient; class SyncableService; struct UserShare; @@ -62,9 +61,8 @@ // Create an uninitialized SharedChangeProcessor. explicit SharedChangeProcessor(ModelType type); - void StartAssociation(const StartDoneCallback& start_done, - const SyncClient::ServiceProvider& service_provider, - SyncApiComponentFactory* driver_factory, + void StartAssociation(StartDoneCallback start_done, + SyncClient* const sync_client, GenericChangeProcessorFactory* processor_factory, UserShare* user_share, std::unique_ptr<DataTypeErrorHandler> error_handler); @@ -73,10 +71,9 @@ // create and store a new GenericChangeProcessor and return a weak pointer to // the SyncableService associated with |type|. // Note: If this SharedChangeProcessor has been disconnected, or the - // SyncableService is not alive, will return a null weak pointer. + // SyncableService was not alive, will return a null weak pointer. virtual base::WeakPtr<SyncableService> Connect( - const SyncClient::ServiceProvider& service_provider, - SyncApiComponentFactory* driver_factory, + SyncClient* sync_client, GenericChangeProcessorFactory* processor_factory, UserShare* user_share, std::unique_ptr<DataTypeErrorHandler> error_handler,
diff --git a/components/sync/driver/shared_change_processor_unittest.cc b/components/sync/driver/shared_change_processor_unittest.cc index 410b8dc..b6494049 100644 --- a/components/sync/driver/shared_change_processor_unittest.cc +++ b/components/sync/driver/shared_change_processor_unittest.cc
@@ -91,9 +91,9 @@ } // FakeSyncClient override. - ServiceProvider GetSyncableServiceForType(ModelType type) override { - return base::Bind(&SyncableService::AsWeakPtr, - base::Unretained(db_syncable_service_.get())); + base::WeakPtr<SyncableService> GetSyncableServiceForType( + ModelType type) override { + return db_syncable_service_->AsWeakPtr(); } protected: @@ -185,8 +185,7 @@ const scoped_refptr<SharedChangeProcessor>& shared_change_processor) { DCHECK(model_thread_.task_runner()->BelongsToCurrentThread()); EXPECT_TRUE(shared_change_processor->Connect( - GetSyncableServiceForType(AUTOFILL), &factory_, &processor_factory_, - test_user_share_.user_share(), + this, &processor_factory_, test_user_share_.user_share(), base::MakeUnique<DataTypeErrorHandlerMock>(), base::WeakPtr<SyncMergeResult>())); did_connect_ = true;
diff --git a/components/sync/driver/sync_client.h b/components/sync/driver/sync_client.h index c0030b4c..ddf64d8 100644 --- a/components/sync/driver/sync_client.h +++ b/components/sync/driver/sync_client.h
@@ -59,8 +59,6 @@ // to handle these scenarios gracefully. class SyncClient { public: - using ServiceProvider = base::Callback<base::WeakPtr<SyncableService>()>; - SyncClient(); virtual ~SyncClient(); @@ -102,10 +100,11 @@ virtual scoped_refptr<ExtensionsActivity> GetExtensionsActivity() = 0; virtual sync_sessions::SyncSessionsClient* GetSyncSessionsClient() = 0; - // Returns a callback to retrieve a syncable service specified by |type|. - // Both the provider and the resulting weak pointer will only be accessed on - // the model thread. - virtual ServiceProvider GetSyncableServiceForType(ModelType type) = 0; + // Returns a weak pointer to the syncable service specified by |type|. + // Weak pointer may be unset if service is already destroyed. + // Note: Should only be dereferenced from the model type thread. + virtual base::WeakPtr<SyncableService> GetSyncableServiceForType( + ModelType type) = 0; // Returns a weak pointer to the ModelTypeSyncBridge specified by |type|. Weak // pointer may be unset if service is already destroyed.
diff --git a/components/viz/DEPS b/components/viz/DEPS new file mode 100644 index 0000000..f8654e9ef --- /dev/null +++ b/components/viz/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+gpu", + "+mojo/public", +]
diff --git a/components/viz/frame_sinks/BUILD.gn b/components/viz/frame_sinks/BUILD.gn new file mode 100644 index 0000000..750e684 --- /dev/null +++ b/components/viz/frame_sinks/BUILD.gn
@@ -0,0 +1,25 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("frame_sinks") { + sources = [ + "display_provider.h", + "gpu_compositor_frame_sink.cc", + "gpu_compositor_frame_sink.h", + "gpu_compositor_frame_sink_delegate.h", + "gpu_root_compositor_frame_sink.cc", + "gpu_root_compositor_frame_sink.h", + "mojo_frame_sink_manager.cc", + "mojo_frame_sink_manager.h", + ] + + deps = [ + "//base", + "//cc", + "//cc/ipc:interfaces", + "//cc/surfaces", + "//components/display_compositor", + "//gpu/ipc:command_buffer", + ] +}
diff --git a/components/viz/frame_sinks/DEPS b/components/viz/frame_sinks/DEPS new file mode 100644 index 0000000..fc0222f --- /dev/null +++ b/components/viz/frame_sinks/DEPS
@@ -0,0 +1,6 @@ +include_rules = [ + "+cc/base", + "+cc/ipc", + "+cc/surfaces", + "+cc/scheduler", +]
diff --git a/services/ui/surfaces/display_provider.h b/components/viz/frame_sinks/display_provider.h similarity index 79% rename from services/ui/surfaces/display_provider.h rename to components/viz/frame_sinks/display_provider.h index 7be3f66..de6127b 100644 --- a/services/ui/surfaces/display_provider.h +++ b/components/viz/frame_sinks/display_provider.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SERVICES_UI_SURFACES_DISPLAY_PROVIDER_H_ -#define SERVICES_UI_SURFACES_DISPLAY_PROVIDER_H_ +#ifndef COMPONENTS_VIZ_FRAME_SINKS_DISPLAY_PROVIDER_H_ +#define COMPONENTS_VIZ_FRAME_SINKS_DISPLAY_PROVIDER_H_ #include <memory> @@ -15,7 +15,7 @@ class FrameSinkId; } -namespace ui { +namespace viz { // Handles creating new cc::Displays and related classes for // MojoFrameSinkManager. @@ -31,6 +31,6 @@ std::unique_ptr<cc::BeginFrameSource>* begin_frame_source) = 0; }; -} // namespace ui +} // namespace viz -#endif // SERVICES_UI_SURFACES_DISPLAY_PROVIDER_H_ +#endif // COMPONENTS_VIZ_FRAME_SINKS_DISPLAY_PROVIDER_H_
diff --git a/components/display_compositor/gpu_compositor_frame_sink.cc b/components/viz/frame_sinks/gpu_compositor_frame_sink.cc similarity index 95% rename from components/display_compositor/gpu_compositor_frame_sink.cc rename to components/viz/frame_sinks/gpu_compositor_frame_sink.cc index 95fc477..ffa80a8f 100644 --- a/components/display_compositor/gpu_compositor_frame_sink.cc +++ b/components/viz/frame_sinks/gpu_compositor_frame_sink.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/display_compositor/gpu_compositor_frame_sink.h" +#include "components/viz/frame_sinks/gpu_compositor_frame_sink.h" -namespace display_compositor { +namespace viz { GpuCompositorFrameSink::GpuCompositorFrameSink( GpuCompositorFrameSinkDelegate* delegate, @@ -102,4 +102,4 @@ client_connection_lost_); } -} // namespace display_compositor +} // namespace viz
diff --git a/components/display_compositor/gpu_compositor_frame_sink.h b/components/viz/frame_sinks/gpu_compositor_frame_sink.h similarity index 85% rename from components/display_compositor/gpu_compositor_frame_sink.h rename to components/viz/frame_sinks/gpu_compositor_frame_sink.h index bc2c9f55..5eac021 100644 --- a/components/display_compositor/gpu_compositor_frame_sink.h +++ b/components/viz/frame_sinks/gpu_compositor_frame_sink.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_DISPLAY_COMPOSITOR_GPU_COMPOSITOR_FRAME_SINK_H_ -#define COMPONENTS_DISPLAY_COMPOSITOR_GPU_COMPOSITOR_FRAME_SINK_H_ +#ifndef COMPONENTS_VIZ_FRAME_SINKS_GPU_COMPOSITOR_FRAME_SINK_H_ +#define COMPONENTS_VIZ_FRAME_SINKS_GPU_COMPOSITOR_FRAME_SINK_H_ #include <memory> #include <vector> @@ -15,14 +15,13 @@ #include "cc/surfaces/compositor_frame_sink_support_client.h" #include "cc/surfaces/local_surface_id.h" #include "cc/surfaces/surface_id.h" -#include "components/display_compositor/display_compositor_export.h" -#include "components/display_compositor/gpu_compositor_frame_sink_delegate.h" +#include "components/viz/frame_sinks/gpu_compositor_frame_sink_delegate.h" #include "mojo/public/cpp/bindings/binding.h" -namespace display_compositor { +namespace viz { // Server side representation of a WindowSurface. -class DISPLAY_COMPOSITOR_EXPORT GpuCompositorFrameSink +class GpuCompositorFrameSink : public NON_EXPORTED_BASE(cc::CompositorFrameSinkSupportClient), public NON_EXPORTED_BASE(cc::mojom::MojoCompositorFrameSink), public NON_EXPORTED_BASE(cc::mojom::MojoCompositorFrameSinkPrivate) { @@ -75,6 +74,6 @@ DISALLOW_COPY_AND_ASSIGN(GpuCompositorFrameSink); }; -} // namespace display_compositor +} // namespace viz -#endif // COMPONENTS_DISPLAY_COMPOSITOR_GPU_COMPOSITOR_FRAME_SINK_H_ +#endif // COMPONENTS_VIZ_FRAME_SINKS_GPU_COMPOSITOR_FRAME_SINK_H_
diff --git a/components/display_compositor/gpu_compositor_frame_sink_delegate.h b/components/viz/frame_sinks/gpu_compositor_frame_sink_delegate.h similarity index 74% rename from components/display_compositor/gpu_compositor_frame_sink_delegate.h rename to components/viz/frame_sinks/gpu_compositor_frame_sink_delegate.h index e1c4382..d9d45ae2 100644 --- a/components/display_compositor/gpu_compositor_frame_sink_delegate.h +++ b/components/viz/frame_sinks/gpu_compositor_frame_sink_delegate.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_DISPLAY_COMPOSITOR_GPU_COMPOSITOR_FRAME_SINK_DELEGATE_H_ -#define COMPONENTS_DISPLAY_COMPOSITOR_GPU_COMPOSITOR_FRAME_SINK_DELEGATE_H_ +#ifndef COMPONENTS_VIZ_FRAME_SINKS_GPU_COMPOSITOR_FRAME_SINK_DELEGATE_H_ +#define COMPONENTS_VIZ_FRAME_SINKS_GPU_COMPOSITOR_FRAME_SINK_DELEGATE_H_ namespace cc { class FrameSinkId; } -namespace display_compositor { +namespace viz { class GpuCompositorFrameSinkDelegate { public: @@ -25,6 +25,6 @@ virtual ~GpuCompositorFrameSinkDelegate() {} }; -} // namespace display_compositor +} // namespace viz -#endif // COMPONENTS_DISPLAY_COMPOSITOR_GPU_COMPOSITOR_FRAME_SINK_DELEGATE_H_ +#endif // COMPONENTS_VIZ_FRAME_SINKS_GPU_COMPOSITOR_FRAME_SINK_DELEGATE_H_
diff --git a/components/display_compositor/gpu_root_compositor_frame_sink.cc b/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc similarity index 97% rename from components/display_compositor/gpu_root_compositor_frame_sink.cc rename to components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc index 932096d..ec22fa2 100644 --- a/components/display_compositor/gpu_root_compositor_frame_sink.cc +++ b/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/display_compositor/gpu_root_compositor_frame_sink.h" +#include "components/viz/frame_sinks/gpu_root_compositor_frame_sink.h" #include "cc/surfaces/compositor_frame_sink_support.h" #include "cc/surfaces/display.h" -namespace display_compositor { +namespace viz { GpuRootCompositorFrameSink::GpuRootCompositorFrameSink( GpuCompositorFrameSinkDelegate* delegate, @@ -152,4 +152,4 @@ client_connection_lost_); } -} // namespace display_compositor +} // namespace viz
diff --git a/components/display_compositor/gpu_root_compositor_frame_sink.h b/components/viz/frame_sinks/gpu_root_compositor_frame_sink.h similarity index 89% rename from components/display_compositor/gpu_root_compositor_frame_sink.h rename to components/viz/frame_sinks/gpu_root_compositor_frame_sink.h index 2b1e415..563ac10 100644 --- a/components/display_compositor/gpu_root_compositor_frame_sink.h +++ b/components/viz/frame_sinks/gpu_root_compositor_frame_sink.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_DISPLAY_COMPOSITOR_GPU_ROOT_COMPOSITOR_FRAME_SINK_H_ -#define COMPONENTS_DISPLAY_COMPOSITOR_GPU_ROOT_COMPOSITOR_FRAME_SINK_H_ +#ifndef COMPONENTS_VIZ_FRAME_SINKS_GPU_ROOT_COMPOSITOR_FRAME_SINK_H_ +#define COMPONENTS_VIZ_FRAME_SINKS_GPU_ROOT_COMPOSITOR_FRAME_SINK_H_ #include "cc/ipc/frame_sink_manager.mojom.h" #include "cc/ipc/mojo_compositor_frame_sink.mojom.h" @@ -11,8 +11,7 @@ #include "cc/surfaces/display_client.h" #include "cc/surfaces/local_surface_id.h" #include "cc/surfaces/surface_id.h" -#include "components/display_compositor/display_compositor_export.h" -#include "components/display_compositor/gpu_compositor_frame_sink_delegate.h" +#include "components/viz/frame_sinks/gpu_compositor_frame_sink_delegate.h" #include "mojo/public/cpp/bindings/associated_binding.h" #include "mojo/public/cpp/bindings/binding.h" @@ -23,11 +22,11 @@ class SurfaceManager; } -namespace display_compositor { +namespace viz { class GpuCompositorFrameSinkDelegate; -class DISPLAY_COMPOSITOR_EXPORT GpuRootCompositorFrameSink +class GpuRootCompositorFrameSink : public NON_EXPORTED_BASE(cc::CompositorFrameSinkSupportClient), public NON_EXPORTED_BASE(cc::mojom::MojoCompositorFrameSink), public NON_EXPORTED_BASE(cc::mojom::MojoCompositorFrameSinkPrivate), @@ -105,6 +104,6 @@ DISALLOW_COPY_AND_ASSIGN(GpuRootCompositorFrameSink); }; -} // namespace display_compositor +} // namespace viz -#endif // COMPONENTS_DISPLAY_COMPOSITOR_GPU_ROOT_COMPOSITOR_FRAME_SINK_H_ +#endif // COMPONENTS_VIZ_FRAME_SINKS_GPU_ROOT_COMPOSITOR_FRAME_SINK_H_
diff --git a/services/ui/surfaces/mojo_frame_sink_manager.cc b/components/viz/frame_sinks/mojo_frame_sink_manager.cc similarity index 92% rename from services/ui/surfaces/mojo_frame_sink_manager.cc rename to components/viz/frame_sinks/mojo_frame_sink_manager.cc index 5595fb5..e3ede34 100644 --- a/services/ui/surfaces/mojo_frame_sink_manager.cc +++ b/components/viz/frame_sinks/mojo_frame_sink_manager.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "services/ui/surfaces/mojo_frame_sink_manager.h" +#include "components/viz/frame_sinks/mojo_frame_sink_manager.h" #include <utility> @@ -12,11 +12,11 @@ #include "cc/scheduler/begin_frame_source.h" #include "cc/surfaces/display.h" #include "cc/surfaces/surface_dependency_tracker.h" -#include "components/display_compositor/gpu_compositor_frame_sink.h" -#include "components/display_compositor/gpu_root_compositor_frame_sink.h" -#include "services/ui/surfaces/display_provider.h" +#include "components/viz/frame_sinks/display_provider.h" +#include "components/viz/frame_sinks/gpu_compositor_frame_sink.h" +#include "components/viz/frame_sinks/gpu_root_compositor_frame_sink.h" -namespace ui { +namespace viz { MojoFrameSinkManager::MojoFrameSinkManager( DisplayProvider* display_provider, @@ -61,7 +61,7 @@ } compositor_frame_sinks_[frame_sink_id] = - base::MakeUnique<display_compositor::GpuRootCompositorFrameSink>( + base::MakeUnique<GpuRootCompositorFrameSink>( this, &manager_, frame_sink_id, std::move(display), std::move(begin_frame_source), std::move(request), std::move(private_request), std::move(client), @@ -77,7 +77,7 @@ DCHECK_EQ(0u, compositor_frame_sinks_.count(frame_sink_id)); compositor_frame_sinks_[frame_sink_id] = - base::MakeUnique<display_compositor::GpuCompositorFrameSink>( + base::MakeUnique<GpuCompositorFrameSink>( this, &manager_, frame_sink_id, std::move(request), std::move(private_request), std::move(client)); } @@ -141,4 +141,4 @@ DestroyCompositorFrameSink(frame_sink_id); } -} // namespace ui +} // namespace viz
diff --git a/services/ui/surfaces/mojo_frame_sink_manager.h b/components/viz/frame_sinks/mojo_frame_sink_manager.h similarity index 87% rename from services/ui/surfaces/mojo_frame_sink_manager.h rename to components/viz/frame_sinks/mojo_frame_sink_manager.h index cf83182..fc33393c 100644 --- a/services/ui/surfaces/mojo_frame_sink_manager.h +++ b/components/viz/frame_sinks/mojo_frame_sink_manager.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SERVICES_UI_SURFACES_MOJO_FRAME_SINK_MANAGER_H_ -#define SERVICES_UI_SURFACES_MOJO_FRAME_SINK_MANAGER_H_ +#ifndef COMPONENTS_VIZ_FRAME_SINKS_MOJO_FRAME_SINK_MANAGER_H_ +#define COMPONENTS_VIZ_FRAME_SINKS_MOJO_FRAME_SINK_MANAGER_H_ #include <stdint.h> @@ -16,11 +16,11 @@ #include "cc/surfaces/frame_sink_id.h" #include "cc/surfaces/surface_manager.h" #include "cc/surfaces/surface_observer.h" -#include "components/display_compositor/gpu_compositor_frame_sink_delegate.h" +#include "components/viz/frame_sinks/gpu_compositor_frame_sink_delegate.h" #include "gpu/ipc/common/surface_handle.h" #include "mojo/public/cpp/bindings/binding.h" -namespace ui { +namespace viz { class DisplayProvider; @@ -32,10 +32,9 @@ // will be true after the mus process split. For non-mus Chrome this will be // created in the browser process, at least until GPU implementations can be // unified. -class MojoFrameSinkManager - : public cc::SurfaceObserver, - public display_compositor::GpuCompositorFrameSinkDelegate, - public cc::mojom::FrameSinkManager { +class MojoFrameSinkManager : public cc::SurfaceObserver, + public GpuCompositorFrameSinkDelegate, + public cc::mojom::FrameSinkManager { public: MojoFrameSinkManager(DisplayProvider* display_provider, cc::mojom::FrameSinkManagerRequest request, @@ -79,7 +78,7 @@ void OnSurfaceDamaged(const cc::SurfaceId& surface_id, bool* changed) override; - // display_compositor::GpuCompositorFrameSinkDelegate implementation. + // GpuCompositorFrameSinkDelegate implementation. void OnClientConnectionLost(const cc::FrameSinkId& frame_sink_id, bool destroy_compositor_frame_sink) override; void OnPrivateConnectionLost(const cc::FrameSinkId& frame_sink_id, @@ -106,6 +105,6 @@ DISALLOW_COPY_AND_ASSIGN(MojoFrameSinkManager); }; -} // namespace ui +} // namespace viz -#endif // SERVICES_UI_SURFACES_MOJO_FRAME_SINK_MANAGER_H_ +#endif // COMPONENTS_VIZ_FRAME_SINKS_MOJO_FRAME_SINK_MANAGER_H_
diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc index 56d2023..7b541e7 100644 --- a/content/browser/ppapi_plugin_process_host.cc +++ b/content/browser/ppapi_plugin_process_host.cc
@@ -33,7 +33,6 @@ #include "content/public/common/sandbox_type.h" #include "content/public/common/sandboxed_process_launcher_delegate.h" #include "content/public/common/service_names.mojom.h" -#include "media/base/media_switches.h" #include "mojo/edk/embedder/embedder.h" #include "net/base/network_change_notifier.h" #include "ppapi/proxy/ppapi_messages.h" @@ -400,8 +399,6 @@ #if defined(OS_MACOSX) switches::kEnableSandboxLogging, #endif - // Need to tell CdmHostFile(s) to ignore missing CDM host files. - switches::kIgnoreMissingCdmHostFile, switches::kNoSandbox, switches::kPpapiStartupDialog, };
diff --git a/content/browser/renderer_host/input/input_router_impl_unittest.cc b/content/browser/renderer_host/input/input_router_impl_unittest.cc index 9beba61..ab450357 100644 --- a/content/browser/renderer_host/input/input_router_impl_unittest.cc +++ b/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -151,13 +151,25 @@ class InputRouterImplTest : public testing::Test { public: - InputRouterImplTest(bool raf_aligned_touch = true) { - if (raf_aligned_touch) { - feature_list_.InitFromCommandLine( - features::kRafAlignedTouchInputEvents.name, ""); - } else { - feature_list_.InitFromCommandLine( - "", features::kRafAlignedTouchInputEvents.name); + InputRouterImplTest(bool raf_aligned_touch = true, + bool wheel_scroll_latching = true) { + if (raf_aligned_touch && wheel_scroll_latching) { + feature_list_.InitWithFeatures( + {features::kRafAlignedTouchInputEvents, + features::kTouchpadAndWheelScrollLatching}, + {}); + } else if (raf_aligned_touch && !wheel_scroll_latching) { + feature_list_.InitWithFeatures( + {features::kRafAlignedTouchInputEvents}, + {features::kTouchpadAndWheelScrollLatching}); + } else if (!raf_aligned_touch && wheel_scroll_latching) { + feature_list_.InitWithFeatures( + {features::kTouchpadAndWheelScrollLatching}, + {features::kRafAlignedTouchInputEvents}); + } else { // !raf_aligned_touch && !wheel_scroll_latching + feature_list_.InitWithFeatures( + {}, {features::kRafAlignedTouchInputEvents, + features::kTouchpadAndWheelScrollLatching}); } } @@ -370,6 +382,77 @@ base::RunLoop().Run(); } + void UnhandledWheelEvent(bool wheel_scroll_latching_enabled) { + // Simulate wheel events. + SimulateWheelEvent(0, 0, 0, -5, 0, false); // sent directly + SimulateWheelEvent(0, 0, 0, -10, 0, false); // enqueued + + // Check that only the first event was sent. + EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( + InputMsg_HandleInputEvent::ID)); + EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + + // Indicate that the wheel event was unhandled. + SendInputEventACK(WebInputEvent::MouseWheel, + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + + // Check that the ack for the MouseWheel and ScrollBegin + // were processed. + EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount()); + + // There should be a ScrollBegin and ScrollUpdate, MouseWheel sent. + EXPECT_EQ(3U, GetSentMessageCountAndResetSink()); + + EXPECT_EQ(ack_handler_->acked_wheel_event().deltaY, -5); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, + INPUT_EVENT_ACK_STATE_CONSUMED); + + if (wheel_scroll_latching_enabled) { + // Check that the ack for ScrollUpdate were processed. + EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount()); + } else { + // The GestureScrollUpdate ACK releases the GestureScrollEnd. + EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + + // Check that the ack for the ScrollUpdate and ScrollEnd + // were processed. + EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount()); + } + + SendInputEventACK(WebInputEvent::MouseWheel, + INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + + if (wheel_scroll_latching_enabled) { + // There should be a ScrollUpdate sent. + EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount()); + } else { + // There should be a ScrollBegin and ScrollUpdate sent. + EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount()); + } + + // Check that the correct unhandled wheel event was received. + EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, + ack_handler_->acked_wheel_event_state()); + EXPECT_EQ(ack_handler_->acked_wheel_event().deltaY, -10); + + SendInputEventACK(WebInputEvent::GestureScrollUpdate, + INPUT_EVENT_ACK_STATE_CONSUMED); + + if (wheel_scroll_latching_enabled) { + // Check that the ack for ScrollUpdate were processed. + EXPECT_EQ(1U, ack_handler_->GetAndResetAckCount()); + } else { + // The GestureScrollUpdate ACK releases the GestureScrollEnd. + EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + + // Check that the ack for the ScrollUpdate and ScrollEnd + // were processed. + EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount()); + } + } + InputRouterImpl::Config config_; std::unique_ptr<MockRenderProcessHost> process_; std::unique_ptr<MockInputRouterClient> client_; @@ -386,7 +469,15 @@ class InputRouterImplRafAlignedTouchDisabledTest : public InputRouterImplTest { public: - InputRouterImplRafAlignedTouchDisabledTest() : InputRouterImplTest(false) {} + InputRouterImplRafAlignedTouchDisabledTest() + : InputRouterImplTest(false, false) {} +}; + +class InputRouterImplWheelScrollLatchingDisabledTest + : public InputRouterImplTest { + public: + InputRouterImplWheelScrollLatchingDisabledTest() + : InputRouterImplTest(true, false) {} }; TEST_F(InputRouterImplTest, CoalescesRangeSelection) { @@ -1008,59 +1099,12 @@ } #endif // defined(USE_AURA) -TEST_F(InputRouterImplTest, UnhandledWheelEvent) { - // Simulate wheel events. - SimulateWheelEvent(0, 0, 0, -5, 0, false); // sent directly - SimulateWheelEvent(0, 0, 0, -10, 0, false); // enqueued - - // Check that only the first event was sent. - EXPECT_TRUE( - process_->sink().GetUniqueMessageMatching(InputMsg_HandleInputEvent::ID)); - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); - - // Indicate that the wheel event was unhandled. - SendInputEventACK(WebInputEvent::MouseWheel, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - - // Check that the ack for the MouseWheel and ScrollBegin - // were processed. - EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount()); - - // There should be a ScrollBegin and ScrollUpdate, MouseWheel sent. - EXPECT_EQ(3U, GetSentMessageCountAndResetSink()); - - EXPECT_EQ(ack_handler_->acked_wheel_event().deltaY, -5); - SendInputEventACK(WebInputEvent::GestureScrollUpdate, - INPUT_EVENT_ACK_STATE_CONSUMED); - - // The GestureScrollUpdate ACK releases the GestureScrollEnd. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); - - // Check that the ack for the ScrollUpdate and ScrollEnd - // were processed. - EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount()); - - SendInputEventACK(WebInputEvent::MouseWheel, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - - // There should be a ScrollBegin and ScrollUpdate sent. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); - - // Check that the correct unhandled wheel event was received. - EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount()); - EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, - ack_handler_->acked_wheel_event_state()); - EXPECT_EQ(ack_handler_->acked_wheel_event().deltaY, -10); - - SendInputEventACK(WebInputEvent::GestureScrollUpdate, - INPUT_EVENT_ACK_STATE_CONSUMED); - - // The GestureScrollUpdate ACK releases the GestureScrollEnd. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); - - // Check that the ack for the ScrollUpdate and ScrollEnd - // were processed. - EXPECT_EQ(2U, ack_handler_->GetAndResetAckCount()); +TEST_F(InputRouterImplTest, UnhandledWheelEventWithoutLatching) { + UnhandledWheelEvent(true); +} +TEST_F(InputRouterImplWheelScrollLatchingDisabledTest, + UnhandledWheelEventWithLatching) { + UnhandledWheelEvent(false); } TEST_F(InputRouterImplTest, TouchTypesIgnoringAck) {
diff --git a/content/browser/renderer_host/media/video_capture_browsertest.cc b/content/browser/renderer_host/media/video_capture_browsertest.cc index 329ee537..19ce4c6 100644 --- a/content/browser/renderer_host/media/video_capture_browsertest.cc +++ b/content/browser/renderer_host/media/video_capture_browsertest.cc
@@ -194,6 +194,13 @@ IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, ReceiveFramesFromFakeCaptureDevice) { +// TODO(chfremer): This test case is flaky on Android. Find out cause of +// flakiness and then re-enable. See crbug.com/709039. +#if defined(OS_ANDROID) + if (GetParam().exercise_accelerated_jpeg_decoding) + return; +#endif + SetUpRequiringBrowserMainLoopOnMainThread(); std::vector<FrameInfo> received_frame_infos;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index ede70ada..7ac964e 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1855,7 +1855,6 @@ switches::kDisableLowEndDeviceMode, #if defined(OS_ANDROID) switches::kDisableMediaSessionAPI, - switches::kEnableContentIntentDetection, switches::kRendererWaitForJavaDebugger, #endif #if defined(OS_MACOSX)
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 9271b5c..09711bf 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1799,11 +1799,12 @@ &window_snapshot_component)) { int sequence_number = static_cast<int>(window_snapshot_component.sequence_number); -#if defined(OS_MACOSX) - // On Mac, when using CoreAnimation, there is a delay between when content - // is drawn to the screen, and when the snapshot will actually pick up - // that content. Insert a manual delay of 1/6th of a second (to simulate - // 10 frames at 60 fps) before actually taking the snapshot. +#if defined(OS_MACOSX) || defined(OS_WIN) + // On Mac, when using CoreAnimation, or Win32 when using GDI, there is a + // delay between when content is drawn to the screen, and when the + // snapshot will actually pick up that content. Insert a manual delay of + // 1/6th of a second (to simulate 10 frames at 60 fps) before actually + // taking the snapshot. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::Bind(&RenderWidgetHostImpl::WindowSnapshotReachedScreen,
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 b935705..179378e 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -516,7 +516,6 @@ } bool handled = true; IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message) - IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent) IPC_MESSAGE_HANDLER(ViewHostMsg_ShowUnhandledTapUIIfNeeded, OnShowUnhandledTapUIIfNeeded) IPC_MESSAGE_UNHANDLED(handled = false) @@ -910,11 +909,6 @@ return weak_ptr_factory_.GetWeakPtr(); } -void RenderWidgetHostViewAndroid::OnStartContentIntent( - const GURL& content_url, bool is_main_frame) { - view_.StartContentIntent(content_url, is_main_frame); -} - bool RenderWidgetHostViewAndroid::OnTouchEvent( const ui::MotionEvent& event) { if (!host_ || !host_->delegate())
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 a1492ec2..af1f00a5d 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -41,8 +41,6 @@ #include "ui/gfx/selection_bound.h" #include "ui/touch_selection/touch_selection_controller.h" -class GURL; - namespace ui { class MotionEventAndroid; struct DidOverscrollParams; @@ -233,8 +231,6 @@ base::WeakPtr<RenderWidgetHostViewAndroid> GetWeakPtrAndroid(); - void OnStartContentIntent(const GURL& content_url, bool is_main_frame); - bool OnTouchEvent(const ui::MotionEvent& event); bool OnTouchHandleEvent(const ui::MotionEvent& event); void ResetGestureDetection();
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index 60aed740..0f4ca71 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -719,6 +719,27 @@ "", features::kRafAlignedTouchInputEvents.name); } + void SetFeatureList(bool raf_aligned_touch, bool wheel_scroll_latching) { + if (raf_aligned_touch && wheel_scroll_latching) { + feature_list_.InitWithFeatures( + {features::kRafAlignedTouchInputEvents, + features::kTouchpadAndWheelScrollLatching}, + {}); + } else if (raf_aligned_touch && !wheel_scroll_latching) { + feature_list_.InitWithFeatures( + {features::kRafAlignedTouchInputEvents}, + {features::kTouchpadAndWheelScrollLatching}); + } else if (!raf_aligned_touch && wheel_scroll_latching) { + feature_list_.InitWithFeatures( + {features::kTouchpadAndWheelScrollLatching}, + {features::kRafAlignedTouchInputEvents}); + } else { // !raf_aligned_touch && !wheel_scroll_latching + feature_list_.InitWithFeatures( + {}, {features::kRafAlignedTouchInputEvents, + features::kTouchpadAndWheelScrollLatching}); + } + } + protected: BrowserContext* browser_context() { return browser_context_.get(); } @@ -847,7 +868,9 @@ class RenderWidgetHostViewAuraOverscrollTest : public RenderWidgetHostViewAuraTest { public: - RenderWidgetHostViewAuraOverscrollTest() {} + RenderWidgetHostViewAuraOverscrollTest( + bool wheel_scroll_latching_enabled = true) + : wheel_scroll_latching_enabled_(wheel_scroll_latching_enabled) {} // We explicitly invoke SetUp to allow gesture debounce customization. void SetUp() override {} @@ -860,7 +883,7 @@ void SetUpOverscrollEnvironment() { SetUpOverscrollEnvironmentImpl(0); } void SetUpOverscrollEnvironmentImpl(int debounce_interval_in_ms) { - EnableRafAlignedTouchInput(); + SetFeatureList(true, wheel_scroll_latching_enabled_); ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms( debounce_interval_in_ms); @@ -1027,14 +1050,119 @@ touch_event_.ReleasePoint(index); } + void ExpectGestureScrollEndForWheelScrolling(bool is_last) { + if (wheel_scroll_latching_enabled_) { + if (!is_last) { + EXPECT_EQ(0U, GetSentMessageCountAndResetSink()); + return; + } + // Let the ScrollEnd timer in mouseWheelEventQueue fire. This will cause + // the mouseWheelEventQueue to send a GestureScrollEnd event. + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), + base::TimeDelta::FromMilliseconds( + kDefaultWheelScrollLatchingTransactionMs)); + base::RunLoop().Run(); + } + + EXPECT_EQ(1U, sink_->message_count()); + InputMsg_HandleInputEvent::Param params; + if (InputMsg_HandleInputEvent::Read(sink_->GetMessageAt(0), ¶ms)) { + const blink::WebInputEvent* event = std::get<0>(params); + EXPECT_EQ(WebInputEvent::GestureScrollEnd, event->type()); + } + EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + } + + void ExpectGestureScrollEventsAfterMouseWheelACK(bool is_first_ack, + bool enqueued_mouse_wheel) { + InputMsg_HandleInputEvent::Param params; + const blink::WebInputEvent* event; + size_t expected_message_count; + if (is_first_ack) { + expected_message_count = enqueued_mouse_wheel ? 3 : 2; + EXPECT_EQ(expected_message_count, sink_->message_count()); + + // The first message is GestureScrollBegin. + if (InputMsg_HandleInputEvent::Read(sink_->GetMessageAt(0), ¶ms)) { + event = std::get<0>(params); + EXPECT_EQ(WebInputEvent::GestureScrollBegin, event->type()); + } + + // The second message is GestureScrollUpdate. + if (InputMsg_HandleInputEvent::Read(sink_->GetMessageAt(1), ¶ms)) { + event = std::get<0>(params); + EXPECT_EQ(WebInputEvent::GestureScrollUpdate, event->type()); + } + + if (enqueued_mouse_wheel) { + // The last message is the queued MouseWheel. + if (InputMsg_HandleInputEvent::Read(sink_->GetMessageAt(2), ¶ms)) { + event = std::get<0>(params); + EXPECT_EQ(WebInputEvent::MouseWheel, event->type()); + } + } + } else { // !is_first_ack + expected_message_count = enqueued_mouse_wheel ? 2 : 1; + size_t scroll_update_index = 0; + + if (!wheel_scroll_latching_enabled_) { + // The first message is GestureScrollBegin even in the middle of + // scrolling. + if (InputMsg_HandleInputEvent::Read(sink_->GetMessageAt(0), ¶ms)) { + event = std::get<0>(params); + EXPECT_EQ(WebInputEvent::GestureScrollBegin, event->type()); + } + expected_message_count++; + scroll_update_index++; + } + + // Check the GestureScrollUpdate message. + if (InputMsg_HandleInputEvent::Read( + sink_->GetMessageAt(scroll_update_index), ¶ms)) { + event = std::get<0>(params); + EXPECT_EQ(WebInputEvent::GestureScrollUpdate, event->type()); + } + + if (enqueued_mouse_wheel) { + // The last message is the queued MouseWheel. + if (InputMsg_HandleInputEvent::Read( + sink_->GetMessageAt(expected_message_count - 1), ¶ms)) { + event = std::get<0>(params); + EXPECT_EQ(WebInputEvent::MouseWheel, event->type()); + } + } + } + EXPECT_EQ(expected_message_count, GetSentMessageCountAndResetSink()); + } + + void WheelNotPreciseScrollEvent(); + void WheelScrollOverscrollToggle(); + void OverscrollMouseMoveCompletion(); + void WheelScrollEventOverscrolls(); + void WheelScrollConsumedDoNotHorizOverscroll(); + void ScrollEventsOverscrollWithFling(); + void OverscrollDirectionChangeMouseWheel(); + void OverscrollStateResetsAfterScroll(); + void ScrollEventsOverscrollWithZeroFling(); + SyntheticWebTouchEvent touch_event_; std::unique_ptr<TestOverscrollDelegate> overscroll_delegate_; + bool wheel_scroll_latching_enabled_; + private: DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraOverscrollTest); }; +class RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest + : public RenderWidgetHostViewAuraOverscrollTest { + public: + RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest() + : RenderWidgetHostViewAuraOverscrollTest(false) {} +}; + class RenderWidgetHostViewAuraShutdownTest : public RenderWidgetHostViewAuraTest { public: @@ -3335,7 +3463,7 @@ EXPECT_EQ(kY, pointer_state().GetY(0)); } -TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelNotPreciseScrollEvent) { +void RenderWidgetHostViewAuraOverscrollTest::WheelNotPreciseScrollEvent() { SetUpOverscrollEnvironment(); // Simulate wheel events. @@ -3347,31 +3475,34 @@ // Receive ACK the first wheel event as not processed. SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEventsAfterMouseWheelACK(true, true); - // ScrollBegin, ScrollUpdate, and MouseWheel will be queued events. - EXPECT_EQ(3U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - + ExpectGestureScrollEndForWheelScrolling(false); EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollUpdate will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(true); EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); +} +TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelNotPreciseScrollEvent) { + WheelNotPreciseScrollEvent(); +} +TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest, + WheelNotPreciseScrollEvent) { + WheelNotPreciseScrollEvent(); } -TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelScrollEventOverscrolls) { +void RenderWidgetHostViewAuraOverscrollTest::WheelScrollEventOverscrolls() { SetUpOverscrollEnvironment(); // Simulate wheel events. @@ -3387,16 +3518,14 @@ // Receive ACK the first wheel event as not processed. SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEventsAfterMouseWheelACK(true, true); - // ScrollBegin, ScrollUpdate, and MouseWheel will be queued events. - EXPECT_EQ(3U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(false); EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); // Receive ACK for the second (coalesced) event as not processed. This will // start a back navigation. However, this will also cause the queued next @@ -3406,17 +3535,20 @@ // back navigation, and no ScrollUpdate event will be sent to the renderer. SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin, ScrollUpdate, and MouseWheel will be queued events. - EXPECT_EQ(3U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(false, true); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEndForWheelScrolling(false); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollEnd will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + if (wheel_scroll_latching_enabled_) { + EXPECT_EQ(0U, GetSentMessageCountAndResetSink()); + } else { + // ScrollBegin and ScrollEnd will be queued events. + EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + } EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode()); EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode()); @@ -3431,11 +3563,18 @@ EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); EXPECT_EQ(1U, sink_->message_count()); } +TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelScrollEventOverscrolls) { + WheelScrollEventOverscrolls(); +} +TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest, + WheelScrollEventOverscrolls) { + WheelScrollEventOverscrolls(); +} // Tests that if some scroll events are consumed towards the start, then // subsequent scrolls do not horizontal overscroll. -TEST_F(RenderWidgetHostViewAuraOverscrollTest, - WheelScrollConsumedDoNotHorizOverscroll) { +void RenderWidgetHostViewAuraOverscrollTest:: + WheelScrollConsumedDoNotHorizOverscroll() { SetUpOverscrollEnvironment(); // Simulate wheel events. @@ -3451,12 +3590,11 @@ // Receive ACK the first wheel event as processed. SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin, ScrollUpdate, and MouseWheel will be queued events. - EXPECT_EQ(3U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(true, true); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_CONSUMED); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEndForWheelScrolling(false); EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); @@ -3468,26 +3606,32 @@ SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); - // ScrollBegin, ScrollUpdate, and MouseWheel will be queued events. - EXPECT_EQ(3U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(false, true); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEndForWheelScrolling(false); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin, ScrollUpdate, and MouseWheel will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEndForWheelScrolling(true); EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); } +TEST_F(RenderWidgetHostViewAuraOverscrollTest, + WheelScrollConsumedDoNotHorizOverscroll) { + WheelScrollConsumedDoNotHorizOverscroll(); +} +TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest, + WheelScrollConsumedDoNotHorizOverscroll) { + WheelScrollConsumedDoNotHorizOverscroll(); +} // Tests that wheel-scrolling correctly turns overscroll on and off. -TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelScrollOverscrollToggle) { +void RenderWidgetHostViewAuraOverscrollTest::WheelScrollOverscrollToggle() { SetUpOverscrollEnvironment(); // Send a wheel event. ACK the event as not processed. This should not @@ -3496,12 +3640,12 @@ EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollUpdate will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(true, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEndForWheelScrolling(false); + EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); @@ -3510,12 +3654,12 @@ EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollUpdate will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEndForWheelScrolling(false); + EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); @@ -3524,12 +3668,12 @@ EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollUpdate will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEndForWheelScrolling(false); + EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode()); EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode()); EXPECT_EQ(60.f, overscroll_delta_x()); @@ -3541,8 +3685,12 @@ EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollEnd will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + if (wheel_scroll_latching_enabled_) { + EXPECT_EQ(0U, GetSentMessageCountAndResetSink()); + } else { + // ScrollBegin and ScrollEnd will be queued events. + EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + } EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); @@ -3551,12 +3699,12 @@ EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollUpdate will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEndForWheelScrolling(false); + EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); @@ -3566,21 +3714,27 @@ EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollUpdate will be the queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEndForWheelScrolling(true); + EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode()); EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode()); EXPECT_EQ(-75.f, overscroll_delta_x()); EXPECT_EQ(-25.f, overscroll_delegate()->delta_x()); EXPECT_EQ(0.f, overscroll_delegate()->delta_y()); } +TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelScrollOverscrollToggle) { + WheelScrollOverscrollToggle(); +} +TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest, + WheelScrollOverscrollToggle) { + WheelScrollOverscrollToggle(); +} -TEST_F(RenderWidgetHostViewAuraOverscrollTest, - ScrollEventsOverscrollWithFling) { +void RenderWidgetHostViewAuraOverscrollTest::ScrollEventsOverscrollWithFling() { SetUpOverscrollEnvironment(); // Send a wheel event. ACK the event as not processed. This should not @@ -3589,14 +3743,14 @@ EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollUpdate will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(true, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(false); + EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); // Scroll some more so as to not overscroll. SimulateWheelEvent(20, 0, 0, true); @@ -3614,12 +3768,15 @@ EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin, ScrollUpdate, and ScrollEnd will be queued events. - EXPECT_EQ(3U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEndForWheelScrolling(false); + EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode()); EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode()); + EXPECT_EQ(60.f, overscroll_delta_x()); EXPECT_EQ(10.f, overscroll_delegate()->delta_x()); EXPECT_EQ(0.f, overscroll_delegate()->delta_y()); @@ -3632,14 +3789,28 @@ blink::WebGestureDeviceTouchscreen); SimulateGestureFlingStartEvent(0.f, 0.1f, blink::WebGestureDeviceTouchpad); EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); - // ScrollBegin and FlingStart will be queued events. - EXPECT_EQ(2U, sink_->message_count()); + + if (!wheel_scroll_latching_enabled_) { + // ScrollBegin and FlingStart will be queued events. + EXPECT_EQ(2U, sink_->message_count()); + } else { + // ScrollEnd, ScrollBegin, and FlingStart will be queued events. + EXPECT_EQ(3U, sink_->message_count()); + } +} +TEST_F(RenderWidgetHostViewAuraOverscrollTest, + ScrollEventsOverscrollWithFling) { + ScrollEventsOverscrollWithFling(); +} +TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest, + ScrollEventsOverscrollWithFling) { + ScrollEventsOverscrollWithFling(); } // Same as ScrollEventsOverscrollWithFling, but with zero velocity. Checks that // the zero-velocity fling does not reach the renderer. -TEST_F(RenderWidgetHostViewAuraOverscrollTest, - ScrollEventsOverscrollWithZeroFling) { +void RenderWidgetHostViewAuraOverscrollTest:: + ScrollEventsOverscrollWithZeroFling() { SetUpOverscrollEnvironment(); // Send a wheel event. ACK the event as not processed. This should not @@ -3648,42 +3819,42 @@ EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollUpdate will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(true, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(false); + EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); // Scroll some more so as to not overscroll. SimulateWheelEvent(20, 0, 0, true); EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollUpdate will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(false); + EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); // Scroll some more to initiate an overscroll. SimulateWheelEvent(30, 0, 0, true); EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollUpdate will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(false); + EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode()); EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode()); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); EXPECT_EQ(60.f, overscroll_delta_x()); EXPECT_EQ(10.f, overscroll_delegate()->delta_x()); @@ -3697,8 +3868,22 @@ blink::WebGestureDeviceTouchscreen); SimulateGestureFlingStartEvent(10.f, 0.f, blink::WebGestureDeviceTouchpad); EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); - // scrollBeign and FlingStart will be queued events. - EXPECT_EQ(2U, sink_->message_count()); + + if (!wheel_scroll_latching_enabled_) { + // ScrollBegin and FlingStart will be queued events. + EXPECT_EQ(2U, sink_->message_count()); + } else { + // ScrollEnd, ScrollBegin, and FlingStart will be queued events. + EXPECT_EQ(3U, sink_->message_count()); + } +} +TEST_F(RenderWidgetHostViewAuraOverscrollTest, + ScrollEventsOverscrollWithZeroFling) { + ScrollEventsOverscrollWithZeroFling(); +} +TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest, + ScrollEventsOverscrollWithZeroFling) { + ScrollEventsOverscrollWithZeroFling(); } // Tests that a fling in the opposite direction of the overscroll cancels the @@ -4146,8 +4331,8 @@ EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); } -TEST_F(RenderWidgetHostViewAuraOverscrollTest, - OverscrollDirectionChangeMouseWheel) { +void RenderWidgetHostViewAuraOverscrollTest:: + OverscrollDirectionChangeMouseWheel() { SetUpOverscrollEnvironment(); // Send wheel event and receive ack as not consumed. @@ -4155,14 +4340,14 @@ EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollUpdate will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(true, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(false); + EXPECT_EQ(OVERSCROLL_EAST, overscroll_mode()); EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->current_mode()); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); // Send another wheel event, but in the reverse direction. The overscroll // controller will not consume the event, because it is not triggering @@ -4172,17 +4357,16 @@ EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); - // ScrollBegin and ScrollUpdate will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(false); // Since it was unhandled; the overscroll should now be west EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode()); EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode()); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); SimulateWheelEvent(-20, 0, 0, true); EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); @@ -4191,13 +4375,26 @@ // wheel event ack generates gesture scroll update; which gets consumed // solely by the overflow controller. - // No ScrollUpdates, only ScrollBegin and ScrollEnd will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + if (!wheel_scroll_latching_enabled_) { + // No ScrollUpdates, only ScrollBegin and ScrollEnd will be queued events. + EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + } else { + EXPECT_EQ(0U, GetSentMessageCountAndResetSink()); + } + EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode()); EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode()); } +TEST_F(RenderWidgetHostViewAuraOverscrollTest, + OverscrollDirectionChangeMouseWheel) { + OverscrollDirectionChangeMouseWheel(); +} +TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest, + OverscrollDirectionChangeMouseWheel) { + OverscrollDirectionChangeMouseWheel(); +} -TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollMouseMoveCompletion) { +void RenderWidgetHostViewAuraOverscrollTest::OverscrollMouseMoveCompletion() { SetUpOverscrollEnvironment(); SimulateWheelEvent(5, 0, 0, true); // sent directly @@ -4211,28 +4408,27 @@ // Receive ACK the first wheel event as not processed. SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin, ScrollUpdate, and the second MouseWheel will be queued - // events. - EXPECT_EQ(3U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(true, true); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(false); + EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode()); EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode()); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); // Receive ACK for the second (coalesced) event as not processed. This will // start an overcroll gesture. SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - // ScrollBegin and ScrollUpdate will be queued events. - EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(false); + EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode()); EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode()); - // ScrollEnd will be the queued event. - EXPECT_EQ(1U, GetSentMessageCountAndResetSink()); // Send a mouse-move event. This should cancel the overscroll navigation // (since the amount overscrolled is not above the threshold), and so the @@ -4285,11 +4481,18 @@ SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); } +TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollMouseMoveCompletion) { + OverscrollMouseMoveCompletion(); +} +TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest, + OverscrollMouseMoveCompletion) { + OverscrollMouseMoveCompletion(); +} // Tests that if a page scrolled, then the overscroll controller's states are // reset after the end of the scroll. -TEST_F(RenderWidgetHostViewAuraOverscrollTest, - OverscrollStateResetsAfterScroll) { +void RenderWidgetHostViewAuraOverscrollTest:: + OverscrollStateResetsAfterScroll() { SetUpOverscrollEnvironment(); SimulateWheelEvent(0, 5, 0, true); // sent directly @@ -4302,21 +4505,22 @@ // The first wheel event is consumed. Dispatches the queued wheel event. SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEventsAfterMouseWheelACK(true, true); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(false); EXPECT_TRUE(ScrollStateIsContentScrolling()); - // ScrollBegin, ScrollUpdate, the second MouseWheel, and ScrollEnd will be - // queued events. - EXPECT_EQ(4U, GetSentMessageCountAndResetSink()); // The second wheel event is consumed. SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(true); EXPECT_TRUE(ScrollStateIsContentScrolling()); - // ScrollBegin, ScrollUpdate, and ScrollEnd will be queued events. - EXPECT_EQ(3U, sink_->message_count()); // Touchpad scroll can end with a zero-velocity fling. But it is not // dispatched, but it should still reset the overscroll controller state. @@ -4324,9 +4528,8 @@ blink::WebGestureDeviceTouchscreen); SimulateGestureFlingStartEvent(0.f, 0.f, blink::WebGestureDeviceTouchpad); EXPECT_TRUE(ScrollStateIsUnknown()); - // ScrollBegin, ScrollUpdate, ScrollEnd, and ScrollBegin will be queued - // events. - EXPECT_EQ(4U, sink_->message_count()); + // ScrollBegin will be queued events. + EXPECT_EQ(1U, sink_->message_count()); // Dropped flings should neither propagate *nor* indicate that they were // consumed and have triggered a fling animation (as tracked by the router). @@ -4334,9 +4537,8 @@ SimulateGestureEvent(WebInputEvent::GestureScrollEnd, blink::WebGestureDeviceTouchscreen); - // ScrollBegin, ScrollUpdate, ScrollEnd, ScrollBegin, and ScrollEnd will be - // queued events. - EXPECT_EQ(5U, GetSentMessageCountAndResetSink()); + // ScrollBegin, and ScrollEnd will be queued events. + EXPECT_EQ(2U, GetSentMessageCountAndResetSink()); SimulateWheelEvent(-5, 0, 0, true); // sent directly SimulateWheelEvent(-60, 0, 0, true); // enqueued @@ -4348,21 +4550,22 @@ // yet, since enough hasn't been scrolled. SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEventsAfterMouseWheelACK(true, true); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(false); EXPECT_TRUE(ScrollStateIsUnknown()); - // ScrollBegin, ScrollUpdate, the second Mousewheel, and ScrollEnd will be - // queued events. - EXPECT_EQ(4U, GetSentMessageCountAndResetSink()); SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEventsAfterMouseWheelACK(false, false); + SendInputEventACK(WebInputEvent::GestureScrollUpdate, INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + ExpectGestureScrollEndForWheelScrolling(true); EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode()); EXPECT_TRUE(ScrollStateIsOverscrolling()); - // ScrollBegin, ScrollUpdate, and ScrollEnd will be queued events. - EXPECT_EQ(3U, GetSentMessageCountAndResetSink()); // The GestureScrollBegin will reset the delegate's mode, so check it here. EXPECT_EQ(OVERSCROLL_WEST, overscroll_delegate()->current_mode()); @@ -4375,6 +4578,14 @@ EXPECT_EQ(1U, sink_->message_count()); EXPECT_FALSE(parent_host_->input_router()->HasPendingEvents()); } +TEST_F(RenderWidgetHostViewAuraOverscrollTest, + OverscrollStateResetsAfterScroll) { + OverscrollStateResetsAfterScroll(); +} +TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest, + OverscrollStateResetsAfterScroll) { + OverscrollStateResetsAfterScroll(); +} TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollResetsOnBlur) { SetUpOverscrollEnvironment();
diff --git a/content/browser/web_contents/web_contents_android.h b/content/browser/web_contents/web_contents_android.h index 50bb975..d35a136 100644 --- a/content/browser/web_contents/web_contents_android.h +++ b/content/browser/web_contents/web_contents_android.h
@@ -19,6 +19,8 @@ #include "content/browser/renderer_host/render_widget_host_view_android.h" #include "content/common/content_export.h" +class GURL; + namespace content { class WebContentsImpl;
diff --git a/content/browser/zygote_host/zygote_communication_linux.cc b/content/browser/zygote_host/zygote_communication_linux.cc index 76548d22..03780e7 100644 --- a/content/browser/zygote_host/zygote_communication_linux.cc +++ b/content/browser/zygote_host/zygote_communication_linux.cc
@@ -22,7 +22,6 @@ #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" #include "content/public/common/result_codes.h" -#include "media/base/media_switches.h" #include "ui/display/display_switches.h" #include "ui/gfx/switches.h" @@ -261,8 +260,6 @@ switches::kForceDeviceScaleFactor, switches::kLoggingLevel, switches::kNoSandbox, switches::kPpapiInProcess, switches::kRegisterPepperPlugins, switches::kV, switches::kVModule, - // Need to tell CdmHostFile(s) to ignore missing CDM host files. - switches::kIgnoreMissingCdmHostFile, }; cmd_line.CopySwitchesFrom(browser_command_line, kForwardSwitches, arraysize(kForwardSwitches));
diff --git a/content/common/media/cdm_host_file.cc b/content/common/media/cdm_host_file.cc index 99d5cca2..ff023839 100644 --- a/content/common/media/cdm_host_file.cc +++ b/content/common/media/cdm_host_file.cc
@@ -10,41 +10,25 @@ #include "base/feature_list.h" #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "media/base/media_switches.h" #include "media/cdm/api/content_decryption_module_ext.h" namespace content { -namespace { - -bool IgnoreMissingCdmHostFile() { - return base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kIgnoreMissingCdmHostFile); -} - -} // namespace - // static std::unique_ptr<CdmHostFile> CdmHostFile::Create( const base::FilePath& file_path, const base::FilePath& sig_file_path) { + DVLOG(1) << __func__; + // Open file at |file_path|. base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); - if (!file.IsValid()) { - DVLOG(1) << "Failed to open file at " << file_path.MaybeAsASCII(); - return nullptr; - } + DVLOG(1) << " " << file.IsValid() << ": " << file_path.MaybeAsASCII(); // Also open the sig file at |sig_file_path|. base::File sig_file(sig_file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); - if (!sig_file.IsValid()) { - DVLOG(1) << "Failed to open sig file at " << sig_file_path.MaybeAsASCII(); - if (!IgnoreMissingCdmHostFile()) - return nullptr; - - DVLOG(1) << "Ignoring sig file failure at " << sig_file_path.MaybeAsASCII(); - } + DVLOG(1) << " " << sig_file.IsValid() << ": " + << sig_file_path.MaybeAsASCII(); return std::unique_ptr<CdmHostFile>( new CdmHostFile(file_path, std::move(file), std::move(sig_file))); @@ -61,12 +45,7 @@ : file_path_(file_path), file_(std::move(file)), sig_file_(std::move(sig_file)) { - DVLOG(1) << __func__ << ": " << file_path_.value(); - DCHECK(!file_path_.empty()) << "File path is empty."; - DCHECK(file_.IsValid()) << "Invalid file."; - - if (!IgnoreMissingCdmHostFile()) - DCHECK(sig_file_.IsValid()) << "Invalid signature file."; + DCHECK(!file_path_.empty()); } } // namespace content
diff --git a/content/common/media/cdm_host_files.cc b/content/common/media/cdm_host_files.cc index 1310403e..0315117 100644 --- a/content/common/media/cdm_host_files.cc +++ b/content/common/media/cdm_host_files.cc
@@ -21,7 +21,6 @@ #include "content/common/media/cdm_host_file.h" #include "content/public/common/cdm_info.h" #include "content/public/common/content_client.h" -#include "media/base/media_switches.h" #include "media/cdm/api/content_decryption_module_ext.h" #include "media/cdm/cdm_paths.h" @@ -36,11 +35,6 @@ namespace { -bool IgnoreMissingCdmHostFile() { - return base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kIgnoreMissingCdmHostFile); -} - // TODO(xhwang): Move this to a common place if needed. const base::FilePath::CharType kSignatureFileExtension[] = FILE_PATH_LITERAL(".sig"); @@ -120,12 +114,7 @@ std::unique_ptr<CdmHostFiles> cdm_host_files = base::MakeUnique<CdmHostFiles>(); - if (!cdm_host_files->OpenFilesForAllRegisteredCdms()) { - DVLOG(1) << __func__ << " failed."; - cdm_host_files.reset(); - return; - } - + cdm_host_files->OpenFilesForAllRegisteredCdms(); g_cdm_host_files.Get().reset(cdm_host_files.release()); } @@ -141,11 +130,7 @@ DVLOG(1) << __func__; std::unique_ptr<CdmHostFiles> cdm_host_files = base::MakeUnique<CdmHostFiles>(); - if (!cdm_host_files->OpenFiles(cdm_adapter_path)) { - cdm_host_files.reset(); - return nullptr; - } - + cdm_host_files->OpenFiles(cdm_adapter_path); return cdm_host_files; } @@ -193,17 +178,24 @@ // Fills |cdm_host_files| with common and CDM specific files for // |cdm_adapter_path|. std::vector<cdm::HostFile> cdm_host_files; - if (!TakePlatformFiles(cdm_adapter_path, &cdm_host_files)) { - DVLOG(1) << "Failed to take platform files."; - CloseAllFiles(); - return true; - } + TakePlatformFiles(cdm_adapter_path, &cdm_host_files); + + // std::vector::data() is not guaranteed to be nullptr when empty(). + const cdm::HostFile* cdm_host_files_ptr = + cdm_host_files.empty() ? nullptr : cdm_host_files.data(); // Call |verify_cdm_host_func| on the CDM with |cdm_host_files|. Note that // the ownership of these files are transferred to the CDM, which will close // the files immediately after use. - DVLOG(1) << __func__ << ": Calling " << kVerifyCdmHostFuncName << "()."; - if (!verify_cdm_host_func(cdm_host_files.data(), cdm_host_files.size())) { + DVLOG(1) << __func__ << ": Calling " << kVerifyCdmHostFuncName << "() with " + << cdm_host_files.size() << " files."; + for (const auto& host_file : cdm_host_files) { + DVLOG(1) << " - File Path: " << host_file.file_path; + DVLOG(1) << " - File: " << host_file.file; + DVLOG(1) << " - Sig File: " << host_file.sig_file; + } + + if (!verify_cdm_host_func(cdm_host_files_ptr, cdm_host_files.size())) { DVLOG(1) << "Failed to verify CDM host."; CloseAllFiles(); return false; @@ -215,39 +207,27 @@ } #if defined(POSIX_WITH_ZYGOTE) -bool CdmHostFiles::OpenFilesForAllRegisteredCdms() { +void CdmHostFiles::OpenFilesForAllRegisteredCdms() { std::vector<base::FilePath> cdm_adapter_paths; GetRegisteredCdms(&cdm_adapter_paths); if (cdm_adapter_paths.empty()) { DVLOG(1) << "No CDM registered."; - return false; + return; } - // Ignore - for (auto& cdm_adapter_path : cdm_adapter_paths) { - bool result = OpenCdmFiles(cdm_adapter_path); - if (!result) - DVLOG(1) << "CDM files cannot be opened for " << cdm_adapter_path.value(); - // Ignore the failure and try other registered CDM. - } + for (auto& cdm_adapter_path : cdm_adapter_paths) + OpenCdmFiles(cdm_adapter_path); - if (cdm_specific_files_map_.empty()) { - DVLOG(1) << "CDM specific files cannot be opened for any registered CDM."; - return false; - } - - return OpenCommonFiles(); + OpenCommonFiles(); } #endif -bool CdmHostFiles::OpenFiles(const base::FilePath& cdm_adapter_path) { - if (!OpenCdmFiles(cdm_adapter_path)) - return false; - - return OpenCommonFiles(); +void CdmHostFiles::OpenFiles(const base::FilePath& cdm_adapter_path) { + OpenCdmFiles(cdm_adapter_path); + OpenCommonFiles(); } -bool CdmHostFiles::OpenCommonFiles() { +void CdmHostFiles::OpenCommonFiles() { DCHECK(common_files_.empty()); std::vector<CdmHostFilePath> cdm_host_file_paths; @@ -255,34 +235,21 @@ &cdm_host_file_paths); for (const CdmHostFilePath& value : cdm_host_file_paths) { - std::unique_ptr<CdmHostFile> cdm_host_file = - CdmHostFile::Create(value.file_path, value.sig_file_path); - if (cdm_host_file) { - common_files_.push_back(std::move(cdm_host_file)); - continue; - } - - if (!IgnoreMissingCdmHostFile()) - return false; + common_files_.push_back( + CdmHostFile::Create(value.file_path, value.sig_file_path)); } - - return true; } -bool CdmHostFiles::OpenCdmFiles(const base::FilePath& cdm_adapter_path) { +void CdmHostFiles::OpenCdmFiles(const base::FilePath& cdm_adapter_path) { DCHECK(!cdm_adapter_path.empty()); DCHECK(!cdm_specific_files_map_.count(cdm_adapter_path)); std::unique_ptr<CdmHostFile> cdm_adapter_file = CdmHostFile::Create(cdm_adapter_path, GetSigFilePath(cdm_adapter_path)); - if (!cdm_adapter_file) - return false; base::FilePath cdm_path = GetCdmPath(cdm_adapter_path); std::unique_ptr<CdmHostFile> cdm_file = CdmHostFile::Create(cdm_path, GetSigFilePath(cdm_path)); - if (!cdm_file) - return false; ScopedFileVector cdm_specific_files; cdm_specific_files.reserve(2); @@ -290,38 +257,26 @@ cdm_specific_files.push_back(std::move(cdm_file)); cdm_specific_files_map_[cdm_adapter_path] = std::move(cdm_specific_files); - return true; } -bool CdmHostFiles::TakePlatformFiles( +void CdmHostFiles::TakePlatformFiles( const base::FilePath& cdm_adapter_path, std::vector<cdm::HostFile>* cdm_host_files) { DCHECK(cdm_host_files->empty()); - if (!IgnoreMissingCdmHostFile()) - DCHECK(!common_files_.empty()); - - // Check whether CDM specific files exist. - const auto& iter = cdm_specific_files_map_.find(cdm_adapter_path); - if (iter == cdm_specific_files_map_.end()) { - // This could happen on Linux where CDM files fail to open for Foo CDM, but - // now we hit Bar CDM. - DVLOG(1) << "No CDM specific files for " << cdm_adapter_path.value(); - return false; - } - - const ScopedFileVector& cdm_specific_files = iter->second; - - cdm_host_files->reserve(common_files_.size() + cdm_specific_files.size()); - // Populate an array of cdm::HostFile. for (const auto& file : common_files_) cdm_host_files->push_back(file->TakePlatformFile()); - for (const auto& file : cdm_specific_files) - cdm_host_files->push_back(file->TakePlatformFile()); - - return true; + // Check whether CDM specific files exist. + const auto& iter = cdm_specific_files_map_.find(cdm_adapter_path); + if (iter == cdm_specific_files_map_.end()) { + NOTREACHED() << "No CDM specific files for " << cdm_adapter_path.value(); + } else { + const ScopedFileVector& cdm_specific_files = iter->second; + for (const auto& file : cdm_specific_files) + cdm_host_files->push_back(file->TakePlatformFile()); + } } void CdmHostFiles::CloseAllFiles() {
diff --git a/content/common/media/cdm_host_files.h b/content/common/media/cdm_host_files.h index 5ec1daf..75430d5 100644 --- a/content/common/media/cdm_host_files.h +++ b/content/common/media/cdm_host_files.h
@@ -72,27 +72,23 @@ private: #if defined(POSIX_WITH_ZYGOTE) // Opens all common files and CDM specific files for all registered CDMs. - bool OpenFilesForAllRegisteredCdms(); + void OpenFilesForAllRegisteredCdms(); #endif // Opens all common files and CDM specific files for the CDM adapter // registered at |cdm_adapter_path|. - bool OpenFiles(const base::FilePath& cdm_adapter_path); + void OpenFiles(const base::FilePath& cdm_adapter_path); - // Opens common CDM host files shared by all CDMs. Upon failure, close all - // files opened. - bool OpenCommonFiles(); + // Opens common CDM host files shared by all CDMs. + void OpenCommonFiles(); // Opens CDM specific files for the CDM adapter registered at - // |cdm_adapter_path|. Returns whether all CDM specific files are opened. - // Upon failure, close all files opened. - bool OpenCdmFiles(const base::FilePath& cdm_adapter_path); + // |cdm_adapter_path|. + void OpenCdmFiles(const base::FilePath& cdm_adapter_path); // Fills |cdm_host_files| with common and CDM specific files for // |cdm_adapter_path|. The ownership of those files are also transferred. - // Returns true upon success where the remaining files will be closed. - // Returns false upon any failure and all files will be closed. - bool TakePlatformFiles(const base::FilePath& cdm_adapter_path, + void TakePlatformFiles(const base::FilePath& cdm_adapter_path, std::vector<cdm::HostFile>* cdm_host_files); void CloseAllFiles();
diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 305fc01..2f4cdf0b 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h
@@ -882,11 +882,6 @@ IPC_MESSAGE_ROUTED0(ViewHostMsg_WaitForNextFrameForTests_ACK) #if defined(OS_ANDROID) -// Start an android intent with the given URI. -IPC_MESSAGE_ROUTED2(ViewHostMsg_StartContentIntent, - GURL /* content_url */, - bool /* is_main_frame */) - // Notifies that an unhandled tap has occurred at the specified x,y position // and that the UI may need to be triggered. IPC_MESSAGE_ROUTED2(ViewHostMsg_ShowUnhandledTapUIIfNeeded,
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 6fe3729..6daa30cdc 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -402,21 +402,15 @@ ] java_files = [ - "javatests/src/org/chromium/content/browser/AddressDetectionTest.java", "javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java", "javatests/src/org/chromium/content/browser/ChildProcessLauncherTest.java", - "javatests/src/org/chromium/content/browser/ClickListenerTest.java", "javatests/src/org/chromium/content/browser/ClipboardTest.java", "javatests/src/org/chromium/content/browser/ContentCommandLineTest.java", - "javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java", - "javatests/src/org/chromium/content/browser/ContentDetectionActivityTestRule.java", - "javatests/src/org/chromium/content/browser/ContentDetectionTestCommon.java", "javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java", "javatests/src/org/chromium/content/browser/ContentViewLocationTest.java", "javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java", "javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java", "javatests/src/org/chromium/content/browser/ContentViewZoomingTest.java", - "javatests/src/org/chromium/content/browser/EmailAddressDetectionTest.java", "javatests/src/org/chromium/content/browser/EncodeHtmlDataUriTest.java", "javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java", "javatests/src/org/chromium/content/browser/ImportantFileWriterAndroidTest.java", @@ -436,7 +430,6 @@ "javatests/src/org/chromium/content/browser/MediaResourceGetterTest.java", "javatests/src/org/chromium/content/browser/MediaSessionTest.java", "javatests/src/org/chromium/content/browser/NavigationTest.java", - "javatests/src/org/chromium/content/browser/PhoneNumberDetectionTest.java", "javatests/src/org/chromium/content/browser/PopupZoomerTest.java", "javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java", "javatests/src/org/chromium/content/browser/TestsJavaScriptEvalTest.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java index 5521da3a..42c5977e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -654,7 +654,7 @@ PopupZoomer.OnTapListener listener = new PopupZoomer.OnTapListener() { // mContainerView can change, but this OnTapListener can only be used // with the mContainerViewAtCreation. - private final ViewGroup mContainerViewAtCreation = mContainerView; + private final ViewGroup mContainerViewAtCreation = containerView; @Override public void onResolveTapDisambiguation(
diff --git a/content/public/android/java/src/org/chromium/content/common/ContentSwitches.java b/content/public/android/java/src/org/chromium/content/common/ContentSwitches.java index a356d08..8b770ef 100644 --- a/content/public/android/java/src/org/chromium/content/common/ContentSwitches.java +++ b/content/public/android/java/src/org/chromium/content/common/ContentSwitches.java
@@ -71,9 +71,6 @@ // Native switch kGPUProcess public static final String SWITCH_GPU_PROCESS = "gpu-process"; - // Enable content intent detection in the renderer - public static final String ENABLE_CONTENT_INTENT_DETECTION = "enable-content-intent-detection"; - // Use fake device for Media Stream to replace actual camera and microphone. public static final String USE_FAKE_DEVICE_FOR_MEDIA_STREAM = "use-fake-device-for-media-stream";
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/AddressDetectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/AddressDetectionTest.java deleted file mode 100644 index 8095a37..0000000 --- a/content/public/android/javatests/src/org/chromium/content/browser/AddressDetectionTest.java +++ /dev/null
@@ -1,119 +0,0 @@ -// Copyright 2012 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.content.browser; - -import android.support.test.filters.MediumTest; - -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; -import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.content.common.ContentSwitches; - -/** - * Test suite for geographical US address detection. - */ -@CommandLineFlags.Add({ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) -public class AddressDetectionTest extends ContentDetectionTestBase { - - private static final String GEO_INTENT_PREFIX = "geo:0,0?q="; - - private boolean isExpectedGeoIntent(String intentUrl, String expectedContent) { - if (intentUrl == null) return false; - final String expectedUrl = GEO_INTENT_PREFIX + urlForContent(expectedContent); - return intentUrl.equals(expectedUrl); - } - - @MediumTest - @Feature({"ContentDetection", "TabContents"}) - @RetryOnFailure - public void testMultipleAddressesInText() throws Throwable { - startActivityWithTestUrl( - "content/test/data/android/content_detection/geo_address_multiple.html"); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"), - "1600 Amphitheatre Parkway Mountain View, CA 94043")); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test2"), - "76 Ninth Avenue 4th Floor New York, NY 10011")); - } - - @MediumTest - @Feature({"ContentDetection", "TabContents"}) - @RetryOnFailure - public void testSplitAddresses() throws Throwable { - startActivityWithTestUrl( - "content/test/data/android/content_detection/geo_address_split.html"); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"), - "9606 North MoPac Expressway Suite 400 Austin, TX 78759")); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test2"), - "1818 Library Street Suite 400, VA 20190")); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test3"), - "1818 Library Street Suite 400, VA 20190")); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test4"), - "1818 Library Street Suite 400, VA 20190")); - } - - //@MediumTest - //@Feature({"ContentDetection", "TabContents"}) - // crbug.com/671647 - @DisabledTest - public void testAddressLimits() throws Throwable { - startActivityWithTestUrl( - "content/test/data/android/content_detection/geo_address_limits.html"); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"), - "2590 Pearl Street Suite 100 Boulder, CO 80302")); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test2"), - "6425 Penn Ave. Suite 700 Pittsburgh, PA 15206")); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test3"), - "34 Main St. Boston, MA 02118")); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test4"), - "1600 Amphitheatre Parkway Mountain View, CA 94043")); - } - - @MediumTest - @Feature({"ContentDetection", "TabContents"}) - @RetryOnFailure - public void testRealAddresses() throws Throwable { - startActivityWithTestUrl( - "content/test/data/android/content_detection/geo_address_real.html"); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"), - "57th Street and Lake Shore Drive Chicago, IL 60637")); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test2"), - "57th Street and Lake Shore Drive Chicago, IL 60637")); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test3"), - "57th Street and Lake Shore Drive Chicago, IL 60637")); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test4"), - "79th Street, New York, NY, 10024-5192")); - } - - //@MediumTest - //@Feature({"ContentDetection", "TabContents"}) - //@RetryOnFailure - // crbug.com/708176 - @DisabledTest - public void testSpecialChars() throws Throwable { - startActivityWithTestUrl( - "content/test/data/android/content_detection/geo_address_special_chars.html"); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"), - "100 34th Avenue , San Francisco, CA 94121")); - - assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test2"), - "100 34th Avenue San Francisco, CA 94121")); - } -}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ClickListenerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ClickListenerTest.java deleted file mode 100644 index c16cb9a..0000000 --- a/content/public/android/javatests/src/org/chromium/content/browser/ClickListenerTest.java +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2012 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.content.browser; - -import android.support.test.filters.MediumTest; - -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.content.common.ContentSwitches; - -/** - * Test suite for click listener validation in content detection. - */ -@CommandLineFlags.Add({ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) -public class ClickListenerTest extends ContentDetectionTestBase { - - @MediumTest - @Feature({"ContentDetection", "TabContents"}) - @RetryOnFailure - public void testClickContentOnLink() throws Throwable { - startActivityWithTestUrl( - "content/test/data/android/content_detection/click_listeners.html"); - - // Clicks on addresses in links should change the url. - scrollAndTapNavigatingOut("linktest"); - assertTrue(isCurrentTestUrl("content/test/data/android/content_detection/empty.html")); - } - - @MediumTest - @Feature({"ContentDetection", "TabContents"}) - public void testClickContentOnJSListener1() throws Throwable { - startActivityWithTestUrl( - "content/test/data/android/content_detection/click_listeners.html"); - - // Clicks on addresses in elements listening to click events should be - // processed normally without address detection. - scrollAndTapNavigatingOut("clicktest1"); - assertTrue(isCurrentTestUrl("content/test/data/android/content_detection/empty.html")); - } - - @MediumTest - @Feature({"ContentDetection", "TabContents"}) - public void testClickContentOnJSListener2() throws Throwable { - startActivityWithTestUrl( - "content/test/data/android/content_detection/click_listeners.html"); - - // Same as previous test, but using addEventListener instead of onclick. - scrollAndTapNavigatingOut("clicktest2"); - assertTrue(isCurrentTestUrl("content/test/data/android/content_detection/empty.html")); - } -}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionActivityTestRule.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionActivityTestRule.java deleted file mode 100644 index 53dc306..0000000 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionActivityTestRule.java +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.content.browser; - -import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; - -import org.chromium.content.browser.test.util.TestCallbackHelperContainer; -import org.chromium.content_shell_apk.ContentShellActivityTestRule; - -/** - * ActivityTestRule for content detection test suites. - */ -public class ContentDetectionActivityTestRule extends ContentShellActivityTestRule { - private static final long WAIT_TIMEOUT_SECONDS = scaleTimeout(10); - - private final ContentDetectionTestCommon mTestCommon = new ContentDetectionTestCommon(this); - - /** - * Returns the TestCallbackHelperContainer associated with this ContentView, - * or creates it lazily. - */ - public TestCallbackHelperContainer getTestCallbackHelperContainer() { - return mTestCommon.getTestCallbackHelperContainer(); - } - - @Override - protected void beforeActivityLaunched() { - super.beforeActivityLaunched(); - mTestCommon.createTestContentIntentHandler(); - } - - @Override - protected void afterActivityLaunched() { - super.afterActivityLaunched(); - mTestCommon.setContentHandler(); - } - - /** - * Encodes the provided content string into an escaped url as intents do. - * @param content Content to escape into a url. - * @return Escaped url. - */ - public static String urlForContent(String content) { - return ContentDetectionTestCommon.urlForContent(content); - } - - /** - * Checks if the provided test url is the current url in the content view. - * @param testUrl Test url to check. - * @return true if the test url is the current one, false otherwise. - */ - public boolean isCurrentTestUrl(String testUrl) { - return mTestCommon.isCurrentTestUrl(testUrl); - } - - /** - * Scrolls to the node with the provided id, taps on it and waits for an intent to come. - * @param id Id of the node to scroll and tap. - * @return The content url of the received intent or null if none. - */ - public String scrollAndTapExpectingIntent(String id) throws Throwable { - return mTestCommon.scrollAndTapExpectingIntent(id); - } - - /** - * Scrolls to the node with the provided id, taps on it and waits for a new page load to finish. - * Useful when tapping on links that take to other pages. - * @param id Id of the node to scroll and tap. - */ - public void scrollAndTapNavigatingOut(String id) throws Throwable { - mTestCommon.scrollAndTapNavigatingOut(id); - } -}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java deleted file mode 100644 index bc234ef..0000000 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java +++ /dev/null
@@ -1,77 +0,0 @@ -// Copyright 2012 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.content.browser; - -import android.app.Activity; - -import org.chromium.content.browser.test.util.TestCallbackHelperContainer; -import org.chromium.content_shell_apk.ContentShellActivity; -import org.chromium.content_shell_apk.ContentShellTestBase; -import org.chromium.content_shell_apk.ContentShellTestCommon.TestCommonCallback; - -/** - * Base class for content detection test suites. - */ -public class ContentDetectionTestBase - extends ContentShellTestBase implements TestCommonCallback<ContentShellActivity> { - private final ContentDetectionTestCommon mTestCommon = new ContentDetectionTestCommon(this); - - /** - * Returns the TestCallbackHelperContainer associated with this ContentView, - * or creates it lazily. - */ - protected TestCallbackHelperContainer getTestCallbackHelperContainer() { - return mTestCommon.getTestCallbackHelperContainer(); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - mTestCommon.createTestContentIntentHandler(); - } - - @SuppressWarnings("deprecation") - @Override - protected void setActivity(Activity activity) { - super.setActivity(activity); - mTestCommon.setContentHandler(); - } - - /** - * Checks if the provided test url is the current url in the content view. - * @param testUrl Test url to check. - * @return true if the test url is the current one, false otherwise. - */ - protected boolean isCurrentTestUrl(String testUrl) { - return mTestCommon.isCurrentTestUrl(testUrl); - } - - /** - * Encodes the provided content string into an escaped url as intents do. - * @param content Content to escape into a url. - * @return Escaped url. - */ - public static String urlForContent(String content) { - return ContentDetectionTestCommon.urlForContent(content); - } - - /** - * Scrolls to the node with the provided id, taps on it and waits for an intent to come. - * @param id Id of the node to scroll and tap. - * @return The content url of the received intent or null if none. - */ - protected String scrollAndTapExpectingIntent(String id) throws Throwable { - return mTestCommon.scrollAndTapExpectingIntent(id); - } - - /** - * Scrolls to the node with the provided id, taps on it and waits for a new page load to finish. - * Useful when tapping on links that take to other pages. - * @param id Id of the node to scroll and tap. - */ - protected void scrollAndTapNavigatingOut(String id) throws Throwable { - mTestCommon.scrollAndTapNavigatingOut(id); - } -} \ No newline at end of file
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestCommon.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestCommon.java deleted file mode 100644 index 0d8d96b..0000000 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestCommon.java +++ /dev/null
@@ -1,123 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.content.browser; - -import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; - -import android.net.Uri; - -import org.chromium.base.test.util.CallbackHelper; -import org.chromium.base.test.util.UrlUtils; -import org.chromium.content.browser.test.util.DOMUtils; -import org.chromium.content.browser.test.util.TestCallbackHelperContainer; -import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageFinishedHelper; -import org.chromium.content_shell.ShellViewAndroidDelegate.ContentIntentHandler; -import org.chromium.content_shell_apk.ContentShellActivity; -import org.chromium.content_shell_apk.ContentShellTestCommon.TestCommonCallback; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -public class ContentDetectionTestCommon { - private static final long WAIT_TIMEOUT_SECONDS = scaleTimeout(10); - - private final TestCommonCallback<ContentShellActivity> mCallback; - - private TestCallbackHelperContainer mCallbackHelper; - private TestContentIntentHandler mContentIntentHandler; - - public ContentDetectionTestCommon(TestCommonCallback<ContentShellActivity> callback) { - mCallback = callback; - } - - /** - * CallbackHelper for OnStartContentIntent. - */ - private static class OnStartContentIntentHelper extends CallbackHelper { - private String mIntentUrl; - public void notifyCalled(String intentUrl) { - mIntentUrl = intentUrl; - notifyCalled(); - } - public String getIntentUrl() { - assert getCallCount() > 0; - return mIntentUrl; - } - } - - /** - * ContentIntentHandler impl to test content detection. - */ - public static class TestContentIntentHandler implements ContentIntentHandler { - private OnStartContentIntentHelper mOnStartContentIntentHelper; - - public OnStartContentIntentHelper getOnStartContentIntentHelper() { - if (mOnStartContentIntentHelper == null) { - mOnStartContentIntentHelper = new OnStartContentIntentHelper(); - } - return mOnStartContentIntentHelper; - } - - @Override - public void onIntentUrlReceived(String intentUrl) { - mOnStartContentIntentHelper.notifyCalled(intentUrl); - } - } - - static String urlForContent(String content) { - return Uri.encode(content).replaceAll("%20", "+"); - } - - TestCallbackHelperContainer getTestCallbackHelperContainer() { - if (mCallbackHelper == null) { - mCallbackHelper = - new TestCallbackHelperContainer(mCallback.getContentViewCoreForTestCommon()); - } - return mCallbackHelper; - } - - void createTestContentIntentHandler() { - mContentIntentHandler = new TestContentIntentHandler(); - } - - void setContentHandler() { - mCallback.getActivityForTestCommon() - .getShellManager() - .getActiveShell() - .getViewAndroidDelegate() - .setContentIntentHandler(mContentIntentHandler); - } - - boolean isCurrentTestUrl(String testUrl) { - return UrlUtils.getIsolatedTestFileUrl(testUrl).equals( - mCallback.getContentViewCoreForTestCommon().getWebContents().getUrl()); - } - - String scrollAndTapExpectingIntent(String id) throws InterruptedException, TimeoutException { - OnStartContentIntentHelper onStartContentIntentHelper = - mContentIntentHandler.getOnStartContentIntentHelper(); - int currentCallCount = onStartContentIntentHelper.getCallCount(); - - DOMUtils.clickNode(mCallback.getContentViewCoreForTestCommon(), id); - - onStartContentIntentHelper.waitForCallback( - currentCallCount, 1, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); - mCallback.getInstrumentationForTestCommon().waitForIdleSync(); - return onStartContentIntentHelper.getIntentUrl(); - } - - void scrollAndTapNavigatingOut(String id) throws InterruptedException, TimeoutException { - TestCallbackHelperContainer callbackHelperContainer = getTestCallbackHelperContainer(); - OnPageFinishedHelper onPageFinishedHelper = - callbackHelperContainer.getOnPageFinishedHelper(); - int currentCallCount = onPageFinishedHelper.getCallCount(); - - DOMUtils.clickNode(mCallback.getContentViewCoreForTestCommon(), id); - - onPageFinishedHelper.waitForCallback( - currentCallCount, 1, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); - mCallback.getInstrumentationForTestCommon().waitForIdleSync(); - } -}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/EmailAddressDetectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/EmailAddressDetectionTest.java deleted file mode 100644 index e9a23f3..0000000 --- a/content/public/android/javatests/src/org/chromium/content/browser/EmailAddressDetectionTest.java +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2012 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.content.browser; - -import android.support.test.filters.MediumTest; - -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.content.common.ContentSwitches; - -/** - * Test suite for email address detection. - */ -@CommandLineFlags.Add({ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) -public class EmailAddressDetectionTest extends ContentDetectionTestBase { - - private static final String EMAIL_INTENT_PREFIX = "mailto:"; - - private boolean isExpectedEmailIntent(String intentUrl, String expectedContent) { - if (intentUrl == null) return false; - final String expectedUrl = EMAIL_INTENT_PREFIX + urlForContent(expectedContent); - return intentUrl.equals(expectedUrl); - } - - @MediumTest - @Feature({"ContentDetection", "TabContents"}) - @RetryOnFailure - public void testValidEmailAddresses() throws Throwable { - startActivityWithTestUrl("content/test/data/android/content_detection/email.html"); - - // valid_1: i.want.a.pony@chromium.org. - String intentUrl = scrollAndTapExpectingIntent("valid_1"); - assertTrue(isExpectedEmailIntent(intentUrl, "i.want.a.pony@chromium.org")); - - // valid_2: nyan_cat@chromium.org. - intentUrl = scrollAndTapExpectingIntent("valid_2"); - assertTrue(isExpectedEmailIntent(intentUrl, "nyan_cat@chromium.org")); - - // valid_3: 123@456.com. - intentUrl = scrollAndTapExpectingIntent("valid_3"); - assertTrue(isExpectedEmailIntent(intentUrl, "123@456.com")); - } -}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/PhoneNumberDetectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/PhoneNumberDetectionTest.java deleted file mode 100644 index ce9bf63..0000000 --- a/content/public/android/javatests/src/org/chromium/content/browser/PhoneNumberDetectionTest.java +++ /dev/null
@@ -1,221 +0,0 @@ -// Copyright 2012 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.content.browser; - -import android.support.test.filters.LargeTest; -import android.support.test.filters.MediumTest; - -import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; -import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.RetryOnFailure; -import org.chromium.content.common.ContentSwitches; - -/** - * Test suite for phone number detection. - */ -@CommandLineFlags.Add({ContentSwitches.ENABLE_CONTENT_INTENT_DETECTION}) -public class PhoneNumberDetectionTest extends ContentDetectionTestBase { - - private static final String TELEPHONE_INTENT_PREFIX = "tel:"; - - private boolean isExpectedTelephoneIntent(String intentUrl, String expectedContent) { - if (intentUrl == null) return false; - final String expectedUrl = TELEPHONE_INTENT_PREFIX + urlForContent(expectedContent); - return intentUrl.equals(expectedUrl); - } - - @LargeTest - @Feature({"ContentDetection", "TabContents"}) - @CommandLineFlags.Add(ContentSwitches.NETWORK_COUNTRY_ISO + "=US") - @RetryOnFailure - public void testInternationalNumberIntents() throws Throwable { - startActivityWithTestUrl( - "content/test/data/android/content_detection/phone_international.html"); - - // US: +1 650-253-0000. - String intentUrl = scrollAndTapExpectingIntent("US"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+16502530000")); - - // Australia: +61 2 9374 4000. - intentUrl = scrollAndTapExpectingIntent("Australia"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+61293744000")); - - // China: +86-10-62503000. - intentUrl = scrollAndTapExpectingIntent("China"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+861062503000")); - - // Hong Kong: +852-3923-5400. - intentUrl = scrollAndTapExpectingIntent("Hong Kong"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+85239235400")); - - // India: +91-80-67218000. - intentUrl = scrollAndTapExpectingIntent("India"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+918067218000")); - - // Japan: +81-3-6384-9000. - intentUrl = scrollAndTapExpectingIntent("Japan"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+81363849000")); - - // Korea: +82-2-531-9000. - intentUrl = scrollAndTapExpectingIntent("Korea"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+8225319000")); - - // Singapore: +65 6521-8000. - intentUrl = scrollAndTapExpectingIntent("Singapore"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+6565218000")); - - // Taiwan: +886 2 8729 6000. - intentUrl = scrollAndTapExpectingIntent("Taiwan"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+886287296000")); - - // Kenya: +254 20 360 1000. - intentUrl = scrollAndTapExpectingIntent("Kenya"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+254203601000")); - - // France: +33 (0)1 42 68 53 00. - intentUrl = scrollAndTapExpectingIntent("France"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+33142685300")); - - // Germany: +49 40-80-81-79-000. - intentUrl = scrollAndTapExpectingIntent("Germany"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+4940808179000")); - - // Ireland: +353 (1) 436 1001. - intentUrl = scrollAndTapExpectingIntent("Ireland"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+35314361001")); - - // Italy: +39 02-36618 300. - intentUrl = scrollAndTapExpectingIntent("Italy"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+390236618300")); - - // Netherlands: +31 (0)20-5045-100. - intentUrl = scrollAndTapExpectingIntent("Netherlands"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+31205045100")); - - // Norway: +47 22996288. - intentUrl = scrollAndTapExpectingIntent("Norway"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+4722996288")); - - // Poland: +48 (12) 68 15 300. - intentUrl = scrollAndTapExpectingIntent("Poland"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+48126815300")); - - // Russia: +7-495-644-1400. - intentUrl = scrollAndTapExpectingIntent("Russia"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+74956441400")); - - // Spain: +34 91-748-6400. - intentUrl = scrollAndTapExpectingIntent("Spain"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+34917486400")); - - // Switzerland: +41 44-668-1800. - intentUrl = scrollAndTapExpectingIntent("Switzerland"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+41446681800")); - - // UK: +44 (0)20-7031-3000. - intentUrl = scrollAndTapExpectingIntent("UK"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+442070313000")); - - // Canada: +1 514-670-8700. - intentUrl = scrollAndTapExpectingIntent("Canada"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+15146708700")); - - // Argentina: +54-11-5530-3000. - intentUrl = scrollAndTapExpectingIntent("Argentina"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+541155303000")); - - // Brazil: +55-31-2128-6800. - intentUrl = scrollAndTapExpectingIntent("Brazil"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+553121286800")); - - // Mexico: +52 55-5342-8400. - intentUrl = scrollAndTapExpectingIntent("Mexico"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+525553428400")); - - // Israel: +972-74-746-6245. - intentUrl = scrollAndTapExpectingIntent("Israel"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+972747466245")); - - // UAE: +971 4 4509500. - intentUrl = scrollAndTapExpectingIntent("UAE"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+97144509500")); - } - - @MediumTest - @Feature({"ContentDetection", "TabContents"}) - @DisabledTest(message = "crbug.com/673279") - @CommandLineFlags.Add(ContentSwitches.NETWORK_COUNTRY_ISO + "=US") - public void testLocalUSNumbers() throws Throwable { - startActivityWithTestUrl( - "content/test/data/android/content_detection/phone_local.html"); - - // US_1: 1-888-433-5788. - String intentUrl = scrollAndTapExpectingIntent("US_1"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+18884335788")); - - // US_2: 703-293-6299. - intentUrl = scrollAndTapExpectingIntent("US_2"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+17032936299")); - - // US_3: (202) 456-2121. - intentUrl = scrollAndTapExpectingIntent("US_3"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+12024562121")); - - // International numbers should still work. - intentUrl = scrollAndTapExpectingIntent("International"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+31205045100")); - } - - @MediumTest - @Feature({"ContentDetection", "TabContents"}) - @DisabledTest(message = "crbug.com/673279") - @CommandLineFlags.Add(ContentSwitches.NETWORK_COUNTRY_ISO + "=GB") - public void testLocalUKNumbers() throws Throwable { - startActivityWithTestUrl( - "content/test/data/android/content_detection/phone_local.html"); - - // GB_1: (0) 20 7323 8299. - String intentUrl = scrollAndTapExpectingIntent("GB_1"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "02073238299")); - - // GB_2: 01227865330. - intentUrl = scrollAndTapExpectingIntent("GB_2"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "01227865330")); - - // GB_3: 01963 824686. - intentUrl = scrollAndTapExpectingIntent("GB_3"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "01963824686")); - - // International numbers should still work. - intentUrl = scrollAndTapExpectingIntent("International"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+31205045100")); - } - - @MediumTest - @Feature({"ContentDetection", "TabContents"}) - @CommandLineFlags.Add(ContentSwitches.NETWORK_COUNTRY_ISO + "=FR") - @RetryOnFailure - public void testLocalFRNumbers() throws Throwable { - startActivityWithTestUrl( - "content/test/data/android/content_detection/phone_local.html"); - - // FR_1: 01 40 20 50 50. - String intentUrl = scrollAndTapExpectingIntent("FR_1"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "0140205050")); - - // FR_2: 0326475534. - intentUrl = scrollAndTapExpectingIntent("FR_2"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "0326475534")); - - // FR_3: (0) 237 211 992. - intentUrl = scrollAndTapExpectingIntent("FR_3"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "0237211992")); - - // International numbers should still work. - intentUrl = scrollAndTapExpectingIntent("International"); - assertTrue(isExpectedTelephoneIntent(intentUrl, "+31205045100")); - } -}
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 61fc77e4..0d82ed0 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -122,7 +122,7 @@ // Enables the old algorithm for processing video constraints in getUserMedia(). const base::Feature kMediaStreamOldVideoConstraints{ - "MediaStreamOldVideoConstraints", base::FEATURE_ENABLED_BY_DEFAULT}; + "MediaStreamOldVideoConstraints", base::FEATURE_DISABLED_BY_DEFAULT}; // Enables the memory coordinator. // WARNING:
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 630ab7d..4230229 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -965,10 +965,6 @@ const char kEnableAdaptiveSelectionHandleOrientation[] = "enable-adaptive-selection-handle-orientation"; -// Enable content intent detection in the renderer. -const char kEnableContentIntentDetection[] = - "enable-content-intent-detection"; - // Enable drag manipulation of longpress-triggered text selections. const char kEnableLongpressDragSelection[] = "enable-longpress-drag-selection";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index e3468c0..3b9f899 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -279,7 +279,6 @@ CONTENT_EXPORT extern const char kDisablePullToRefreshEffect[]; CONTENT_EXPORT extern const char kDisableScreenOrientationLock[]; CONTENT_EXPORT extern const char kEnableAdaptiveSelectionHandleOrientation[]; -CONTENT_EXPORT extern const char kEnableContentIntentDetection[]; CONTENT_EXPORT extern const char kEnableLongpressDragSelection[]; CONTENT_EXPORT extern const char kHideScrollbars[]; extern const char kNetworkCountryIso[];
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 3f4bbfb..b00ed864 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -35,16 +35,8 @@ "accessibility/blink_ax_tree_source.h", "accessibility/render_accessibility_impl.cc", "accessibility/render_accessibility_impl.h", - "android/address_detector.cc", - "android/address_detector.h", - "android/content_detector.cc", - "android/content_detector.h", "android/disambiguation_popup_helper.cc", "android/disambiguation_popup_helper.h", - "android/email_detector.cc", - "android/email_detector.h", - "android/phone_number_detector.cc", - "android/phone_number_detector.h", "android/renderer_date_time_picker.cc", "android/renderer_date_time_picker.h", "android/synchronous_compositor_filter.cc",
diff --git a/content/renderer/android/address_detector.cc b/content/renderer/android/address_detector.cc deleted file mode 100644 index f4a0f24..0000000 --- a/content/renderer/android/address_detector.cc +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright (c) 2012 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/renderer/android/address_detector.h" - -#include <bitset> - -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "content/common/android/address_parser.h" -#include "content/public/renderer/android_content_detection_prefixes.h" -#include "net/base/escape.h" - -namespace { - -// Maximum text length to be searched for address detection. -static const size_t kMaxAddressLength = 250; - -} // anonymous namespace - -namespace content { - -AddressDetector::AddressDetector() { -} - -AddressDetector::~AddressDetector() { -} - -GURL AddressDetector::GetIntentURL(const std::string& content_text) { - return GURL(kAddressPrefix + - net::EscapeQueryParamValue(content_text, true)); -} - -size_t AddressDetector::GetMaximumContentLength() { - return kMaxAddressLength; -} - -std::string AddressDetector::GetContentText(const base::string16& text) { - // Get the address and replace unicode bullets with commas. - base::string16 address_16 = base::CollapseWhitespace(text, false); - std::replace(address_16.begin(), address_16.end(), - static_cast<base::char16>(0x2022), static_cast<base::char16>(',')); - return base::UTF16ToUTF8(address_16); -} - -bool AddressDetector::FindContent( - const base::string16::const_iterator& begin, - const base::string16::const_iterator& end, - size_t* start_pos, - size_t* end_pos, - std::string* content_text) { - if (address_parser::FindAddress(begin, end, start_pos, end_pos)) { - content_text->assign( - GetContentText(base::string16(begin + *start_pos, begin + *end_pos))); - return true; - } - return false; -} - -} // namespace content
diff --git a/content/renderer/android/address_detector.h b/content/renderer/android/address_detector.h deleted file mode 100644 index 5734c5b..0000000 --- a/content/renderer/android/address_detector.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright (c) 2012 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_RENDERER_ANDROID_ADDRESS_DETECTOR_H_ -#define CONTENT_RENDERER_ANDROID_ADDRESS_DETECTOR_H_ - -#include <stddef.h> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "content/renderer/android/content_detector.h" -#include "url/gurl.h" - -namespace content { - -// Finds a geographical address (currently US only) in the given text string. -class AddressDetector : public ContentDetector { - public: - AddressDetector(); - ~AddressDetector() override; - - private: - // Implementation of ContentDetector. - bool FindContent(const base::string16::const_iterator& begin, - const base::string16::const_iterator& end, - size_t* start_pos, - size_t* end_pos, - std::string* content_text) override; - GURL GetIntentURL(const std::string& content_text) override; - size_t GetMaximumContentLength() override; - - std::string GetContentText(const base::string16& text); - - DISALLOW_COPY_AND_ASSIGN(AddressDetector); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_ANDROID_ADDRESS_DETECTOR_H_
diff --git a/content/renderer/android/content_detector.cc b/content/renderer/android/content_detector.cc deleted file mode 100644 index 7bf2562..0000000 --- a/content/renderer/android/content_detector.cc +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright (c) 2012 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/renderer/android/content_detector.h" - -#include "base/logging.h" -#include "third_party/WebKit/public/platform/WebPoint.h" -#include "third_party/WebKit/public/web/WebHitTestResult.h" -#include "third_party/WebKit/public/web/WebSurroundingText.h" - -using blink::WebURL; -using blink::WebHitTestResult; -using blink::WebSurroundingText; - -namespace content { - -WebURL ContentDetector::FindTappedContent(const WebHitTestResult& hit_test) { - if (hit_test.isNull()) - return WebURL(); - - std::string content_text; - if (!FindContentRange(hit_test, &content_text)) - return WebURL(); - - return GetIntentURL(content_text); -} - -bool ContentDetector::FindContentRange(const WebHitTestResult& hit_test, - std::string* content_text) { - // As the surrounding text extractor looks at maxLength/2 characters on - // either side of the hit point, we need to double max content length here. - WebSurroundingText surrounding_text; - surrounding_text.initialize(hit_test.node(), hit_test.localPoint(), - GetMaximumContentLength() * 2); - if (surrounding_text.isNull()) - return false; - - base::string16 content = surrounding_text.textContent().utf16(); - if (content.empty()) - return false; - - size_t selected_offset = surrounding_text.hitOffsetInTextContent(); - for (size_t start_offset = 0; start_offset < content.length();) { - size_t relative_start, relative_end; - if (!FindContent(content.begin() + start_offset, - content.end(), &relative_start, &relative_end, content_text)) { - break; - } else { - size_t content_start = start_offset + relative_start; - size_t content_end = start_offset + relative_end; - DCHECK(content_end <= content.length()); - - if (selected_offset >= content_start && selected_offset < content_end) - return true; - else - start_offset += relative_end; - } - } - - return false; -} - -} // namespace content
diff --git a/content/renderer/android/content_detector.h b/content/renderer/android/content_detector.h deleted file mode 100644 index ea85fc7..0000000 --- a/content/renderer/android/content_detector.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright (c) 2012 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_RENDERER_ANDROID_CONTENT_DETECTOR_H_ -#define CONTENT_RENDERER_ANDROID_CONTENT_DETECTOR_H_ - -#include <stddef.h> - -#include "base/macros.h" -#include "third_party/WebKit/public/platform/WebURL.h" -#include "url/gurl.h" - -namespace blink { -class WebHitTestResult; -} - -namespace content { - -// Base class for text-based content detectors. -class ContentDetector { - public: - virtual ~ContentDetector() {} - - // Returns an intent URL for the content around the hit_test. - // If no content is found, an empty URL will be returned. - blink::WebURL FindTappedContent(const blink::WebHitTestResult& hit_test); - - protected: - ContentDetector() {} - - // Parses the input string defined by the begin/end iterators returning true - // if the desired content is found. The start and end positions relative to - // the input iterators are returned in start_pos and end_pos. - // The end position is assumed to be non-inclusive. - virtual bool FindContent(const base::string16::const_iterator& begin, - const base::string16::const_iterator& end, - size_t* start_pos, - size_t* end_pos, - std::string* content_text) = 0; - - // Returns the intent URL that should process the content, if any. - virtual GURL GetIntentURL(const std::string& content_text) = 0; - - // Returns the maximum length of text to be extracted around the tapped - // position in order to search for content. - virtual size_t GetMaximumContentLength() = 0; - - bool FindContentRange(const blink::WebHitTestResult& hit_test, - std::string* content_text); - - DISALLOW_COPY_AND_ASSIGN(ContentDetector); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_ANDROID_CONTENT_DETECTOR_H_
diff --git a/content/renderer/android/email_detector.cc b/content/renderer/android/email_detector.cc deleted file mode 100644 index 1a0db8b0..0000000 --- a/content/renderer/android/email_detector.cc +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright (c) 2012 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/renderer/android/email_detector.h" - -#include <memory> - -#include "base/logging.h" -#include "base/strings/utf_string_conversions.h" -#include "content/public/renderer/android_content_detection_prefixes.h" -#include "net/base/escape.h" -#include "third_party/icu/source/i18n/unicode/regex.h" - -namespace { - -// Maximum length of an email address. -const size_t kMaximumEmailLength = 254; - -// Regex to match email addresses. -// This is more specific than RFC 2822 (uncommon special characters are -// disallowed) in order to avoid false positives. -// Delimiters are word boundaries to allow punctuation, quote marks etc. around -// the address. -const char kEmailRegex[] = - "\\b[A-Z0-9._%+-]+@[A-Z0-9-]+(\\.[A-Z0-9-]+)*(\\.[A-Z]{2,6})\\b"; - -} // anonymous namespace - -namespace content { - -EmailDetector::EmailDetector() { -} - -size_t EmailDetector::GetMaximumContentLength() { - return kMaximumEmailLength; -} - -GURL EmailDetector::GetIntentURL(const std::string& content_text) { - if (content_text.empty()) - return GURL(); - - return GURL(kEmailPrefix + - net::EscapeQueryParamValue(content_text, true)); -} - -bool EmailDetector::FindContent(const base::string16::const_iterator& begin, - const base::string16::const_iterator& end, - size_t* start_pos, - size_t* end_pos, - std::string* content_text) { - base::string16 utf16_input = base::string16(begin, end); - icu::UnicodeString pattern(kEmailRegex); - icu::UnicodeString input(utf16_input.data(), utf16_input.length()); - UErrorCode status = U_ZERO_ERROR; - std::unique_ptr<icu::RegexMatcher> matcher( - new icu::RegexMatcher(pattern, input, UREGEX_CASE_INSENSITIVE, status)); - if (matcher->find()) { - *start_pos = matcher->start(status); - DCHECK(U_SUCCESS(status)); - *end_pos = matcher->end(status); - DCHECK(U_SUCCESS(status)); - icu::UnicodeString content_ustr(matcher->group(status)); - DCHECK(U_SUCCESS(status)); - content_text->clear(); - content_ustr.toUTF8String(*content_text); - return true; - } - - return false; -} - -} // namespace content
diff --git a/content/renderer/android/email_detector.h b/content/renderer/android/email_detector.h deleted file mode 100644 index d3544693..0000000 --- a/content/renderer/android/email_detector.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright (c) 2012 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_RENDERER_ANDROID_EMAIL_DETECTOR_H_ -#define CONTENT_RENDERER_ANDROID_EMAIL_DETECTOR_H_ - -#include <stddef.h> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "content/common/content_export.h" -#include "content/renderer/android/content_detector.h" - -namespace content { - -class EmailDetectorTest; - -// Finds email addresses (in most common formats, but not including special -// characters) in the given text string. -class CONTENT_EXPORT EmailDetector : public ContentDetector { - public: - EmailDetector(); - - private: - friend class EmailDetectorTest; - - // Implementation of ContentDetector. - bool FindContent(const base::string16::const_iterator& begin, - const base::string16::const_iterator& end, - size_t* start_pos, - size_t* end_pos, - std::string* content_text) override; - GURL GetIntentURL(const std::string& content_text) override; - size_t GetMaximumContentLength() override; - - DISALLOW_COPY_AND_ASSIGN(EmailDetector); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_ANDROID_EMAIL_DETECTOR_H_
diff --git a/content/renderer/android/email_detector_unittest.cc b/content/renderer/android/email_detector_unittest.cc deleted file mode 100644 index 020a0fa..0000000 --- a/content/renderer/android/email_detector_unittest.cc +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright (c) 2012 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/renderer/android/email_detector.h" - -#include <stddef.h> - -#include "base/strings/utf_string_conversions.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { - -class EmailDetectorTest : public testing::Test { - public: - static void FindAndCheckEmail(const std::string& content, - const std::string& expected) { - base::string16 content_16 = base::UTF8ToUTF16(content); - base::string16 result_16; - size_t start, end; - EmailDetector detector; - std::string content_text; - if (detector.FindContent(content_16.begin(), content_16.end(), - &start, &end, &content_text)) { - result_16 = content_16.substr(start, end - start); - } - EXPECT_EQ(expected, base::UTF16ToUTF8(result_16)); - EXPECT_EQ(expected, content_text); - } -}; - -TEST_F(EmailDetectorTest, FindEmail) { - FindAndCheckEmail("please email test@testing.com", "test@testing.com"); - FindAndCheckEmail("please email test@123.456.co.uk.", "test@123.456.co.uk"); - FindAndCheckEmail("My email is 'a@b.org'.", "a@b.org"); - FindAndCheckEmail("123@bcd.org", "123@bcd.org"); - FindAndCheckEmail("[quitelongwelllongemailaddress@somequitelongdomain.org]", - "quitelongwelllongemailaddress@somequitelongdomain.org"); - FindAndCheckEmail("Should find the first@email.org not the second@email.org", - "first@email.org"); - FindAndCheckEmail("Email:HELLO@SOMETHING.COM", "HELLO@SOMETHING.COM"); - FindAndCheckEmail("Email SOMEONE@GOOGLE.COM for details.", - "SOMEONE@GOOGLE.COM"); - FindAndCheckEmail("It's \"testadd@company.fr\"", "testadd@company.fr"); - FindAndCheckEmail("This is not an @emailaddress.com", ""); - FindAndCheckEmail("Apples @2.50 each", ""); - FindAndCheckEmail("Log on to google.com", ""); - FindAndCheckEmail("Try someone@, they might know.", ""); - FindAndCheckEmail("No, bob@com is not an email address.", ""); - FindAndCheckEmail("@", ""); - FindAndCheckEmail("Just bob @google.com", ""); - FindAndCheckEmail("Why not call larry@google and ask him.", ""); - FindAndCheckEmail("Lets test invalid invalid@email..com address", ""); - FindAndCheckEmail("Invalid dots are bad invalid@.email.com address", ""); -} - -} // namespace content
diff --git a/content/renderer/android/phone_number_detector.cc b/content/renderer/android/phone_number_detector.cc deleted file mode 100644 index 871ee85..0000000 --- a/content/renderer/android/phone_number_detector.cc +++ /dev/null
@@ -1,93 +0,0 @@ -// Copyright (c) 2012 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/renderer/android/phone_number_detector.h" - -#include <algorithm> - -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "content/public/renderer/android_content_detection_prefixes.h" -#include "net/base/escape.h" -#include "third_party/libphonenumber/dist/cpp/src/phonenumbers/phonenumbermatch.h" -#include "third_party/libphonenumber/dist/cpp/src/phonenumbers/phonenumbermatcher.h" -#include "third_party/libphonenumber/dist/cpp/src/phonenumbers/region_code.h" -#include "third_party/libphonenumber/phonenumber_api.h" - -using i18n::phonenumbers::PhoneNumberMatch; -using i18n::phonenumbers::PhoneNumberMatcher; -using i18n::phonenumbers::PhoneNumberUtil; -using i18n::phonenumbers::RegionCode; - -namespace { - -// Maximum number of characters to look around for phone number detection. -const size_t kMaximumTelephoneLength = 20; - -} // anonymous namespace - -namespace content { - -PhoneNumberDetector::PhoneNumberDetector() - : region_code_(RegionCode::GetUnknown()) { -} - -// Region should be empty or an ISO 3166-1 alpha-2 country code. -PhoneNumberDetector::PhoneNumberDetector(const std::string& region) - : region_code_(region.empty() ? RegionCode::GetUnknown() - : base::ToUpperASCII(region)) { -} - -PhoneNumberDetector::~PhoneNumberDetector() { -} - -size_t PhoneNumberDetector::GetMaximumContentLength() { - return kMaximumTelephoneLength; -} - -GURL PhoneNumberDetector::GetIntentURL(const std::string& content_text) { - if (content_text.empty()) - return GURL(); - - return GURL(kPhoneNumberPrefix + - net::EscapeQueryParamValue(content_text, true)); -} - -bool PhoneNumberDetector::FindContent( - const base::string16::const_iterator& begin, - const base::string16::const_iterator& end, - size_t* start_pos, - size_t* end_pos, - std::string* content_text) { - base::string16 utf16_input = base::string16(begin, end); - std::string utf8_input = base::UTF16ToUTF8(utf16_input); - - PhoneNumberUtil* phone_util = PhoneNumberUtil::GetInstance(); - if (phone_util->IsAlphaNumber(utf8_input)) - phone_util->ConvertAlphaCharactersInNumber(&utf8_input); - PhoneNumberMatcher matcher(utf8_input, region_code_); - if (matcher.HasNext()) { - PhoneNumberMatch match; - matcher.Next(&match); - phone_util->FormatNumberForMobileDialing(match.number(), region_code_, - false, /* with_formatting */ - content_text); - - // If the number can't be dialed from the current region, the formatted - // string will be empty. - if (content_text->empty()) - return false; - - // Need to return start_pos and end_pos relative to a UTF16 encoding. - *start_pos = - base::UTF8ToUTF16(utf8_input.substr(0, match.start())).length(); - *end_pos = *start_pos + base::UTF8ToUTF16(match.raw_string()).length(); - - return true; - } - - return false; -} - -} // namespace content
diff --git a/content/renderer/android/phone_number_detector.h b/content/renderer/android/phone_number_detector.h deleted file mode 100644 index 2d6b4d27..0000000 --- a/content/renderer/android/phone_number_detector.h +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright (c) 2012 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_RENDERER_ANDROID_PHONE_NUMBER_DETECTOR_H_ -#define CONTENT_RENDERER_ANDROID_PHONE_NUMBER_DETECTOR_H_ - -#include <stddef.h> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "content/common/content_export.h" -#include "content/renderer/android/content_detector.h" - -namespace content { - -class PhoneNumberDetectorTest; - -// Finds a telephone number in the given content text string. -class CONTENT_EXPORT PhoneNumberDetector : public ContentDetector { - public: - PhoneNumberDetector(); - explicit PhoneNumberDetector(const std::string& region); - ~PhoneNumberDetector() override; - - private: - friend class PhoneNumberDetectorTest; - - // Implementation of ContentDetector. - bool FindContent(const base::string16::const_iterator& begin, - const base::string16::const_iterator& end, - size_t* start_pos, - size_t* end_pos, - std::string* content_text) override; - GURL GetIntentURL(const std::string& content_text) override; - size_t GetMaximumContentLength() override; - - const std::string region_code_; - - DISALLOW_COPY_AND_ASSIGN(PhoneNumberDetector); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_ANDROID_PHONE_NUMBER_DETECTOR_H_
diff --git a/content/renderer/android/phone_number_detector_unittest.cc b/content/renderer/android/phone_number_detector_unittest.cc deleted file mode 100644 index 474003b0..0000000 --- a/content/renderer/android/phone_number_detector_unittest.cc +++ /dev/null
@@ -1,91 +0,0 @@ -// Copyright (c) 2012 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/renderer/android/phone_number_detector.h" - -#include <stddef.h> - -#include "base/strings/utf_string_conversions.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace content { - -class PhoneNumberDetectorTest : public testing::Test { - public: - static std::string FindNumber(const std::string& content, - const std::string& region) { - base::string16 content_16 = base::UTF8ToUTF16(content); - base::string16 result_16; - size_t start, end; - PhoneNumberDetector detector(region); - std::string content_text; - if (detector.FindContent(content_16.begin(), content_16.end(), - &start, &end, &content_text)) - result_16 = content_16.substr(start, end - start); - return base::UTF16ToUTF8(result_16); - } - - static std::string FindAndFormatNumber(const std::string& content, - const std::string& region) { - base::string16 content_16 = base::UTF8ToUTF16(content); - base::string16 result_16; - size_t start, end; - PhoneNumberDetector detector(region); - std::string content_text; - detector.FindContent(content_16.begin(), content_16.end(), - &start, &end, &content_text); - return content_text; - } -}; - -TEST_F(PhoneNumberDetectorTest, FindNumber) { - // Tests cases with valid home numbers. - EXPECT_EQ("617-426-3000", FindNumber("hello 617-426-3000 blah", "us")); - EXPECT_EQ("", FindNumber("hello 617-426-3000 blah", "gb")); - EXPECT_EQ("020-7617-4426", FindNumber("<div>020-7617-4426</div>", "gb")); - EXPECT_EQ("", FindNumber("<div>020-7617-4426</div>", "fr")); - EXPECT_EQ("02.38.96.68.88", FindNumber("Tel:02.38.96.68.88", "fr")); - EXPECT_EQ("", FindNumber("Tel:02.38.96.68.88", "gb")); - EXPECT_EQ("1-800-866-2453", - FindNumber("You can call this number:1-800-866-2453 for more " - "information", "us")); - EXPECT_EQ("+1 203-925-4602", FindNumber("+1 203-925-4602", "us")); -} - -TEST_F(PhoneNumberDetectorTest, FindAndFormatNumber) { - EXPECT_EQ("+16174263000", - FindAndFormatNumber("hello 617-426-3000 blah", "us")); - EXPECT_EQ("", FindAndFormatNumber("hello 617-426-3000 blah", "gb")); - EXPECT_EQ("02076174426", - FindAndFormatNumber("<div>020-7617-4426</div>", "gb")); - EXPECT_EQ("", FindAndFormatNumber("<div>020-7617-4426</div>", "fr")); - EXPECT_EQ("0238966888", FindAndFormatNumber("Tel:02.38.96.68.88", "fr")); - EXPECT_EQ("+18008662453", - FindAndFormatNumber("You can call this number:1-800-866-2453 for" - "more information", "us")); - EXPECT_EQ("+12039254602", FindAndFormatNumber("+1 203-925-4602", "us")); - - // "+1 (650) 333-6000" using fullwidth UTF-8 characters. - EXPECT_EQ("+16503336000", FindAndFormatNumber( - "\xEF\xBC\x8B\xEF\xBC\x91\xE3\x80\x80\xEF\xBC\x88" - "\xEF\xBC\x96\xEF\xBC\x95\xEF\xBC\x90\xEF\xBC\x89" - "\xE3\x80\x80\xEF\xBC\x93\xEF\xBC\x93\xEF\xBC\x93" - "\xE3\x83\xBC\xEF\xBC\x96\xEF\xBC\x90\xEF\xBC\x90" - "\xEF\xBC\x90", "us")); -} - -TEST_F(PhoneNumberDetectorTest, FindAndFormatAlphaNumber) { - // Tests cases with valid alpha numbers. - EXPECT_EQ("+18002378289", FindAndFormatNumber("1 800-BestBuy", "us")); - EXPECT_EQ("+18002378289", FindAndFormatNumber("1-800-BEST-BUY", "us")); - EXPECT_EQ("+18002378289", FindAndFormatNumber("1-800-BEST BUY", "us")); - // TODO(qinmin): support alpha number detection when there are characters on - // either side of the string. - EXPECT_EQ("", FindAndFormatNumber("hello 1-800-BEST-BUY", "us")); - EXPECT_EQ("", FindAndFormatNumber("BestBuy", "us")); - EXPECT_EQ("", FindAndFormatNumber("1-BestBuy", "us")); - EXPECT_EQ("", FindAndFormatNumber("1 BestBuy", "us")); -} - -} // namespace content
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index ea44ac5..3c12a24 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -181,11 +181,7 @@ #include <cpu-features.h> #include "base/android/build_info.h" -#include "content/renderer/android/address_detector.h" -#include "content/renderer/android/content_detector.h" #include "content/renderer/android/disambiguation_popup_helper.h" -#include "content/renderer/android/email_detector.h" -#include "content/renderer/android/phone_number_detector.h" #include "ui/gfx/geometry/rect_f.h" #elif defined(OS_MACOSX) @@ -284,12 +280,6 @@ const int kDelaySecondsForContentStateSyncHidden = 5; const int kDelaySecondsForContentStateSync = 1; -#if defined(OS_ANDROID) -// Delay between tapping in content and launching the associated android intent. -// Used to allow users see what has been recognized as content. -const size_t kContentIntentDelayMilliseconds = 700; -#endif - static RenderViewImpl* (*g_create_render_view_impl)( CompositorDependencies* compositor_deps, const mojom::CreateViewParams&) = nullptr; @@ -601,7 +591,6 @@ frame_widget_(nullptr), speech_recognition_dispatcher_(NULL), #if defined(OS_ANDROID) - expected_content_intent_id_(0), was_created_by_renderer_(false), #endif enumeration_completion_id_(0), @@ -708,17 +697,6 @@ if (main_render_frame_) main_render_frame_->Initialize(); -#if defined(OS_ANDROID) - content_detectors_.push_back(base::MakeUnique<AddressDetector>()); - const std::string& contry_iso = - params.renderer_preferences.network_contry_iso; - if (!contry_iso.empty()) { - content_detectors_.push_back( - base::MakeUnique<PhoneNumberDetector>(contry_iso)); - } - content_detectors_.push_back(base::MakeUnique<EmailDetector>()); -#endif - // If this RenderView's creation was initiated by an opener page in this // process, (e.g. window.open()), we won't be visible until we ask the opener, // via show_callback, to make us visible. Otherwise, we went through a @@ -2428,61 +2406,7 @@ main_render_frame_->GetRoutingID(), signals)); } -// TODO(dglazkov): Remove this ifdef. The content detection code -// should not be platform-specific. -// See http://crbug.com/635214 for details. #if defined(OS_ANDROID) -WebURL RenderViewImpl::detectContentIntentAt( - const WebHitTestResult& touch_hit) { - // TODO(twellington): Remove content detection entirely. It is - // currently only enabled for tests. crbug.com/664307. - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableContentIntentDetection)) { - return WebURL(); - } - DCHECK(touch_hit.node().isTextNode()); - - // Process the position with all the registered content detectors until - // a match is found. Priority is provided by their relative order. - for (const auto& detector : content_detectors_) { - WebURL intent = detector->FindTappedContent(touch_hit); - if (intent.isValid()) { - return intent; - } - } - return WebURL(); -} - -void RenderViewImpl::scheduleContentIntent(const WebURL& intent, - bool is_main_frame) { - // Introduce a short delay so that the user can notice the content. - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, base::Bind(&RenderViewImpl::LaunchAndroidContentIntent, - weak_ptr_factory_.GetWeakPtr(), intent, - expected_content_intent_id_, is_main_frame), - base::TimeDelta::FromMilliseconds(kContentIntentDelayMilliseconds)); -} - -void RenderViewImpl::cancelScheduledContentIntents() { - ++expected_content_intent_id_; -} - -void RenderViewImpl::LaunchAndroidContentIntent(const GURL& intent, - size_t request_id, - bool is_main_frame) { - if (request_id != expected_content_intent_id_) - return; - - // Remove the content highlighting if any. - if (RenderWidgetCompositor* rwc = compositor()) - rwc->setNeedsBeginFrame(); - - if (!intent.is_empty()) { - Send(new ViewHostMsg_StartContentIntent(GetRoutingID(), intent, - is_main_frame)); - } -} - bool RenderViewImpl::openDateTimeChooser( const blink::WebDateTimeChooserParams& params, blink::WebDateTimeChooserCompletion* completion) {
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 6fae3db..7fbcc0d1 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -60,7 +60,6 @@ #include "ui/surface/transport_dib.h" #if defined(OS_ANDROID) -#include "content/renderer/android/content_detector.h" #include "content/renderer/android/renderer_date_time_picker.h" #endif @@ -86,10 +85,6 @@ struct WebPluginAction; struct WebPoint; struct WebWindowFeatures; - -#if defined(OS_ANDROID) -class WebHitTestResult; -#endif } // namespace blink namespace gfx { @@ -344,12 +339,6 @@ void didFocus() override; #if defined(OS_ANDROID) - void scheduleContentIntent(const blink::WebURL& intent, - bool is_main_frame) override; - void cancelScheduledContentIntents() override; - blink::WebURL detectContentIntentAt( - const blink::WebHitTestResult& touch_hit) override; - // Only used on Android since all other platforms implement // date and time input fields using MULTIPLE_FIELDS_UI bool openDateTimeChooser(const blink::WebDateTimeChooserParams&, @@ -584,10 +573,6 @@ void CheckPreferredSize(); #if defined(OS_ANDROID) - // Launch an Android content intent with the given URL. - void LaunchAndroidContentIntent(const GURL& intent_url, - size_t request_id, - bool is_main_frame); // Make the video capture devices (e.g. webcam) stop/resume delivering video // frames to their clients, depending on flag |suspend|. This is called in // response to a RenderView PageHidden/Shown(). @@ -800,13 +785,6 @@ #if defined(OS_ANDROID) // Android Specific --------------------------------------------------------- - // Expected id of the next content intent launched. Used to prevent scheduled - // intents to be launched if aborted. - size_t expected_content_intent_id_; - - // List of click-based content detectors. - std::vector<std::unique_ptr<ContentDetector>> content_detectors_; - // A date/time picker object for date and time related input elements. std::unique_ptr<RendererDateTimePicker> date_time_picker_client_;
diff --git a/content/shell/android/java/src/org/chromium/content_shell/ShellViewAndroidDelegate.java b/content/shell/android/java/src/org/chromium/content_shell/ShellViewAndroidDelegate.java index b1102b3..0e51e9d 100644 --- a/content/shell/android/java/src/org/chromium/content_shell/ShellViewAndroidDelegate.java +++ b/content/shell/android/java/src/org/chromium/content_shell/ShellViewAndroidDelegate.java
@@ -4,7 +4,6 @@ package org.chromium.content_shell; -import android.content.Intent; import android.view.ViewGroup; import org.chromium.ui.base.ViewAndroidDelegate; @@ -15,36 +14,11 @@ */ public class ShellViewAndroidDelegate extends ViewAndroidDelegate { private final ViewGroup mContainerView; - private ContentIntentHandler mContentIntentHandler; - - /** - * Interface used to define/modify what {@link #startContentIntent} does. - */ - public interface ContentIntentHandler { - /** - * Called when intent url from content is received. - * @param intentUrl intent url. - */ - void onIntentUrlReceived(String intentUrl); - } public ShellViewAndroidDelegate(ViewGroup containerView) { mContainerView = containerView; } - /** - * Set the {@link ContentIntentHandler} for {@link #starContentIntent}. - * @param handler Handler to inject to {@link #startContentIntent}. - */ - public void setContentIntentHandler(ContentIntentHandler handler) { - mContentIntentHandler = handler; - } - - @Override - public void startContentIntent(Intent intent, String intentUrl, boolean isMainFrame) { - if (mContentIntentHandler != null) mContentIntentHandler.onIntentUrlReceived(intentUrl); - } - @Override public ViewGroup getContainerView() { return mContainerView;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 99d23d1f..013db3b 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1390,8 +1390,6 @@ "../common/webplugininfo_unittest.cc", "../public/test/referrer_unittest.cc", "../renderer/android/disambiguation_popup_helper_unittest.cc", - "../renderer/android/email_detector_unittest.cc", - "../renderer/android/phone_number_detector_unittest.cc", "../renderer/bmp_image_decoder_unittest.cc", "../renderer/categorized_worker_pool_unittest.cc", "../renderer/device_sensors/device_light_event_pump_unittest.cc",
diff --git a/content/test/data/android/content_detection/click_listeners.html b/content/test/data/android/content_detection/click_listeners.html deleted file mode 100644 index b4fd5104..0000000 --- a/content/test/data/android/content_detection/click_listeners.html +++ /dev/null
@@ -1,26 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> -</head> -<body> -Blah blah <a href="empty.html">Excepteur sint 1818 Library Street <span id="linktest">Suite</span> 400, VA 20190 occaecat cupidatat</a><br> - -<!-- Click listeners --> -<span onclick="javascript:window.location.href='empty.html'"> -blah 1818 <span id="clicktest1">Library</span> Street <br> -Suite 400, VA 20190 blah <br> -</span><br> - -<span id="clicklistener"> -blah 1818 Library Street <br> -Suite <span id="clicktest2">400</span>, VA 20190 blah <br> -</span><br> - -<script language=javascript> -var blah = document.getElementById('clicklistener'); -blah.addEventListener('click', function() { window.location.href = "empty.html"; }); -</script> - -</body> -</html>
diff --git a/content/test/data/android/content_detection/email.html b/content/test/data/android/content_detection/email.html deleted file mode 100644 index 0e5f00d68..0000000 --- a/content/test/data/android/content_detection/email.html +++ /dev/null
@@ -1,19 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> -</head> -<body> - -<!-- Examples of valid email addresses --> -<span id="valid_1">i.want.a.pony@chromium.org</span></br> -<span id="valid_2">nyan_cat@chromium.org</span></br> -<span id="valid_3">123@456.com</span></br> - -<!-- Examples of invalid email addresses --> -<span id="invalid_1">username@password</span></br> -<span id="invalid_2">meh@@hiybbprqag.com</span></br> -<span id="invalid_3">@chromium.org</span></br> - -</body> -</html>
diff --git a/content/test/data/android/content_detection/empty.html b/content/test/data/android/content_detection/empty.html deleted file mode 100644 index bd54434..0000000 --- a/content/test/data/android/content_detection/empty.html +++ /dev/null
@@ -1,3 +0,0 @@ -<!DOCTYPE html> -<html> -</html>
diff --git a/content/test/data/android/content_detection/geo_address_limits.html b/content/test/data/android/content_detection/geo_address_limits.html deleted file mode 100644 index 29f8ab1..0000000 --- a/content/test/data/android/content_detection/geo_address_limits.html +++ /dev/null
@@ -1,25 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> -</head> -<body> - -<!-- Contiguous addresses --> -<p> -Non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 2590 Pearl Street Suite 100 Boulder, CO <span id="test1">80302</span> <span id="test2">6425</span> Penn Ave. Suite 700 Pittsburgh, PA 15206 -</p> - -<!-- Limited address exploration --> -<div><b>12</b></div> <div><span id="test3">34</span> Main St. Boston, MA 02118</div> - -<!-- Unformatted contents --> -<pre> - - 1600 -Amphitheatre Parkway -<span id="test4">Mountain</span> -View, CA 94043 </pre> - -</body> -</html>
diff --git a/content/test/data/android/content_detection/geo_address_multiple.html b/content/test/data/android/content_detection/geo_address_multiple.html deleted file mode 100644 index 7148432..0000000 --- a/content/test/data/android/content_detection/geo_address_multiple.html +++ /dev/null
@@ -1,19 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> -</head> -<body> - -<!-- Multiple addresses in text --> -<p> - 1600 -Amphitheatre <span id="test1">Parkway</span> -Mountain -View, CA 94043, United States -(650) 253-0000 -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 76 Ninth Avenue 4th <span id="test2">Floor</span> New York, NY 10011 nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. -</p> - -</body> -</html>
diff --git a/content/test/data/android/content_detection/geo_address_real.html b/content/test/data/android/content_detection/geo_address_real.html deleted file mode 100644 index 509949e6..0000000 --- a/content/test/data/android/content_detection/geo_address_real.html +++ /dev/null
@@ -1,20 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> -</head> -<body> - -<!-- A few unusual real cases --> -<address>57th Street and Lake <span id="test1">Shore</span> Drive <br />Chicago, IL 60637</address><address>Main: (773) 684-1414<br />TTY: (773) 753-1351</address><br> - -<div class="street-address">57th Street and Lake Shore <span id="test2">Drive</span></div> -<span class="locality">Chicago</span>, <span class="region">IL</span> <span class="postal-code">60637</span><br> - -<div class="street-address">57th Street and Lake Shore Drive -<span class="locality">Chicago</span>, <span class="region" id="test3">IL</span> <span class="postal-code">60637</span></div><br> - -<li class="lastItem">Central Park West at 79th <span id="test4">Street</span>, New York, NY, 10024-5192</li> - -</body> -</html>
diff --git a/content/test/data/android/content_detection/geo_address_special_chars.html b/content/test/data/android/content_detection/geo_address_special_chars.html deleted file mode 100644 index 7c626c4..0000000 --- a/content/test/data/android/content_detection/geo_address_special_chars.html +++ /dev/null
@@ -1,13 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> -</head> -<body> - -<!-- Correct handling of • and --> -<p>Lincoln Park | 100 34th <span id="test1">Avenue</span> • San Francisco, CA 94121 | 415.750.3600</p> -<p>Lincoln Park | 100 34th Avenue San <span id="test2">Francisco</span>, CA 94121 | 415.750.3600</p> - -</body> -</html>
diff --git a/content/test/data/android/content_detection/geo_address_split.html b/content/test/data/android/content_detection/geo_address_split.html deleted file mode 100644 index c529625..0000000 --- a/content/test/data/android/content_detection/geo_address_split.html +++ /dev/null
@@ -1,19 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> -</head> -<body> - -<!-- Address split by <br> --!> -blah 9606 North MoPac Expressway <br> -<span id="test1">Suite</span> 400<br> - Austin, TX <br> - 78759<br>blah - -<!-- Address split by scripts and comments --!> -<p>blah 1818 <span id="test2">Library</span> <!-- blah blah blah --!> Street <span id="test3">Suite</span> -<script language=javascript>/* This is a comment */</script>400, <span id="test4">VA</span> 20190 blah</p> - -</body> -</html>
diff --git a/content/test/data/android/content_detection/phone_international.html b/content/test/data/android/content_detection/phone_international.html deleted file mode 100644 index 7c3a8092..0000000 --- a/content/test/data/android/content_detection/phone_international.html +++ /dev/null
@@ -1,39 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> -</head> -<body> - -<!-- International phone numbers from different Google offices --> -<!-- The spans point where to tap, but don't define the content boundaries --> -<span id="US">+1 650-253-0000</span></br> -<span id="Australia">+61 2 9374 4000</span></br> -<span id="China">+86-10-62503000</span></br> -<span id="Hong Kong">+852-3923-5400</span></br> -<span id="India">+91-80-67218000</span></br> -<span id="Japan">+81-3-6384-9000</span></br> -<span id="Korea">+82-2-531-9000</span></br> -<span id="Singapore">+65 6521-8000</span></br> -<span id="Taiwan">+886 2 8729 6000</span></br> -<span id="Kenya">+254 20 360 1000</span></br> -<span id="France">+33 (0)1 42 68 53 00</span></br> -<span id="Germany">+49 40-80-81-79-000</span></br> -<span id="Ireland">+353 (1) 436 1001</span></br> -<span id="Italy">+39 02-36618 300</span></br> -<span id="Netherlands">+31 (0)20-5045-100</span></br> -<span id="Norway">+47 22996288</span></br> -<span id="Poland">+48 (12) 68 15 300</span></br> -<span id="Russia">+7-495-644-1400</span></br> -<span id="Spain">+34 91-748-6400</span></br> -<span id="Switzerland">+41 44-668-1800</span></br> -<span id="UK">+44 (0)20-7031-3000</span></br> -<span id="Canada">+1 514-670-8700</span></br> -<span id="Argentina">+54-11-5530-3000</span></br> -<span id="Brazil">+55-31-2128-6800</span></br> -<span id="Mexico">+52 55-5342-8400</span></br> -<span id="Israel">+972-74-746-6245</span></br> -<span id="UAE">+971 4 4509500</span></br> - -</body> -</html>
diff --git a/content/test/data/android/content_detection/phone_local.html b/content/test/data/android/content_detection/phone_local.html deleted file mode 100644 index a3feda7..0000000 --- a/content/test/data/android/content_detection/phone_local.html +++ /dev/null
@@ -1,27 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> -</head> -<body> - -<!-- Local US numbers --> -<span id="US_1">1-888-433-5788</span></br> -<span id="US_2">703-293-6299</span></br> -<span id="US_3">(202) 456-2121</span></br> - -<!-- Local UK/GB numbers --> -<span id="GB_1">(0) 20 7323 8299</span></br> -<span id="GB_2">01227865330</span></br> -<span id="GB_3">01963 824686</span></br> - -<!-- Local FR numbers --> -<span id="FR_1">01 40 20 50 50</span></br> -<span id="FR_2">0326475534</span></br> -<span id="FR_3">(0) 237 211 992</span></br> - -<!-- International numbers should still work in local modes --> -<span id="International">+31 (0)20-5045-100</span></br> - -</body> -</html>
diff --git a/content/test/gpu/gpu_tests/pixel_expectations.py b/content/test/gpu/gpu_tests/pixel_expectations.py index 23a0c98e..aa3ae6ed 100644 --- a/content/test/gpu/gpu_tests/pixel_expectations.py +++ b/content/test/gpu/gpu_tests/pixel_expectations.py
@@ -28,6 +28,12 @@ self.Fail('Pixel_ScissorTestWithPreserveDrawingBuffer', ['android'], bug=521588) + # TODO(junov) needs new baseline + self.Fail('Pixel_OffscreenCanvasTransferToImageBitmap', + bug=585607) + self.Fail('Pixel_OffscreenCanvasTransferToImageBitmapWorker', + bug=585607) + # TODO(ccameron) fix these on Mac Retina self.Fail('Pixel_CSS3DBlueBox', ['mac'], bug=533690)
diff --git a/content/test/gpu/gpu_tests/pixel_test_pages.py b/content/test/gpu/gpu_tests/pixel_test_pages.py index 48aa660..4046f2b 100644 --- a/content/test/gpu/gpu_tests/pixel_test_pages.py +++ b/content/test/gpu/gpu_tests/pixel_test_pages.py
@@ -306,14 +306,14 @@ 'pixel_offscreenCanvas_transferToImageBitmap_main.html', base_name + '_OffscreenCanvasTransferToImageBitmap', test_rect=[0, 0, 300, 300], - revision=1, + revision=2, browser_args=browser_args), PixelTestPage( 'pixel_offscreenCanvas_transferToImageBitmap_worker.html', base_name + '_OffscreenCanvasTransferToImageBitmapWorker', test_rect=[0, 0, 300, 300], - revision=1, + revision=2, browser_args=browser_args), PixelTestPage(
diff --git a/docs/clang_tool_refactoring.md b/docs/clang_tool_refactoring.md index 9b49df1..9fc3a7f 100644 --- a/docs/clang_tool_refactoring.md +++ b/docs/clang_tool_refactoring.md
@@ -125,13 +125,6 @@ ninja -C out/Debug $gen_targets ``` -On Windows, generate the compile DB first, and after making any source changes. -Then omit the `--generate-compdb` in later steps. - -```shell -tools/clang/scripts/generate_win_compdb.py out/Debug -``` - Then run the actual clang tool to generate a list of edits: ```shell
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 02a49b2..aee589d 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -244,6 +244,7 @@ "quota_service.h", "renderer_startup_helper.cc", "renderer_startup_helper.h", + "requirements_checker.cc", "requirements_checker.h", "runtime_data.cc", "runtime_data.h", @@ -452,6 +453,7 @@ "process_map_unittest.cc", "quota_service_unittest.cc", "renderer_startup_helper_unittest.cc", + "requirements_checker_unittest.cc", "runtime_data_unittest.cc", "sandboxed_unpacker_unittest.cc", "updater/update_service_unittest.cc",
diff --git a/extensions/browser/DEPS b/extensions/browser/DEPS index 99095ce4..bc6d14a 100644 --- a/extensions/browser/DEPS +++ b/extensions/browser/DEPS
@@ -19,6 +19,7 @@ "+device/serial", "+device/usb", "+google_apis/gaia", + "+gpu/config", "+grit/extensions_strings.h", "+net", # This directory contains build flags and does not pull all of PPAPI in.
diff --git a/extensions/browser/api/management/management_api.cc b/extensions/browser/api/management/management_api.cc index c723341f..8f4df2a34 100644 --- a/extensions/browser/api/management/management_api.cc +++ b/extensions/browser/api/management/management_api.cc
@@ -447,9 +447,8 @@ if (prefs->GetDisableReasons(extension_id_) & Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { // Recheck the requirements. - requirements_checker_ = delegate->CreateRequirementsChecker(); - requirements_checker_->Check( - extension, + requirements_checker_ = base::MakeUnique<RequirementsChecker>(extension); + requirements_checker_->Start( base::Bind(&ManagementSetEnabledFunction::OnRequirementsChecked, this)); // This bind creates a reference. return RespondLater(); @@ -478,15 +477,15 @@ } void ManagementSetEnabledFunction::OnRequirementsChecked( - const std::vector<std::string>& requirements_errors) { - if (requirements_errors.empty()) { + PreloadCheck::Errors errors) { + if (errors.empty()) { ManagementAPI::GetFactoryInstance()->Get(browser_context())->GetDelegate()-> EnableExtension(browser_context(), extension_id_); Respond(NoArguments()); } else { // TODO(devlin): Should we really be noisy here all the time? Respond(Error(keys::kMissingRequirementsError, - base::JoinString(requirements_errors, " "))); + base::UTF16ToUTF8(requirements_checker_->GetErrorMessage()))); } }
diff --git a/extensions/browser/api/management/management_api.h b/extensions/browser/api/management/management_api.h index 785af73..e699ece8 100644 --- a/extensions/browser/api/management/management_api.h +++ b/extensions/browser/api/management/management_api.h
@@ -16,6 +16,7 @@ #include "extensions/browser/extension_event_histogram_value.h" #include "extensions/browser/extension_function.h" #include "extensions/browser/extension_registry_observer.h" +#include "extensions/browser/preload_check.h" struct WebApplicationInfo; @@ -112,7 +113,7 @@ private: void OnInstallPromptDone(bool did_accept); - void OnRequirementsChecked(const std::vector<std::string>& requirements); + void OnRequirementsChecked(PreloadCheck::Errors errors); std::string extension_id_;
diff --git a/extensions/browser/api/management/management_api_delegate.h b/extensions/browser/api/management/management_api_delegate.h index b221907..7a0e461c 100644 --- a/extensions/browser/api/management/management_api_delegate.h +++ b/extensions/browser/api/management/management_api_delegate.h
@@ -25,7 +25,6 @@ class ManagementGenerateAppForLinkFunction; class ManagementGetPermissionWarningsByManifestFunction; class ManagementUninstallFunctionBase; -class RequirementsChecker; // Manages the lifetime of the install prompt. class InstallPromptDelegate { @@ -83,10 +82,6 @@ const Extension* extension, const base::Callback<void(bool)>& callback) const = 0; - // Returns a new RequirementsChecker. - virtual std::unique_ptr<RequirementsChecker> CreateRequirementsChecker() - const = 0; - // Enables the extension identified by |extension_id|. virtual void EnableExtension(content::BrowserContext* context, const std::string& extension_id) const = 0;
diff --git a/extensions/browser/preload_check.h b/extensions/browser/preload_check.h index 5050d54..d3445ff 100644 --- a/extensions/browser/preload_check.h +++ b/extensions/browser/preload_check.h
@@ -27,6 +27,9 @@ BLACKLISTED_ID, BLACKLISTED_UNKNOWN, DISALLOWED_BY_POLICY, + NPAPI_NOT_SUPPORTED, + WEBGL_NOT_SUPPORTED, + WINDOW_SHAPE_NOT_SUPPORTED, }; using Errors = std::set<Error>;
diff --git a/extensions/browser/requirements_checker.cc b/extensions/browser/requirements_checker.cc new file mode 100644 index 0000000..a70b043 --- /dev/null +++ b/extensions/browser/requirements_checker.cc
@@ -0,0 +1,99 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/requirements_checker.h" + +#include "base/bind.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/gpu_feature_checker.h" +#include "extensions/common/extension.h" +#include "extensions/common/manifest_handlers/requirements_info.h" +#include "extensions/strings/grit/extensions_strings.h" +#include "gpu/config/gpu_feature_type.h" +#include "ui/base/l10n/l10n_util.h" + +namespace extensions { + +RequirementsChecker::RequirementsChecker( + scoped_refptr<const Extension> extension) + : PreloadCheck(extension), weak_ptr_factory_(this) {} + +RequirementsChecker::~RequirementsChecker() {} + +void RequirementsChecker::Start(ResultCallback callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + const RequirementsInfo& requirements = + RequirementsInfo::GetRequirements(extension()); + +#if defined(OS_POSIX) && !defined(OS_MACOSX) + if (requirements.npapi) + errors_.insert(NPAPI_NOT_SUPPORTED); +#endif + +#if !defined(USE_AURA) + if (requirements.window_shape) + errors_.insert(WINDOW_SHAPE_NOT_SUPPORTED); +#endif + + callback_ = std::move(callback); + if (requirements.webgl) { + webgl_checker_ = content::GpuFeatureChecker::Create( + gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL, + base::Bind(&RequirementsChecker::VerifyWebGLAvailability, + weak_ptr_factory_.GetWeakPtr())); + webgl_checker_->CheckGpuFeatureAvailability(); + } else { + PostRunCallback(); + } +} + +base::string16 RequirementsChecker::GetErrorMessage() const { + // Join the error messages into one string. + std::vector<std::string> messages; +#if defined(OS_POSIX) && !defined(OS_MACOSX) + if (errors_.count(NPAPI_NOT_SUPPORTED)) { + messages.push_back( + l10n_util::GetStringUTF8(IDS_EXTENSION_NPAPI_NOT_SUPPORTED)); + } +#endif + if (errors_.count(WEBGL_NOT_SUPPORTED)) { + messages.push_back( + l10n_util::GetStringUTF8(IDS_EXTENSION_WEBGL_NOT_SUPPORTED)); + } +#if !defined(USE_AURA) + if (errors_.count(WINDOW_SHAPE_NOT_SUPPORTED)) { + messages.push_back( + l10n_util::GetStringUTF8(IDS_EXTENSION_WINDOW_SHAPE_NOT_SUPPORTED)); + } +#endif + + return base::UTF8ToUTF16(base::JoinString(messages, " ")); +} + +void RequirementsChecker::VerifyWebGLAvailability(bool available) { + if (!available) + errors_.insert(WEBGL_NOT_SUPPORTED); + PostRunCallback(); +} + +void RequirementsChecker::PostRunCallback() { + // TODO(michaelpg): This always forces the callback to run asynchronously + // to maintain the assumption in + // ExtensionService::LoadExtensionsFromCommandLineFlag(). Remove these helper + // functions after crbug.com/708354 is addressed. + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&RequirementsChecker::RunCallback, + weak_ptr_factory_.GetWeakPtr())); +} + +void RequirementsChecker::RunCallback() { + DCHECK(callback_); + std::move(callback_).Run(errors_); +} + +} // namespace extensions
diff --git a/extensions/browser/requirements_checker.h b/extensions/browser/requirements_checker.h index 8844157e..3118325 100644 --- a/extensions/browser/requirements_checker.h +++ b/extensions/browser/requirements_checker.h
@@ -5,10 +5,14 @@ #ifndef EXTENSIONS_BROWSER_REQUIREMENTS_CHECKER_H_ #define EXTENSIONS_BROWSER_REQUIREMENTS_CHECKER_H_ -#include <vector> - -#include "base/callback.h" +#include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "extensions/browser/preload_check.h" + +namespace content { +class GpuFeatureChecker; +} namespace extensions { class Extension; @@ -17,20 +21,34 @@ // asynchronous process that involves several threads, but the public interface // of this class (including constructor and destructor) must only be used on // the UI thread. -class RequirementsChecker { +class RequirementsChecker : public PreloadCheck { public: - virtual ~RequirementsChecker() {} + explicit RequirementsChecker(scoped_refptr<const Extension> extension); + ~RequirementsChecker() override; - using RequirementsCheckedCallback = - base::Callback<void(const std::vector<std::string>& /* requirements */)>; + // PreloadCheck: + void Start(ResultCallback callback) override; + // Joins multiple errors into a space-separated string. + base::string16 GetErrorMessage() const override; - // The vector passed to the callback are any localized errors describing - // requirement violations. If this vector is non-empty, requirements checking - // failed. This should only be called once. |callback| will always be invoked - // asynchronously on the UI thread. |callback| will only be called once, and - // will be reset after called. - virtual void Check(const scoped_refptr<const Extension>& extension, - const RequirementsCheckedCallback& callback) = 0; + private: + // Callback for the GpuFeatureChecker. + void VerifyWebGLAvailability(bool available); + + // Helper function to post a task on the UI thread to call RunCallback(). + void PostRunCallback(); + + // Helper function to run the callback. + void RunCallback(); + + scoped_refptr<content::GpuFeatureChecker> webgl_checker_; + + ResultCallback callback_; + Errors errors_; + + base::WeakPtrFactory<RequirementsChecker> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(RequirementsChecker); }; } // namespace extensions
diff --git a/extensions/browser/requirements_checker_unittest.cc b/extensions/browser/requirements_checker_unittest.cc new file mode 100644 index 0000000..c4532f74 --- /dev/null +++ b/extensions/browser/requirements_checker_unittest.cc
@@ -0,0 +1,176 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/requirements_checker.h" + +#include <memory> +#include <vector> + +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" +#include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "content/public/browser/gpu_data_manager.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "extensions/browser/extension_system.h" +#include "extensions/browser/extensions_test.h" +#include "extensions/browser/preload_check.h" +#include "extensions/browser/preload_check_test_util.h" +#include "extensions/common/extension.h" +#include "extensions/common/manifest.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/l10n/l10n_util.h" + +namespace extensions { + +namespace { + +// Whether this build supports the window.shape requirement. +const bool kSupportsWindowShape = +#if defined(USE_AURA) + true; +#else + false; +#endif + +// Whether this build supports the plugins.npapi requirement. +const bool kSupportsNPAPI = +#if defined(OS_POSIX) && !defined(OS_MACOSX) + false; +#else + true; +#endif + +// Returns true if a WebGL check might not fail immediately. +bool MightSupportWebGL() { + return content::GpuDataManager::GetInstance()->GpuAccessAllowed(nullptr); +} + +const char kFeaturesKey[] = "requirements.3D.features"; +const char kFeatureWebGL[] = "webgl"; +const char kFeatureCSS3d[] = "css3d"; + +} // namespace + +class RequirementsCheckerTest : public ExtensionsTest { + public: + RequirementsCheckerTest() { + manifest_dict_ = base::MakeUnique<base::DictionaryValue>(); + } + + ~RequirementsCheckerTest() override {} + + void CreateExtension() { + manifest_dict_->SetString("name", "dummy name"); + manifest_dict_->SetString("version", "1"); + + std::string error; + extension_ = + Extension::Create(base::FilePath(), Manifest::UNPACKED, *manifest_dict_, + Extension::NO_FLAGS, &error); + ASSERT_TRUE(extension_.get()) << error; + } + + protected: + void StartChecker() { + checker_ = base::MakeUnique<RequirementsChecker>(extension_); + // TODO(michaelpg): This should normally not have to be async. Use Run() + // instead of RunUntilComplete() after crbug.com/708354 is addressed. + runner_.RunUntilComplete(checker_.get()); + } + + void RequireWindowShape() { + manifest_dict_->SetBoolean("requirements.window.shape", true); + } + + void RequireNPAPI() { + manifest_dict_->SetBoolean("requirements.plugins.npapi", true); + } + + void RequireFeature(const char feature[]) { + if (!manifest_dict_->HasKey(kFeaturesKey)) + manifest_dict_->Set(kFeaturesKey, base::MakeUnique<base::ListValue>()); + base::ListValue* features_list = nullptr; + ASSERT_TRUE(manifest_dict_->GetList(kFeaturesKey, &features_list)); + features_list->AppendString(feature); + } + + std::unique_ptr<RequirementsChecker> checker_; + PreloadCheckRunner runner_; + + private: + content::TestBrowserThreadBundle bundle_; + scoped_refptr<Extension> extension_; + std::unique_ptr<base::DictionaryValue> manifest_dict_; +}; + +// Tests no requirements. +TEST_F(RequirementsCheckerTest, RequirementsEmpty) { + CreateExtension(); + StartChecker(); + EXPECT_TRUE(runner_.called()); + EXPECT_EQ(0u, runner_.errors().size()); + EXPECT_TRUE(checker_->GetErrorMessage().empty()); +} + +// Tests fulfilled requirements. +TEST_F(RequirementsCheckerTest, RequirementsSuccess) { + if (kSupportsWindowShape) + RequireWindowShape(); + if (kSupportsNPAPI) + RequireNPAPI(); + RequireFeature(kFeatureCSS3d); + + CreateExtension(); + StartChecker(); + EXPECT_TRUE(runner_.called()); + EXPECT_EQ(0u, runner_.errors().size()); + EXPECT_TRUE(checker_->GetErrorMessage().empty()); +} + +// Tests multiple requirements failing (on some builds). +TEST_F(RequirementsCheckerTest, RequirementsFailMultiple) { + size_t expected_errors = 0u; + if (!kSupportsWindowShape) { + RequireWindowShape(); + expected_errors++; + } + if (!kSupportsNPAPI) { + RequireNPAPI(); + expected_errors++; + } + if (!MightSupportWebGL()) { + RequireFeature(kFeatureWebGL); + expected_errors++; + } + // css3d should always succeed. + RequireFeature(kFeatureCSS3d); + + CreateExtension(); + StartChecker(); + EXPECT_TRUE(runner_.called()); + EXPECT_EQ(expected_errors, runner_.errors().size()); + EXPECT_EQ(expected_errors == 0, checker_->GetErrorMessage().empty()); +} + +// Tests a requirement that might fail asynchronously. +TEST_F(RequirementsCheckerTest, RequirementsFailWebGL) { + content::GpuDataManager::GetInstance()->BlacklistWebGLForTesting(); + RequireFeature(kFeatureWebGL); + CreateExtension(); + StartChecker(); + + // TODO(michaelpg): Check that the runner actually finishes, which requires + // waiting for the GPU check to succeed: crbug.com/706204. + runner_.WaitForIdle(); + if (runner_.errors().size()) { + EXPECT_THAT(runner_.errors(), testing::UnorderedElementsAre( + PreloadCheck::WEBGL_NOT_SUPPORTED)); + EXPECT_FALSE(checker_->GetErrorMessage().empty()); + } +} + +} // namespace extensions
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn index b711c37f..8af643d 100644 --- a/extensions/common/BUILD.gn +++ b/extensions/common/BUILD.gn
@@ -180,6 +180,8 @@ "manifest_handlers/options_page_info.h", "manifest_handlers/permissions_parser.cc", "manifest_handlers/permissions_parser.h", + "manifest_handlers/plugins_handler.cc", + "manifest_handlers/plugins_handler.h", "manifest_handlers/requirements_info.cc", "manifest_handlers/requirements_info.h", "manifest_handlers/sandboxed_page_info.cc",
diff --git a/extensions/common/common_manifest_handlers.cc b/extensions/common/common_manifest_handlers.cc index a40be154..b4e4cc8 100644 --- a/extensions/common/common_manifest_handlers.cc +++ b/extensions/common/common_manifest_handlers.cc
@@ -23,6 +23,8 @@ #include "extensions/common/manifest_handlers/nacl_modules_handler.h" #include "extensions/common/manifest_handlers/oauth2_manifest_handler.h" #include "extensions/common/manifest_handlers/offline_enabled_info.h" +#include "extensions/common/manifest_handlers/plugins_handler.h" +#include "extensions/common/manifest_handlers/requirements_info.h" #include "extensions/common/manifest_handlers/sandboxed_page_info.h" #include "extensions/common/manifest_handlers/shared_module_info.h" #include "extensions/common/manifest_handlers/web_accessible_resources_info.h" @@ -58,6 +60,8 @@ #endif (new OAuth2ManifestHandler)->Register(); (new OfflineEnabledHandler)->Register(); + (new PluginsHandler)->Register(); + (new RequirementsHandler)->Register(); // Depends on plugins. (new SandboxedPageHandler)->Register(); (new SharedModuleHandler)->Register(); (new SocketsManifestHandler)->Register();
diff --git a/chrome/common/extensions/api/plugins/plugins_handler.cc b/extensions/common/manifest_handlers/plugins_handler.cc similarity index 84% rename from chrome/common/extensions/api/plugins/plugins_handler.cc rename to extensions/common/manifest_handlers/plugins_handler.cc index dedf995..d89fdbe 100644 --- a/chrome/common/extensions/api/plugins/plugins_handler.cc +++ b/extensions/common/manifest_handlers/plugins_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/common/extensions/api/plugins/plugins_handler.h" +#include "extensions/common/manifest_handlers/plugins_handler.h" #include <stddef.h> @@ -13,13 +13,13 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "build/build_config.h" -#include "chrome/grit/generated_resources.h" #include "extensions/common/error_utils.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/permissions_parser.h" #include "extensions/common/permissions/api_permission.h" #include "extensions/common/permissions/api_permission_set.h" +#include "extensions/strings/grit/extensions_strings.h" #include "ui/base/l10n/l10n_util.h" namespace extensions { @@ -36,11 +36,9 @@ } // namespace PluginInfo::PluginInfo(const base::FilePath& plugin_path, bool plugin_is_public) - : path(plugin_path), is_public(plugin_is_public) { -} + : path(plugin_path), is_public(plugin_is_public) {} -PluginInfo::~PluginInfo() { -} +PluginInfo::~PluginInfo() {} // static const PluginInfo::PluginVector* PluginInfo::GetPlugins( @@ -57,11 +55,9 @@ return data && !data->plugins.empty() ? true : false; } -PluginsHandler::PluginsHandler() { -} +PluginsHandler::PluginsHandler() {} -PluginsHandler::~PluginsHandler() { -} +PluginsHandler::~PluginsHandler() {} const std::vector<std::string> PluginsHandler::Keys() const { return SingleKey(keys::kPlugins); @@ -100,10 +96,10 @@ } } - // We don't allow extensions to load NPAPI plugins on Chrome OS, but still - // parse the entries to display consistent error messages. If the extension - // actually requires the plugins then LoadRequirements will prevent it - // loading. +// We don't allow extensions to load NPAPI plugins on Chrome OS, but still +// parse the entries to display consistent error messages. If the extension +// actually requires the plugins then LoadRequirements will prevent it +// loading. #if defined(OS_CHROMEOS) continue; #endif // defined(OS_CHROMEOS). @@ -132,10 +128,10 @@ plugins->begin(); plugin != plugins->end(); ++plugin) { if (!base::PathExists(plugin->path)) { - *error = l10n_util::GetStringFUTF8( - IDS_EXTENSION_LOAD_PLUGIN_PATH_FAILED, - plugin->path.LossyDisplayName()); - return false; + *error = + l10n_util::GetStringFUTF8(IDS_EXTENSION_LOAD_PLUGIN_PATH_FAILED, + plugin->path.LossyDisplayName()); + return false; } } }
diff --git a/chrome/common/extensions/api/plugins/plugins_handler.h b/extensions/common/manifest_handlers/plugins_handler.h similarity index 83% rename from chrome/common/extensions/api/plugins/plugins_handler.h rename to extensions/common/manifest_handlers/plugins_handler.h index 6568b38..c2a580096 100644 --- a/chrome/common/extensions/api/plugins/plugins_handler.h +++ b/extensions/common/manifest_handlers/plugins_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_COMMON_EXTENSIONS_API_PLUGINS_PLUGINS_HANDLER_H_ -#define CHROME_COMMON_EXTENSIONS_API_PLUGINS_PLUGINS_HANDLER_H_ +#ifndef EXTENSIONS_COMMON_MANIFEST_HANDLERS_PLUGINS_HANDLER_H_ +#define EXTENSIONS_COMMON_MANIFEST_HANDLERS_PLUGINS_HANDLER_H_ #include <memory> #include <string> @@ -22,7 +22,7 @@ ~PluginInfo(); base::FilePath path; // Path to the plugin. - bool is_public; // False if only this extension can load this plugin. + bool is_public; // False if only this extension can load this plugin. // Return the plugins for a given |extensions|, or NULL if none exist. static const PluginVector* GetPlugins(const Extension* extension); @@ -50,4 +50,4 @@ } // namespace extensions -#endif // CHROME_COMMON_EXTENSIONS_API_PLUGINS_PLUGINS_HANDLER_H_ +#endif // EXTENSIONS_COMMON_MANIFEST_HANDLERS_PLUGINS_HANDLER_H_
diff --git a/extensions/renderer/api_binding.cc b/extensions/renderer/api_binding.cc index a039f8c..6c3cc2e 100644 --- a/extensions/renderer/api_binding.cc +++ b/extensions/renderer/api_binding.cc
@@ -32,8 +32,14 @@ // Returns the name of the enum value for use in JavaScript; JS enum entries use // SCREAMING_STYLE. std::string GetJSEnumEntryName(const std::string& original) { + // The webstorePrivate API has an empty enum value for a result. + // TODO(devlin): Work with the webstore team to see if we can move them off + // this - they also already have a "success" result that they can use. + // See crbug.com/709120. + if (original.empty()) + return original; + std::string result; - DCHECK(!original.empty()); // If the original starts with a digit, prefix it with an underscore. if (base::IsAsciiDigit(original[0])) result.push_back('_');
diff --git a/extensions/renderer/api_binding_unittest.cc b/extensions/renderer/api_binding_unittest.cc index a2b36a2..c8d7d22 100644 --- a/extensions/renderer/api_binding_unittest.cc +++ b/extensions/renderer/api_binding_unittest.cc
@@ -417,6 +417,29 @@ GetStringPropertyFromObject(binding_object, context, "last")); } +// Test that empty enum entries are (unfortunately) allowed. +TEST_F(APIBindingUnittest, EnumWithEmptyEntry) { + const char kTypes[] = + "[{" + " 'id': 'enumWithEmpty'," + " 'type': 'string'," + " 'enum': [{'name': ''}, {'name': 'other'}]" + "}]"; + + SetTypes(kTypes); + InitializeBinding(); + + v8::HandleScope handle_scope(isolate()); + v8::Local<v8::Context> context = MainContext(); + + v8::Local<v8::Object> binding_object = + binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); + + EXPECT_EQ( + "{\"\":\"\",\"OTHER\":\"other\"}", + GetStringPropertyFromObject(binding_object, context, "enumWithEmpty")); +} + TEST_F(APIBindingUnittest, TypeRefsTest) { const char kTypes[] = "[{"
diff --git a/extensions/strings/extensions_strings.grd b/extensions/strings/extensions_strings.grd index bc58dba..ad0f8918 100644 --- a/extensions/strings/extensions_strings.grd +++ b/extensions/strings/extensions_strings.grd
@@ -163,6 +163,9 @@ <message name="IDS_EXTENSION_LOAD_OPTIONS_PAGE_FAILED" desc=""> Could not load options page '<ph name="OPTIONS_PAGE">$1<ex>page.html</ex></ph>'. </message> + <message name="IDS_EXTENSION_LOAD_PLUGIN_PATH_FAILED" desc=""> + Could not load '<ph name="PLUGIN_PATH">$1<ex>/path/to/file</ex></ph>' for plugin. + </message> <message name="IDS_EXTENSION_LOCALES_NO_DEFAULT_LOCALE_SPECIFIED" desc=""> Localization used, but default_locale wasn't specified in the manifest. </message> @@ -308,6 +311,11 @@ <message name="IDS_EXTENSION_INSTALL_PROCESS_CRASHED" desc="Error message in case package fails to install because a utility process crashed."> Could not install package because a utility process crashed. Try restarting Chrome and trying again. </message> + <if expr="is_posix and not is_macosx"> + <message name="IDS_EXTENSION_NPAPI_NOT_SUPPORTED" desc="Error message when an extension has a requirement for plugins that the system does not support."> + NPAPI plugins are not supported. + </message> + </if> <message name="IDS_EXTENSION_PACKAGE_ERROR_CODE" desc="Error message in cases where we fail to install the extension because the crx file is invalid. For example, because the crx header or signature is invalid."> Package is invalid: '<ph name="ERROR_CODE">$1<ex>error</ex></ph>'. </message> @@ -327,6 +335,14 @@ Can not unpack extension. To safely unpack an extension, there must be a path to your profile directory that does not contain a symlink. No such path exists for your profile. </message> </if> + <message name="IDS_EXTENSION_WEBGL_NOT_SUPPORTED" desc="Error message when an extension has a requirement for WebGL that the system does not support."> + WebGL is not supported. + </message> + <if expr="not use_aura"> + <message name="IDS_EXTENSION_WINDOW_SHAPE_NOT_SUPPORTED" desc="Error message when an extension has a requirement for shaped windows that the system does not support."> + Shaped windows are not supported. + </message> + </if> <!-- Utility process names. Please keep alphabetized. --> <message name="IDS_UTILITY_PROCESS_EXTENSION_UNPACKER_NAME" desc="The name of the utility process used for unpacking extensions.">
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm b/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm index 2b9c166..29e1a41 100644 --- a/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm +++ b/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm
@@ -495,6 +495,11 @@ // Verify correct recording of metrics when the reloading of an evicted tab // fails. - (void)testEvictedTabReloadFailure { +// TODO(crbug.com/709126): Evaluate and re-enable this test if necessary. +#if !TARGET_IPHONE_SIMULATOR + EARL_GREY_TEST_DISABLED(@"Test disabled on device."); +#endif + web::test::SetUpFileBasedHttpServer(); chrome_test_util::HistogramTester histogramTester; FailureBlock failureBlock = ^(NSString* error) {
diff --git a/ios/chrome/browser/payments/payment_request.h b/ios/chrome/browser/payments/payment_request.h index c044f429..a0d32d0 100644 --- a/ios/chrome/browser/payments/payment_request.h +++ b/ios/chrome/browser/payments/payment_request.h
@@ -5,6 +5,7 @@ #ifndef IOS_CHROME_BROWSER_PAYMENTS_PAYMENT_REQUEST_H_ #define IOS_CHROME_BROWSER_PAYMENTS_PAYMENT_REQUEST_H_ +#include <set> #include <vector> #include "base/macros.h" @@ -100,6 +101,10 @@ return supported_card_networks_; } + const std::set<std::string>& basic_card_specified_networks() const { + return basic_card_specified_networks_; + } + // Adds |credit_card| to the list of cached credit cards and returns a pointer // to the cached copy. virtual autofill::CreditCard* AddCreditCard( @@ -178,8 +183,13 @@ std::vector<autofill::CreditCard*> credit_cards_; autofill::CreditCard* selected_credit_card_; - // A vector of supported basic card networks. + // A vector of supported basic card networks. This encompasses everything that + // the merchant supports and should be used for support checks. std::vector<std::string> supported_card_networks_; + // A subset of |supported_card_networks_| which is only the networks that have + // been specified as part of the "basic-card" supported method. Callers should + // use |supported_card_networks_| for merchant support checks. + std::set<std::string> basic_card_specified_networks_; // A vector of pointers to the shipping options in |web_payment_request_|. std::vector<web::PaymentShippingOption*> shipping_options_;
diff --git a/ios/chrome/browser/payments/payment_request.mm b/ios/chrome/browser/payments/payment_request.mm index 9af93a43..86625b5 100644 --- a/ios/chrome/browser/payments/payment_request.mm +++ b/ios/chrome/browser/payments/payment_request.mm
@@ -10,6 +10,7 @@ #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/payments/core/currency_formatter.h" +#include "components/payments/core/payment_request_data_util.h" #include "ios/chrome/browser/application_context.h" #include "ios/web/public/payments/payment_request.h" @@ -83,21 +84,18 @@ } void PaymentRequest::PopulateCreditCardCache() { - for (const auto& method_data : web_payment_request_.method_data) { - for (const std::string& supported_method : method_data.supported_methods) { - supported_card_networks_.push_back(supported_method); - } + if (!payments::data_util::ParseBasicCardSupportedNetworks( + web_payment_request_.method_data, &supported_card_networks_, + &basic_card_specified_networks_)) { + // TODO(crbug.com/709036): close the UI and reject the promise since the + // data is invalid. + return; } const std::vector<autofill::CreditCard*>& credit_cards_to_suggest = personal_data_manager_->GetCreditCardsToSuggest(); credit_card_cache_.reserve(credit_cards_to_suggest.size()); - // TODO(crbug.com/602666): Update the following logic to allow basic card - // payment. https://w3c.github.io/webpayments-methods-card/ - // new PaymentRequest([{supportedMethods: ['basic-card'], - // data: {supportedNetworks:['visa']}]}], ...); - for (const auto* credit_card : credit_cards_to_suggest) { std::string spec_card_type = autofill::data_util::GetPaymentRequestData(credit_card->type())
diff --git a/ios/chrome/browser/payments/payment_request_coordinator.mm b/ios/chrome/browser/payments/payment_request_coordinator.mm index 3290959..38ecb76 100644 --- a/ios/chrome/browser/payments/payment_request_coordinator.mm +++ b/ios/chrome/browser/payments/payment_request_coordinator.mm
@@ -208,9 +208,17 @@ CVC:(const base::string16&)cvc { web::PaymentResponse paymentResponse; + // If the merchant specified the card network as part of the "basic-card" + // payment method, return "basic-card" as the method_name. Otherwise, return + // the name of the network directly. + std::string basic_card_type = + autofill::data_util::GetPaymentRequestData(card.type()) + .basic_card_payment_type; paymentResponse.method_name = - base::ASCIIToUTF16(autofill::data_util::GetPaymentRequestData(card.type()) - .basic_card_payment_type); + _paymentRequest->basic_card_specified_networks().find(basic_card_type) != + _paymentRequest->basic_card_specified_networks().end() + ? base::ASCIIToUTF16("basic-card") + : base::ASCIIToUTF16(basic_card_type); paymentResponse.details = GetBasicCardResponseFromAutofillCreditCard( card, cvc, _paymentRequest->billing_profiles(),
diff --git a/ios/chrome/browser/payments/payment_request_unittest.mm b/ios/chrome/browser/payments/payment_request_unittest.mm index 5b75fb3..ed86712b 100644 --- a/ios/chrome/browser/payments/payment_request_unittest.mm +++ b/ios/chrome/browser/payments/payment_request_unittest.mm
@@ -65,6 +65,145 @@ EXPECT_EQ("mastercard", payment_request.supported_card_networks()[1]); } +// Test that parsing supported methods (with invalid values and duplicates) +// works as expected. +TEST(PaymentRequestTest, SupportedMethods) { + web::PaymentRequest web_payment_request; + autofill::TestPersonalDataManager personal_data_manager; + + payments::PaymentMethodData method_datum1; + method_datum1.supported_methods.push_back("visa"); + method_datum1.supported_methods.push_back("mastercard"); + method_datum1.supported_methods.push_back("invalid"); + method_datum1.supported_methods.push_back(""); + method_datum1.supported_methods.push_back("visa"); + web_payment_request.method_data.push_back(method_datum1); + + PaymentRequest payment_request(web_payment_request, &personal_data_manager); + ASSERT_EQ(2U, payment_request.supported_card_networks().size()); + EXPECT_EQ("visa", payment_request.supported_card_networks()[0]); + EXPECT_EQ("mastercard", payment_request.supported_card_networks()[1]); +} + +// Test that parsing supported methods in different method data entries (with +// invalid values and duplicates) works as expected. +TEST(PaymentRequestTest, SupportedMethods_MultipleEntries) { + web::PaymentRequest web_payment_request; + autofill::TestPersonalDataManager personal_data_manager; + + payments::PaymentMethodData method_datum1; + method_datum1.supported_methods.push_back("visa"); + web_payment_request.method_data.push_back(method_datum1); + payments::PaymentMethodData method_datum2; + method_datum2.supported_methods.push_back("mastercard"); + web_payment_request.method_data.push_back(method_datum2); + payments::PaymentMethodData method_datum3; + method_datum3.supported_methods.push_back(""); + web_payment_request.method_data.push_back(method_datum3); + payments::PaymentMethodData method_datum4; + method_datum4.supported_methods.push_back("visa"); + web_payment_request.method_data.push_back(method_datum4); + + PaymentRequest payment_request(web_payment_request, &personal_data_manager); + ASSERT_EQ(2U, payment_request.supported_card_networks().size()); + EXPECT_EQ("visa", payment_request.supported_card_networks()[0]); + EXPECT_EQ("mastercard", payment_request.supported_card_networks()[1]); +} + +// Test that only specifying basic-card means that all are supported. +TEST(PaymentRequestTest, SupportedMethods_OnlyBasicCard) { + web::PaymentRequest web_payment_request; + autofill::TestPersonalDataManager personal_data_manager; + + payments::PaymentMethodData method_datum1; + method_datum1.supported_methods.push_back("basic-card"); + web_payment_request.method_data.push_back(method_datum1); + + PaymentRequest payment_request(web_payment_request, &personal_data_manager); + + // All of the basic card networks are supported. + ASSERT_EQ(8U, payment_request.supported_card_networks().size()); + EXPECT_EQ("amex", payment_request.supported_card_networks()[0]); + EXPECT_EQ("diners", payment_request.supported_card_networks()[1]); + EXPECT_EQ("discover", payment_request.supported_card_networks()[2]); + EXPECT_EQ("jcb", payment_request.supported_card_networks()[3]); + EXPECT_EQ("mastercard", payment_request.supported_card_networks()[4]); + EXPECT_EQ("mir", payment_request.supported_card_networks()[5]); + EXPECT_EQ("unionpay", payment_request.supported_card_networks()[6]); + EXPECT_EQ("visa", payment_request.supported_card_networks()[7]); +} + +// Test that specifying a method AND basic-card means that all are supported, +// but with the method as first. +TEST(PaymentRequestTest, SupportedMethods_BasicCard_WithSpecificMethod) { + web::PaymentRequest web_payment_request; + autofill::TestPersonalDataManager personal_data_manager; + + payments::PaymentMethodData method_datum1; + method_datum1.supported_methods.push_back("jcb"); + method_datum1.supported_methods.push_back("basic-card"); + web_payment_request.method_data.push_back(method_datum1); + + PaymentRequest payment_request(web_payment_request, &personal_data_manager); + + // All of the basic card networks are supported, but JCB is first because it + // was specified first. + EXPECT_EQ(8u, payment_request.supported_card_networks().size()); + EXPECT_EQ("jcb", payment_request.supported_card_networks()[0]); + EXPECT_EQ("amex", payment_request.supported_card_networks()[1]); + EXPECT_EQ("diners", payment_request.supported_card_networks()[2]); + EXPECT_EQ("discover", payment_request.supported_card_networks()[3]); + EXPECT_EQ("mastercard", payment_request.supported_card_networks()[4]); + EXPECT_EQ("mir", payment_request.supported_card_networks()[5]); + EXPECT_EQ("unionpay", payment_request.supported_card_networks()[6]); + EXPECT_EQ("visa", payment_request.supported_card_networks()[7]); +} + +// Test that specifying basic-card with a supported network (with previous +// supported methods) will work as expected +TEST(PaymentRequestTest, SupportedMethods_BasicCard_Overlap) { + web::PaymentRequest web_payment_request; + autofill::TestPersonalDataManager personal_data_manager; + + payments::PaymentMethodData method_datum1; + method_datum1.supported_methods.push_back("mastercard"); + method_datum1.supported_methods.push_back("visa"); + web_payment_request.method_data.push_back(method_datum1); + payments::PaymentMethodData method_datum2; + method_datum2.supported_methods.push_back("basic-card"); + method_datum2.supported_networks.push_back("visa"); + method_datum2.supported_networks.push_back("mastercard"); + method_datum2.supported_networks.push_back("unionpay"); + web_payment_request.method_data.push_back(method_datum2); + + PaymentRequest payment_request(web_payment_request, &personal_data_manager); + + EXPECT_EQ(3u, payment_request.supported_card_networks().size()); + EXPECT_EQ("mastercard", payment_request.supported_card_networks()[0]); + EXPECT_EQ("visa", payment_request.supported_card_networks()[1]); + EXPECT_EQ("unionpay", payment_request.supported_card_networks()[2]); +} + +// Test that specifying basic-card with supported networks after specifying +// some methods +TEST(PaymentRequestTest, SupportedMethods_BasicCard_WithSupportedNetworks) { + web::PaymentRequest web_payment_request; + autofill::TestPersonalDataManager personal_data_manager; + + payments::PaymentMethodData method_datum1; + method_datum1.supported_methods.push_back("basic-card"); + method_datum1.supported_networks.push_back("visa"); + method_datum1.supported_networks.push_back("unionpay"); + web_payment_request.method_data.push_back(method_datum1); + + PaymentRequest payment_request(web_payment_request, &personal_data_manager); + + // Only the specified networks are supported. + EXPECT_EQ(2u, payment_request.supported_card_networks().size()); + EXPECT_EQ("visa", payment_request.supported_card_networks()[0]); + EXPECT_EQ("unionpay", payment_request.supported_card_networks()[1]); +} + // Tests that credit cards can be added to the list of cached credit cards. TEST(PaymentRequestTest, AddCreditCard) { web::PaymentRequest web_payment_request;
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.h b/ios/chrome/browser/sync/ios_chrome_sync_client.h index c0c6a14..3d93a7c 100644 --- a/ios/chrome/browser/sync/ios_chrome_sync_client.h +++ b/ios/chrome/browser/sync/ios_chrome_sync_client.h
@@ -54,7 +54,8 @@ BookmarkUndoService* GetBookmarkUndoServiceIfExists() override; scoped_refptr<syncer::ExtensionsActivity> GetExtensionsActivity() override; sync_sessions::SyncSessionsClient* GetSyncSessionsClient() override; - ServiceProvider GetSyncableServiceForType(syncer::ModelType type) override; + base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( + syncer::ModelType type) override; base::WeakPtr<syncer::ModelTypeSyncBridge> GetSyncBridgeForModelType( syncer::ModelType type) override; scoped_refptr<syncer::ModelSafeWorker> CreateModelWorkerForGroup(
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.mm b/ios/chrome/browser/sync/ios_chrome_sync_client.mm index 74a38d3..cc349d6e 100644 --- a/ios/chrome/browser/sync/ios_chrome_sync_client.mm +++ b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
@@ -71,46 +71,8 @@ #error "This file requires ARC support." #endif -using autofill::AutocompleteSyncableService; -using autofill::AutofillProfileSyncableService; -using autofill::AutofillWalletMetadataSyncableService; -using autofill::AutofillWalletSyncableService; -using base::Callback; -using base::WeakPtr; -using syncer::SyncableService; - -using ServiceProvider = syncer::SyncClient::ServiceProvider; - namespace { -template <typename T> -T Trampoline(T arg) { - return arg; -} - -template <typename T> -Callback<T()> WrapInCallback(T arg) { - return base::Bind(&Trampoline<T>, arg); -} - -WeakPtr<SyncableService> ServiceAsWeakPtr(SyncableService* ptr) { - return ptr ? ptr->AsWeakPtr() : WeakPtr<SyncableService>(); -} - -ServiceProvider WrapInProvider(SyncableService* service) { - return WrapInCallback(ServiceAsWeakPtr(service)); -} - -template <typename T> -WeakPtr<SyncableService> CallbackResultAsWeakPtr(Callback<T()> callback) { - return ServiceAsWeakPtr(callback.Run()); -} - -template <typename T> -ServiceProvider WrapInWeakPtrCallback(Callback<T()> callback) { - return base::Bind(&CallbackResultAsWeakPtr<T>, callback); -} - // iOS implementation of SyncSessionsClient. Needs to be in a separate class // due to possible multiple inheritance issues, wherein IOSChromeSyncClient // might inherit from other interfaces with same methods. @@ -301,78 +263,87 @@ return sync_sessions_client_.get(); } -ServiceProvider IOSChromeSyncClient::GetSyncableServiceForType( - syncer::ModelType type) { +base::WeakPtr<syncer::SyncableService> +IOSChromeSyncClient::GetSyncableServiceForType(syncer::ModelType type) { switch (type) { case syncer::DEVICE_INFO: - return WrapInProvider( - IOSChromeProfileSyncServiceFactory::GetForBrowserState(browser_state_) - ->GetDeviceInfoSyncableService()); + return IOSChromeProfileSyncServiceFactory::GetForBrowserState( + browser_state_) + ->GetDeviceInfoSyncableService() + ->AsWeakPtr(); case syncer::PREFERENCES: + return browser_state_->GetSyncablePrefs() + ->GetSyncableService(syncer::PREFERENCES) + ->AsWeakPtr(); case syncer::PRIORITY_PREFERENCES: - return WrapInProvider( - browser_state_->GetSyncablePrefs()->GetSyncableService(type)); + return browser_state_->GetSyncablePrefs() + ->GetSyncableService(syncer::PRIORITY_PREFERENCES) + ->AsWeakPtr(); case syncer::AUTOFILL: case syncer::AUTOFILL_PROFILE: case syncer::AUTOFILL_WALLET_DATA: case syncer::AUTOFILL_WALLET_METADATA: { if (!web_data_service_) - return WrapInProvider(nullptr); + return base::WeakPtr<syncer::SyncableService>(); if (type == syncer::AUTOFILL) { - return WrapInWeakPtrCallback( - base::Bind(&AutocompleteSyncableService::FromWebDataService, - base::RetainedRef(web_data_service_))); + return autofill::AutocompleteSyncableService::FromWebDataService( + web_data_service_.get()) + ->AsWeakPtr(); } else if (type == syncer::AUTOFILL_PROFILE) { - return WrapInWeakPtrCallback( - base::Bind(&AutofillProfileSyncableService::FromWebDataService, - base::RetainedRef(web_data_service_))); + return autofill::AutofillProfileSyncableService::FromWebDataService( + web_data_service_.get()) + ->AsWeakPtr(); } else if (type == syncer::AUTOFILL_WALLET_METADATA) { - return WrapInWeakPtrCallback(base::Bind( - &AutofillWalletMetadataSyncableService::FromWebDataService, - base::RetainedRef(web_data_service_))); + return autofill::AutofillWalletMetadataSyncableService:: + FromWebDataService(web_data_service_.get()) + ->AsWeakPtr(); } - return WrapInWeakPtrCallback( - base::Bind(&AutofillWalletSyncableService::FromWebDataService, - base::RetainedRef(web_data_service_))); + return autofill::AutofillWalletSyncableService::FromWebDataService( + web_data_service_.get()) + ->AsWeakPtr(); } case syncer::HISTORY_DELETE_DIRECTIVES: { - return WrapInProvider(ios::HistoryServiceFactory::GetForBrowserState( - browser_state_, ServiceAccessType::EXPLICIT_ACCESS)); + history::HistoryService* history = + ios::HistoryServiceFactory::GetForBrowserState( + browser_state_, ServiceAccessType::EXPLICIT_ACCESS); + return history ? history->AsWeakPtr() + : base::WeakPtr<history::HistoryService>(); } case syncer::TYPED_URLS: { history::HistoryService* history = ios::HistoryServiceFactory::GetForBrowserState( browser_state_, ServiceAccessType::EXPLICIT_ACCESS); - return WrapInProvider(history ? history->GetTypedUrlSyncableService() - : nullptr); + return history ? history->GetTypedUrlSyncableService()->AsWeakPtr() + : base::WeakPtr<syncer::SyncableService>(); } case syncer::FAVICON_IMAGES: case syncer::FAVICON_TRACKING: { - return WrapInProvider( + sync_sessions::FaviconCache* favicons = IOSChromeProfileSyncServiceFactory::GetForBrowserState(browser_state_) - ->GetFaviconCache()); + ->GetFaviconCache(); + return favicons ? favicons->AsWeakPtr() + : base::WeakPtr<syncer::SyncableService>(); } case syncer::ARTICLES: { // DomDistillerService is used in iOS ReadingList. The distilled articles // are saved separately and must not be synced. // Add a not reached to avoid having ARTICLES sync be enabled silently. NOTREACHED(); - return WrapInProvider(nullptr); + return base::WeakPtr<syncer::SyncableService>(); } case syncer::SESSIONS: { - return WrapInProvider( - IOSChromeProfileSyncServiceFactory::GetForBrowserState(browser_state_) - ->GetSessionsSyncableService()); + return IOSChromeProfileSyncServiceFactory::GetForBrowserState( + browser_state_) + ->GetSessionsSyncableService() + ->AsWeakPtr(); } case syncer::PASSWORDS: { - return password_store_ ? base::Bind(&password_manager::PasswordStore:: - GetPasswordSyncableService, - base::RetainedRef(password_store_)) - : WrapInProvider(nullptr); + return password_store_ ? password_store_->GetPasswordSyncableService() + : base::WeakPtr<syncer::SyncableService>(); } default: NOTREACHED(); - return WrapInProvider(nullptr); + return base::WeakPtr<syncer::SyncableService>(); } }
diff --git a/ios/chrome/browser/translate/translate_egtest.mm b/ios/chrome/browser/translate/translate_egtest.mm index 6e0b951..cce39fb 100644 --- a/ios/chrome/browser/translate/translate_egtest.mm +++ b/ios/chrome/browser/translate/translate_egtest.mm
@@ -558,6 +558,11 @@ // Tests that the language detection infobar is displayed. - (void)testLanguageDetectionInfobar { +// TODO(crbug.com/709131): Evaluate and re-enable this test if necessary. +#if !TARGET_IPHONE_SIMULATOR + EARL_GREY_TEST_DISABLED(@"Test disabled on device."); +#endif + // The translate machinery will not auto-fire without API keys, unless that // behavior is overridden for testing. translate::TranslateManager::SetIgnoreMissingKeyForTesting(true); @@ -712,6 +717,11 @@ // Tests that translation occurs automatically on second navigation to an // already translated page. - (void)testAutoTranslate { +// TODO(crbug.com/709131): Evaluate and re-enable this test if necessary. +#if !TARGET_IPHONE_SIMULATOR + EARL_GREY_TEST_DISABLED(@"Test disabled on device."); +#endif + // The translate machinery will not auto-fire without API keys, unless that // behavior is overridden for testing. translate::TranslateManager::SetIgnoreMissingKeyForTesting(true);
diff --git a/ios/chrome/browser/ui/activity_services/activity_service_controller_egtest.mm b/ios/chrome/browser/ui/activity_services/activity_service_controller_egtest.mm index 52b3458..9e5992d 100644 --- a/ios/chrome/browser/ui/activity_services/activity_service_controller_egtest.mm +++ b/ios/chrome/browser/ui/activity_services/activity_service_controller_egtest.mm
@@ -60,6 +60,12 @@ // Test that when trying to print a page redirected to an unprintable page, a // snackbar explaining that the page cannot be printed is displayed. - (void)testActivityServiceControllerPrintAfterRedirectionToUnprintablePage { +// TODO(crbug.com/694662): This test relies on external URL because of the bug. +// Re-enable this test on device once the bug is fixed. +#if !TARGET_IPHONE_SIMULATOR + EARL_GREY_TEST_DISABLED(@"Test disabled on device."); +#endif + std::map<GURL, std::string> responses; const GURL regularPageURL = web::test::HttpServer::MakeUrl("http://choux"); responses[regularPageURL] = "fleur";
diff --git a/ios/chrome/browser/ui/error_page_egtest.mm b/ios/chrome/browser/ui/error_page_egtest.mm index 52fe6f1f..51452b5 100644 --- a/ios/chrome/browser/ui/error_page_egtest.mm +++ b/ios/chrome/browser/ui/error_page_egtest.mm
@@ -58,6 +58,12 @@ // Tests whether the error page is displayed for a bad URL. - (void)testErrorPage { +// TODO(crbug.com/694662): This test relies on external URL because of the bug. +// Re-enable this test on device once the bug is fixed. +#if !TARGET_IPHONE_SIMULATOR + EARL_GREY_TEST_DISABLED(@"Test disabled on device."); +#endif + std::unique_ptr<web::DataResponseProvider> provider( new ErrorPageResponseProvider()); web::test::SetUpHttpServer(std::move(provider)); @@ -69,6 +75,12 @@ // Tests whether the error page is displayed if it is behind a redirect. - (void)testErrorPageRedirect { +// TODO(crbug.com/694662): This test relies on external URL because of the bug. +// Re-enable this test on device once the bug is fixed. +#if !TARGET_IPHONE_SIMULATOR + EARL_GREY_TEST_DISABLED(@"Test disabled on device."); +#endif + std::unique_ptr<web::DataResponseProvider> provider( new ErrorPageResponseProvider()); web::test::SetUpHttpServer(std::move(provider));
diff --git a/ios/chrome/browser/ui/history/history_ui_egtest.mm b/ios/chrome/browser/ui/history/history_ui_egtest.mm index 77a830c..98eced1 100644 --- a/ios/chrome/browser/ui/history/history_ui_egtest.mm +++ b/ios/chrome/browser/ui/history/history_ui_egtest.mm
@@ -285,6 +285,11 @@ // in, and that tapping on the link in the message opens a new tab with the sync // help page. - (void)testHistoryEntriesStatusCell { +// TODO(crbug.com/709135): Evaluate and re-enable this test if necessary. +#if !TARGET_IPHONE_SIMULATOR + EARL_GREY_TEST_DISABLED(@"Test disabled on device."); +#endif + [self loadTestURLs]; [self openHistoryPanel]; // Assert that no message is shown when the user is not signed in.
diff --git a/ios/chrome/browser/web/navigation_egtest.mm b/ios/chrome/browser/web/navigation_egtest.mm index eb477d92..f73b4ae 100644 --- a/ios/chrome/browser/web/navigation_egtest.mm +++ b/ios/chrome/browser/web/navigation_egtest.mm
@@ -413,6 +413,12 @@ // Tests navigating forward via window.history.forward() to an error page. - (void)testHistoryForwardToErrorPage { +// TODO(crbug.com/694662): This test relies on external URL because of the bug. +// Re-enable this test on device once the bug is fixed. +#if !TARGET_IPHONE_SIMULATOR + EARL_GREY_TEST_DISABLED(@"Test disabled on device."); +#endif + SetupBackAndForwardResponseProvider(); // Go to page 1 with a button which calls window.history.forward().
diff --git a/ios/clean/chrome/browser/ui/tools/BUILD.gn b/ios/clean/chrome/browser/ui/tools/BUILD.gn index 816c6f1..61d3519 100644 --- a/ios/clean/chrome/browser/ui/tools/BUILD.gn +++ b/ios/clean/chrome/browser/ui/tools/BUILD.gn
@@ -43,6 +43,6 @@ "//ios/chrome/browser/ui", "//ios/clean/chrome/browser/ui/commands", "//ios/clean/chrome/browser/ui/toolbar:toolbar_components_ui", - "//ios/third_party/material_roboto_font_loader_ios", + "//ios/third_party/material_components_ios", ] }
diff --git a/ios/clean/chrome/browser/ui/tools/menu_view_controller.mm b/ios/clean/chrome/browser/ui/tools/menu_view_controller.mm index 1b47378c..f226742d 100644 --- a/ios/clean/chrome/browser/ui/tools/menu_view_controller.mm +++ b/ios/clean/chrome/browser/ui/tools/menu_view_controller.mm
@@ -12,7 +12,7 @@ #import "ios/clean/chrome/browser/ui/toolbar/toolbar_button.h" #import "ios/clean/chrome/browser/ui/tools/menu_overflow_controls_stackview.h" #import "ios/clean/chrome/browser/ui/tools/tools_menu_item.h" -#import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoFontLoader.h" +#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -54,8 +54,7 @@ menuButton.tintColor = [UIColor blackColor]; [menuButton setTitle:item.title forState:UIControlStateNormal]; [menuButton setContentEdgeInsets:UIEdgeInsetsMakeDirected(0, 10.0f, 0, 0)]; - [menuButton.titleLabel - setFont:[[MDFRobotoFontLoader sharedInstance] regularFontOfSize:16]]; + [menuButton.titleLabel setFont:[MDCTypography subheadFont]]; [menuButton.titleLabel setTextAlignment:NSTextAlignmentNatural]; [menuButton addTarget:self action:@selector(closeToolsMenu:)
diff --git a/ios/web/navigation/navigation_manager_impl.h b/ios/web/navigation/navigation_manager_impl.h index a6d41fe..2c1a9d3 100644 --- a/ios/web/navigation/navigation_manager_impl.h +++ b/ios/web/navigation/navigation_manager_impl.h
@@ -110,11 +110,6 @@ NavigationInitiationType initiation_type, UserAgentOverrideOption user_agent_override_option); - // Temporary method. Returns a vector of NavigationItems corresponding to - // the SessionEntries of the uderlying CRWSessionController. - // TODO(crbug.com/546365): Remove this method. - NavigationItemList GetItems() const; - // NavigationManager: BrowserState* GetBrowserState() const override; WebState* GetWebState() const override; @@ -123,7 +118,6 @@ NavigationItem* GetPendingItem() const override; NavigationItem* GetTransientItem() const override; void DiscardNonCommittedItems() override; - void LoadIfNecessary() override; void LoadURLWithParams(const NavigationManager::WebLoadParams&) override; void AddTransientURLRewriter( BrowserURLRewriter::URLRewriter rewriter) override;
diff --git a/ios/web/navigation/navigation_manager_impl.mm b/ios/web/navigation/navigation_manager_impl.mm index 54f69e5..1d20a089 100644 --- a/ios/web/navigation/navigation_manager_impl.mm +++ b/ios/web/navigation/navigation_manager_impl.mm
@@ -236,10 +236,6 @@ } } -NavigationItemList NavigationManagerImpl::GetItems() const { - return CreateNavigationItemList([session_controller_ items]); -} - BrowserState* NavigationManagerImpl::GetBrowserState() const { return browser_state_; } @@ -268,10 +264,6 @@ [session_controller_ discardNonCommittedItems]; } -void NavigationManagerImpl::LoadIfNecessary() { - // Nothing to do; iOS loads lazily. -} - void NavigationManagerImpl::LoadURLWithParams( const NavigationManager::WebLoadParams& params) { delegate_->LoadURLWithParams(params);
diff --git a/ios/web/public/navigation_manager.h b/ios/web/public/navigation_manager.h index 3d8a52b..2950c3be 100644 --- a/ios/web/public/navigation_manager.h +++ b/ios/web/public/navigation_manager.h
@@ -111,13 +111,6 @@ // Removes the transient and pending NavigationItems. virtual void DiscardNonCommittedItems() = 0; - // Currently a no-op, but present to be called in contexts where - // NavigationController::LoadIfNecessary() is called in the analogous - // //content-based context. In particular, likely will become more than - // a no-op if NavigationManager::SetNeedsReload() becomes necessary to - // match NavigationController::SetNeedsReload(). - virtual void LoadIfNecessary() = 0; - // Loads the URL with specified |params|. virtual void LoadURLWithParams( const NavigationManager::WebLoadParams& params) = 0;
diff --git a/ios/web/public/test/fakes/test_navigation_manager.h b/ios/web/public/test/fakes/test_navigation_manager.h index 8497b0b..4d9e483 100644 --- a/ios/web/public/test/fakes/test_navigation_manager.h +++ b/ios/web/public/test/fakes/test_navigation_manager.h
@@ -25,7 +25,6 @@ NavigationItem* GetPendingItem() const override; NavigationItem* GetTransientItem() const override; void DiscardNonCommittedItems() override; - void LoadIfNecessary() override; void LoadURLWithParams(const NavigationManager::WebLoadParams&) override; void AddTransientURLRewriter( BrowserURLRewriter::URLRewriter rewriter) override;
diff --git a/ios/web/public/test/fakes/test_navigation_manager.mm b/ios/web/public/test/fakes/test_navigation_manager.mm index 931a7f2..972efdca 100644 --- a/ios/web/public/test/fakes/test_navigation_manager.mm +++ b/ios/web/public/test/fakes/test_navigation_manager.mm
@@ -57,10 +57,6 @@ NOTREACHED(); } -void TestNavigationManager::LoadIfNecessary() { - NOTREACHED(); -} - void TestNavigationManager::LoadURLWithParams( const NavigationManager::WebLoadParams& params) { NOTREACHED();
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index d6595a1..28e749dc 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -135,11 +135,6 @@ const char kMSEAudioBufferSizeLimit[] = "mse-audio-buffer-size-limit"; const char kMSEVideoBufferSizeLimit[] = "mse-video-buffer-size-limit"; -// By default, if any CDM host (including signature) file is missing, the CDM -// will not be called to verify the host. Enable this switch to ignore missing -// CDM host files. This can be used in tests. -const char kIgnoreMissingCdmHostFile[] = "ignore-missing-cdm-host-file"; - } // namespace switches namespace media {
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 4200da1..89b4a03a 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -75,8 +75,6 @@ MEDIA_EXPORT extern const char kMSEAudioBufferSizeLimit[]; MEDIA_EXPORT extern const char kMSEVideoBufferSizeLimit[]; -MEDIA_EXPORT extern const char kIgnoreMissingCdmHostFile[]; - } // namespace switches namespace media {
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc index 655fd6a..18e4f87 100644 --- a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc +++ b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
@@ -272,22 +272,33 @@ // Makes sure files and corresponding signature files are readable but not // writable. bool VerifyCdmHost_0(const cdm::HostFile* host_files, uint32_t num_files) { - DVLOG(1) << __func__; + DVLOG(1) << __func__ << ": " << num_files; + + // We should always have the CDM and CDM adapter and at lease one common file. + // The common CDM host file (e.g. chrome) might not exist since we are running + // in browser_tests. + const uint32_t kMinNumHostFiles = 3; // We should always have the CDM and CDM adapter. - // We might not have any common CDM host file (e.g. chrome) since we are - // running in browser_tests. - if (num_files < 2) { + const int kNumCdmFiles = 2; + + if (num_files < kMinNumHostFiles) { LOG(ERROR) << "Too few host files: " << num_files; g_verify_host_files_result = false; return true; } + int num_opened_files = 0; for (uint32_t i = 0; i < num_files; ++i) { const int kBytesToRead = 10; std::vector<char> buffer(kBytesToRead); base::File file(static_cast<base::PlatformFile>(host_files[i].file)); + if (!file.IsValid()) + continue; + + num_opened_files++; + int bytes_read = file.Read(0, buffer.data(), buffer.size()); if (bytes_read != kBytesToRead) { LOG(ERROR) << "File bytes read: " << bytes_read; @@ -299,6 +310,13 @@ // TODO(xhwang): Also verify the signature file when it's available. } + // We should always have CDM files opened. + if (num_opened_files < kNumCdmFiles) { + LOG(ERROR) << "Too few opened files: " << num_opened_files; + g_verify_host_files_result = false; + return true; + } + g_verify_host_files_result = true; return true; }
diff --git a/media/gpu/vt_video_encode_accelerator_mac.cc b/media/gpu/vt_video_encode_accelerator_mac.cc index 77052f3..de0d8d7 100644 --- a/media/gpu/vt_video_encode_accelerator_mac.cc +++ b/media/gpu/vt_video_encode_accelerator_mac.cc
@@ -97,8 +97,7 @@ SupportedProfiles profiles; const bool rv = CreateCompressionSession( - video_toolbox::DictionaryWithKeysAndValues(nullptr, nullptr, 0), - gfx::Size(kDefaultResolutionWidth, kDefaultResolutionHeight), true); + gfx::Size(kDefaultResolutionWidth, kDefaultResolutionHeight)); DestroyCompressionSession(); if (!rv) { VLOG(1) @@ -453,22 +452,7 @@ DestroyCompressionSession(); - CFTypeRef attributes_keys[] = {kCVPixelBufferOpenGLCompatibilityKey, - kCVPixelBufferIOSurfacePropertiesKey, - kCVPixelBufferPixelFormatTypeKey}; - const int format[] = {kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange}; - CFTypeRef attributes_values[] = { - kCFBooleanTrue, - video_toolbox::DictionaryWithKeysAndValues(nullptr, nullptr, 0).release(), - video_toolbox::ArrayWithIntegers(format, arraysize(format)).release()}; - const base::ScopedCFTypeRef<CFDictionaryRef> attributes = - video_toolbox::DictionaryWithKeysAndValues( - attributes_keys, attributes_values, arraysize(attributes_keys)); - for (auto* v : attributes_values) - CFRelease(v); - - bool session_rv = - CreateCompressionSession(attributes, input_visible_size_, false); + bool session_rv = CreateCompressionSession(input_visible_size_); if (!session_rv) { DestroyCompressionSession(); return false; @@ -481,22 +465,12 @@ } bool VTVideoEncodeAccelerator::CreateCompressionSession( - base::ScopedCFTypeRef<CFDictionaryRef> attributes, - const gfx::Size& input_size, - bool require_hw_encoding) { + const gfx::Size& input_size) { DCHECK(thread_checker_.CalledOnValidThread()); - std::vector<CFTypeRef> encoder_keys; - std::vector<CFTypeRef> encoder_values; - if (require_hw_encoding) { - encoder_keys.push_back( - kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder); - encoder_values.push_back(kCFBooleanTrue); - } else { - encoder_keys.push_back( - kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder); - encoder_values.push_back(kCFBooleanTrue); - } + std::vector<CFTypeRef> encoder_keys( + 1, kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder); + std::vector<CFTypeRef> encoder_values(1, kCFBooleanTrue); base::ScopedCFTypeRef<CFDictionaryRef> encoder_spec = video_toolbox::DictionaryWithKeysAndValues( encoder_keys.data(), encoder_values.data(), encoder_keys.size()); @@ -512,7 +486,8 @@ // are guaranteed that the output callback will not execute again. OSStatus status = VTCompressionSessionCreate( kCFAllocatorDefault, input_size.width(), input_size.height(), - kCMVideoCodecType_H264, encoder_spec, attributes, + kCMVideoCodecType_H264, encoder_spec, + nullptr /* sourceImageBufferAttributes */, nullptr /* compressedDataAllocator */, &VTVideoEncodeAccelerator::CompressionCallback, reinterpret_cast<void*>(this), compression_session_.InitializeInto()); @@ -520,8 +495,8 @@ DLOG(ERROR) << " VTCompressionSessionCreate failed: " << status; return false; } - DVLOG(3) << " VTCompressionSession created with HW encode: " - << require_hw_encoding << ", input size=" << input_size.ToString(); + DVLOG(3) << " VTCompressionSession created with input size=" + << input_size.ToString(); return true; } @@ -542,6 +517,9 @@ kVTCompressionPropertyKey_MaxKeyFrameInterval, 7200); rv &= session_property_setter.Set( kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, 240); + rv &= + session_property_setter.Set(kVTCompressionPropertyKey_MaxFrameDelayCount, + static_cast<int>(kNumInputBuffers)); DLOG_IF(ERROR, !rv) << " Setting session property failed."; return rv; }
diff --git a/media/gpu/vt_video_encode_accelerator_mac.h b/media/gpu/vt_video_encode_accelerator_mac.h index a177b51..d596ffef 100644 --- a/media/gpu/vt_video_encode_accelerator_mac.h +++ b/media/gpu/vt_video_encode_accelerator_mac.h
@@ -87,12 +87,8 @@ // is configured using ConfigureCompressionSession(). bool ResetCompressionSession(); - // Create a compression session, with HW encoder enforced if - // |require_hw_encoding| is set. - bool CreateCompressionSession( - base::ScopedCFTypeRef<CFDictionaryRef> attributes, - const gfx::Size& input_size, - bool require_hw_encoding); + // Create a compression session. + bool CreateCompressionSession(const gfx::Size& input_size); // Configure the current compression session using current encoder settings. bool ConfigureCompressionSession();
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc index f03b2da..cc150452 100644 --- a/media/renderers/renderer_impl.cc +++ b/media/renderers/renderer_impl.cc
@@ -184,6 +184,11 @@ DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(flush_cb_.is_null()); + if (state_ == STATE_FLUSHED) { + task_runner_->PostTask(FROM_HERE, flush_cb); + return; + } + if (state_ != STATE_PLAYING) { DCHECK_EQ(state_, STATE_ERROR); return; @@ -202,13 +207,14 @@ DVLOG(1) << __func__; DCHECK(task_runner_->BelongsToCurrentThread()); - if (state_ != STATE_PLAYING) { + if (state_ != STATE_FLUSHED) { DCHECK_EQ(state_, STATE_ERROR); return; } time_source_->SetMediaTime(time); + state_ = STATE_PLAYING; if (audio_renderer_) audio_renderer_->StartPlaying(); if (video_renderer_) @@ -278,7 +284,7 @@ DCHECK(task_runner_->BelongsToCurrentThread()); // Playback rate changes are only carried out while playing. - if (state_ != STATE_PLAYING) + if (state_ != STATE_PLAYING && state_ != STATE_FLUSHED) return; time_source_->SetPlaybackRate(playback_rate); @@ -480,7 +486,7 @@ time_source_ = wall_clock_time_source_.get(); } - state_ = STATE_PLAYING; + state_ = STATE_FLUSHED; DCHECK(time_source_); DCHECK(audio_renderer_ || video_renderer_); @@ -552,7 +558,7 @@ DCHECK_EQ(video_buffering_state_, BUFFERING_HAVE_NOTHING); video_ended_ = false; - state_ = STATE_PLAYING; + state_ = STATE_FLUSHED; base::ResetAndReturn(&flush_cb_).Run(); } @@ -733,6 +739,7 @@ break; case STATE_FLUSHING: + case STATE_FLUSHED: // It's OK to pause playback when flushing. break;
diff --git a/media/renderers/renderer_impl.h b/media/renderers/renderer_impl.h index f55a763..0a30165 100644 --- a/media/renderers/renderer_impl.h +++ b/media/renderers/renderer_impl.h
@@ -82,8 +82,9 @@ STATE_UNINITIALIZED, STATE_INIT_PENDING_CDM, // Initialization is waiting for the CDM to be set. STATE_INITIALIZING, // Initializing audio/video renderers. - STATE_FLUSHING, - STATE_PLAYING, + STATE_FLUSHING, // Flushing is in progress. + STATE_FLUSHED, // After initialization or after flush completed. + STATE_PLAYING, // After StartPlayingFrom has been called. STATE_ERROR };
diff --git a/media/renderers/renderer_impl_unittest.cc b/media/renderers/renderer_impl_unittest.cc index 77480f9..bbbaa2c 100644 --- a/media/renderers/renderer_impl_unittest.cc +++ b/media/renderers/renderer_impl_unittest.cc
@@ -492,7 +492,10 @@ TEST_F(RendererImplTest, FlushAfterInitialization) { InitializeWithAudioAndVideo(); - Flush(true); + EXPECT_CALL(callbacks_, OnFlushed()); + renderer_impl_->Flush( + base::Bind(&CallbackHelper::OnFlushed, base::Unretained(&callbacks_))); + base::RunLoop().RunUntilIdle(); } TEST_F(RendererImplTest, FlushAfterPlay) {
diff --git a/net/BUILD.gn b/net/BUILD.gn index a39405a..3151bda 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1401,6 +1401,8 @@ "reporting/reporting_cache.h", "reporting/reporting_client.cc", "reporting/reporting_client.h", + "reporting/reporting_delivery_agent.cc", + "reporting/reporting_delivery_agent.h", "reporting/reporting_endpoint_manager.cc", "reporting/reporting_endpoint_manager.h", "reporting/reporting_header_parser.cc", @@ -4621,6 +4623,7 @@ "quic/test_tools/simulator/traffic_policer.cc", "quic/test_tools/simulator/traffic_policer.h", "reporting/reporting_cache_unittest.cc", + "reporting/reporting_delivery_agent_unittest.cc", "reporting/reporting_endpoint_manager_unittest.cc", "reporting/reporting_header_parser_unittest.cc", "reporting/reporting_test_util.cc",
diff --git a/net/http/bidirectional_stream.cc b/net/http/bidirectional_stream.cc index ea65dca..a8fe3ad 100644 --- a/net/http/bidirectional_stream.cc +++ b/net/http/bidirectional_stream.cc
@@ -124,7 +124,8 @@ session->http_stream_factory()->RequestBidirectionalStreamImpl( http_request_info, request_info_->priority, server_ssl_config, server_ssl_config, this, - /* enable_ip_based_pooling = */ true, net_log_)); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, net_log_)); // Check that this call cannot fail to set a non-NULL |stream_request_|. DCHECK(stream_request_); // Check that HttpStreamFactory does not invoke OnBidirectionalStreamImplReady
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 5961f42..19a70d9 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc
@@ -102,6 +102,7 @@ next_state_(STATE_NONE), establishing_tunnel_(false), enable_ip_based_pooling_(true), + enable_alternative_services_(true), websocket_handshake_stream_base_create_helper_(NULL), net_error_details_() {} @@ -850,17 +851,21 @@ response_.network_accessed = true; next_state_ = STATE_CREATE_STREAM_COMPLETE; + // IP based pooling and Alternative Services are disabled under the same + // circumstances: on a retry after 421 Misdirected Request is received. + DCHECK(enable_ip_based_pooling_ == enable_alternative_services_); if (ForWebSocketHandshake()) { stream_request_.reset( session_->http_stream_factory_for_websocket() ->RequestWebSocketHandshakeStream( *request_, priority_, server_ssl_config_, proxy_ssl_config_, this, websocket_handshake_stream_base_create_helper_, - enable_ip_based_pooling_, net_log_)); + enable_ip_based_pooling_, enable_alternative_services_, + net_log_)); } else { stream_request_.reset(session_->http_stream_factory()->RequestStream( *request_, priority_, server_ssl_config_, proxy_ssl_config_, this, - enable_ip_based_pooling_, net_log_)); + enable_ip_based_pooling_, enable_alternative_services_, net_log_)); } DCHECK(stream_request_.get()); return ERR_IO_PENDING; @@ -1553,11 +1558,12 @@ break; case ERR_MISDIRECTED_REQUEST: // If this is the second try, just give up. - if (!enable_ip_based_pooling_) + if (!enable_ip_based_pooling_ && !enable_alternative_services_) return OK; - // Otherwise, since the response status was 421 Misdirected Request, - // retry the request with IP based pooling disabled. + // Otherwise retry the request with both IP based pooling + // and Alternative Services disabled. enable_ip_based_pooling_ = false; + enable_alternative_services_ = false; net_log_.AddEventWithNetErrorCode( NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); ResetConnectionAndRequestForResend();
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index 10b2aa3..550b24b 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h
@@ -377,6 +377,9 @@ // even if the SpdySessionKey is different. bool enable_ip_based_pooling_; + // Enable using alternative services for the request. + bool enable_alternative_services_; + // The helper object to use to create WebSocketHandshakeStreamBase // objects. Only relevant when establishing a WebSocket connection. WebSocketHandshakeStreamBase::CreateHelper*
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 6e02e73..0314f62 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -15085,6 +15085,7 @@ const SSLConfig& proxy_ssl_config, HttpStreamRequest::Delegate* delegate, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) override { FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate); last_stream_request_ = fake_request->AsWeakPtr(); @@ -15098,6 +15099,7 @@ const SSLConfig& proxy_ssl_config, HttpStreamRequest::Delegate* delegate, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) override { NOTREACHED(); return nullptr; @@ -15111,6 +15113,7 @@ HttpStreamRequest::Delegate* delegate, WebSocketHandshakeStreamBase::CreateHelper* create_helper, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) override { FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate, create_helper);
diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h index 4dd1540..95aca6b 100644 --- a/net/http/http_stream_factory.h +++ b/net/http/http_stream_factory.h
@@ -209,6 +209,7 @@ const SSLConfig& proxy_ssl_config, HttpStreamRequest::Delegate* delegate, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) = 0; // Request a WebSocket handshake stream. @@ -222,6 +223,7 @@ HttpStreamRequest::Delegate* delegate, WebSocketHandshakeStreamBase::CreateHelper* create_helper, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) = 0; // Request a BidirectionalStreamImpl. @@ -234,6 +236,7 @@ const SSLConfig& proxy_ssl_config, HttpStreamRequest::Delegate* delegate, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) = 0; // Requests that enough connections for |num_streams| be opened.
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc index 973c536..13948e47f 100644 --- a/net/http/http_stream_factory_impl.cc +++ b/net/http/http_stream_factory_impl.cc
@@ -138,12 +138,13 @@ const SSLConfig& proxy_ssl_config, HttpStreamRequest::Delegate* delegate, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) { DCHECK(!for_websockets_); - return RequestStreamInternal(request_info, priority, server_ssl_config, - proxy_ssl_config, delegate, nullptr, - HttpStreamRequest::HTTP_STREAM, - enable_ip_based_pooling, net_log); + return RequestStreamInternal( + request_info, priority, server_ssl_config, proxy_ssl_config, delegate, + nullptr, HttpStreamRequest::HTTP_STREAM, enable_ip_based_pooling, + enable_alternative_services, net_log); } HttpStreamRequest* HttpStreamFactoryImpl::RequestWebSocketHandshakeStream( @@ -154,13 +155,14 @@ HttpStreamRequest::Delegate* delegate, WebSocketHandshakeStreamBase::CreateHelper* create_helper, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) { DCHECK(for_websockets_); DCHECK(create_helper); - return RequestStreamInternal(request_info, priority, server_ssl_config, - proxy_ssl_config, delegate, create_helper, - HttpStreamRequest::HTTP_STREAM, - enable_ip_based_pooling, net_log); + return RequestStreamInternal( + request_info, priority, server_ssl_config, proxy_ssl_config, delegate, + create_helper, HttpStreamRequest::HTTP_STREAM, enable_ip_based_pooling, + enable_alternative_services, net_log); } HttpStreamRequest* HttpStreamFactoryImpl::RequestBidirectionalStreamImpl( @@ -170,14 +172,15 @@ const SSLConfig& proxy_ssl_config, HttpStreamRequest::Delegate* delegate, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) { DCHECK(!for_websockets_); DCHECK(request_info.url.SchemeIs(url::kHttpsScheme)); - return RequestStreamInternal(request_info, priority, server_ssl_config, - proxy_ssl_config, delegate, nullptr, - HttpStreamRequest::BIDIRECTIONAL_STREAM, - enable_ip_based_pooling, net_log); + return RequestStreamInternal( + request_info, priority, server_ssl_config, proxy_ssl_config, delegate, + nullptr, HttpStreamRequest::BIDIRECTIONAL_STREAM, enable_ip_based_pooling, + enable_alternative_services, net_log); } HttpStreamRequest* HttpStreamFactoryImpl::RequestStreamInternal( @@ -190,10 +193,12 @@ websocket_handshake_stream_create_helper, HttpStreamRequest::StreamType stream_type, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) { auto job_controller = base::MakeUnique<JobController>( this, delegate, session_, job_factory_.get(), request_info, - /* is_preconnect = */ false, enable_ip_based_pooling); + /* is_preconnect = */ false, enable_ip_based_pooling, + enable_alternative_services); JobController* job_controller_raw_ptr = job_controller.get(); job_controller_set_.insert(std::move(job_controller)); Request* request = job_controller_raw_ptr->Start( @@ -218,7 +223,8 @@ auto job_controller = base::MakeUnique<JobController>( this, nullptr, session_, job_factory_.get(), request_info, /* is_preconnect = */ true, - /* enable_ip_based_pooling = */ true); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true); JobController* job_controller_raw_ptr = job_controller.get(); job_controller_set_.insert(std::move(job_controller)); job_controller_raw_ptr->Preconnect(num_streams, request_info,
diff --git a/net/http/http_stream_factory_impl.h b/net/http/http_stream_factory_impl.h index 6fd07a95..ce29d1f7 100644 --- a/net/http/http_stream_factory_impl.h +++ b/net/http/http_stream_factory_impl.h
@@ -50,6 +50,7 @@ const SSLConfig& proxy_ssl_config, HttpStreamRequest::Delegate* delegate, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) override; HttpStreamRequest* RequestWebSocketHandshakeStream( @@ -60,6 +61,7 @@ HttpStreamRequest::Delegate* delegate, WebSocketHandshakeStreamBase::CreateHelper* create_helper, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) override; HttpStreamRequest* RequestBidirectionalStreamImpl( @@ -69,6 +71,7 @@ const SSLConfig& proxy_ssl_config, HttpStreamRequest::Delegate* delegate, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log) override; void PreconnectStreams(int num_streams, const HttpRequestInfo& info) override; @@ -126,6 +129,7 @@ WebSocketHandshakeStreamBase::CreateHelper* create_helper, HttpStreamRequest::StreamType stream_type, bool enable_ip_based_pooling, + bool enable_alternative_services, const NetLogWithSource& net_log); // Called when a SpdySession is ready. It will find appropriate Requests and
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index c03fe25..fcff283 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc
@@ -849,6 +849,7 @@ } int HttpStreamFactoryImpl::Job::DoInitConnection() { + net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_JOB_INIT_CONNECTION); int result = DoInitConnectionImpl(); if (result != ERR_SPDY_SESSION_ALREADY_EXISTS) delegate_->OnConnectionInitialized(this, result); @@ -1020,6 +1021,7 @@ } int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { + net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB_INIT_CONNECTION); if (job_type_ == PRECONNECT) { if (using_quic_) return result;
diff --git a/net/http/http_stream_factory_impl_job_controller.cc b/net/http/http_stream_factory_impl_job_controller.cc index 7c420b5..b05bacf 100644 --- a/net/http/http_stream_factory_impl_job_controller.cc +++ b/net/http/http_stream_factory_impl_job_controller.cc
@@ -49,7 +49,8 @@ JobFactory* job_factory, const HttpRequestInfo& request_info, bool is_preconnect, - bool enable_ip_based_pooling) + bool enable_ip_based_pooling, + bool enable_alternative_services) : factory_(factory), session_(session), job_factory_(job_factory), @@ -57,6 +58,7 @@ delegate_(delegate), is_preconnect_(is_preconnect), enable_ip_based_pooling_(enable_ip_based_pooling), + enable_alternative_services_(enable_alternative_services), alternative_job_net_error_(OK), job_bound_(false), main_job_is_blocked_(false), @@ -926,6 +928,9 @@ const HttpRequestInfo& request_info, HttpStreamRequest::Delegate* delegate, HttpStreamRequest::StreamType stream_type) { + if (!enable_alternative_services_) + return AlternativeService(); + AlternativeService alternative_service = GetAlternativeServiceForInternal(request_info, delegate, stream_type); AlternativeServiceType type; @@ -1064,6 +1069,10 @@ const GURL& url, ProxyServer* alternative_proxy_server) const { DCHECK(!alternative_proxy_server->is_valid()); + + if (!enable_alternative_services_) + return false; + if (!can_start_alternative_proxy_job_) { // Either an alternative service job or an alternative proxy server job has // already been started.
diff --git a/net/http/http_stream_factory_impl_job_controller.h b/net/http/http_stream_factory_impl_job_controller.h index a0b0da7..60e22e8d 100644 --- a/net/http/http_stream_factory_impl_job_controller.h +++ b/net/http/http_stream_factory_impl_job_controller.h
@@ -25,7 +25,8 @@ JobFactory* job_factory, const HttpRequestInfo& request_info, bool is_preconnect, - bool enable_ip_based_pooling); + bool enable_ip_based_pooling, + bool enable_alternative_services); ~JobController() override; @@ -290,6 +291,9 @@ // the SpdySessionKey is different. const bool enable_ip_based_pooling_; + // Enable using alternative services for the request. + const bool enable_alternative_services_; + // |main_job_| is a job waiting to see if |alternative_job_| can reuse a // connection. If |alternative_job_| is unable to do so, |this| will notify // |main_job_| to proceed and then race the two jobs.
diff --git a/net/http/http_stream_factory_impl_job_controller_unittest.cc b/net/http/http_stream_factory_impl_job_controller_unittest.cc index 2f851aa..1c00041 100644 --- a/net/http/http_stream_factory_impl_job_controller_unittest.cc +++ b/net/http/http_stream_factory_impl_job_controller_unittest.cc
@@ -129,6 +129,8 @@ : session_deps_(ProxyService::CreateDirect()), use_alternative_proxy_(false), is_preconnect_(false), + enable_ip_based_pooling_(true), + enable_alternative_services_(true), test_proxy_delegate_(nullptr) { session_deps_.enable_quic = true; } @@ -143,6 +145,16 @@ is_preconnect_ = true; } + void DisableIPBasedPooling() { + ASSERT_FALSE(test_proxy_delegate_); + enable_ip_based_pooling_ = false; + } + + void DisableAlternativeServices() { + ASSERT_FALSE(test_proxy_delegate_); + enable_alternative_services_ = false; + } + void Initialize(const HttpRequestInfo& request_info) { ASSERT_FALSE(test_proxy_delegate_); std::unique_ptr<TestProxyDelegate> test_proxy_delegate( @@ -164,7 +176,8 @@ static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); job_controller_ = new HttpStreamFactoryImpl::JobController( factory_, &request_delegate_, session_.get(), &job_factory_, - request_info, is_preconnect_, /* enable_ip_based_pooling = */ true); + request_info, is_preconnect_, enable_ip_based_pooling_, + enable_alternative_services_); HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); } @@ -205,6 +218,8 @@ private: bool use_alternative_proxy_; bool is_preconnect_; + bool enable_ip_based_pooling_; + bool enable_alternative_services_; // Not owned by |this|. TestProxyDelegate* test_proxy_delegate_; @@ -1342,6 +1357,64 @@ EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); } +class HttpStreamFactoryImplJobControllerMisdirectedRequestRetry + : public HttpStreamFactoryImplJobControllerTest, + public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {}; + +INSTANTIATE_TEST_CASE_P( + /* no prefix */, + HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, + ::testing::Combine(::testing::Bool(), ::testing::Bool())); + +TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, + DisableIPBasedPoolingAndAlternativeServices) { + const bool enable_ip_based_pooling = ::testing::get<0>(GetParam()); + const bool enable_alternative_services = ::testing::get<1>(GetParam()); + + ProxyConfig proxy_config; + proxy_config.set_auto_detect(true); + // Use asynchronous proxy resolver. + MockAsyncProxyResolverFactory* proxy_resolver_factory = + new MockAsyncProxyResolverFactory(false); + session_deps_.proxy_service.reset( + new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), + base::WrapUnique(proxy_resolver_factory), nullptr)); + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("https://www.google.com"); + + if (!enable_ip_based_pooling) + DisableIPBasedPooling(); + if (!enable_alternative_services) + DisableAlternativeServices(); + + Initialize(request_info); + + url::SchemeHostPort server(request_info.url); + AlternativeService alternative_service(kProtoQUIC, server.host(), 443); + SetAlternativeService(request_info, alternative_service); + + request_.reset( + job_controller_->Start(request_info, &request_delegate_, nullptr, + NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, + DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); + EXPECT_TRUE(job_controller_->main_job()); + if (enable_alternative_services) { + EXPECT_TRUE(job_controller_->alternative_job()); + } else { + EXPECT_FALSE(job_controller_->alternative_job()); + } + + // |main_job| succeeds and should report status to Request. + HttpStream* http_stream = + new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); + job_factory_.main_job()->SetStream(http_stream); + + EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) + .WillOnce(Invoke(DeleteHttpStreamPointer)); + job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); +} + class HttpStreamFactoryImplJobControllerPreconnectTest : public HttpStreamFactoryImplJobControllerTest, public ::testing::WithParamInterface<bool> { @@ -1364,7 +1437,8 @@ job_controller_ = new HttpStreamFactoryImpl::JobController( factory_, &request_delegate_, session_.get(), &job_factory_, request_info_, /* is_preconnect = */ true, - /* enable_ip_based_pooling = */ true); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true); HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); }
diff --git a/net/http/http_stream_factory_impl_request_unittest.cc b/net/http/http_stream_factory_impl_request_unittest.cc index 5dab0cc..b2bff0ea 100644 --- a/net/http/http_stream_factory_impl_request_unittest.cc +++ b/net/http/http_stream_factory_impl_request_unittest.cc
@@ -36,7 +36,8 @@ auto job_controller = base::MakeUnique<HttpStreamFactoryImpl::JobController>( factory, &request_delegate, session.get(), &job_factory, request_info, /* is_preconnect = */ false, - /* enable_ip_based_pooling = */ true); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true); HttpStreamFactoryImpl::JobController* job_controller_raw_ptr = job_controller.get(); factory->job_controller_set_.insert(std::move(job_controller));
diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc index d26f9fb..2ac222b 100644 --- a/net/http/http_stream_factory_impl_unittest.cc +++ b/net/http/http_stream_factory_impl_unittest.cc
@@ -693,7 +693,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); // The proxy that failed should now be known to the proxy_service as bad. @@ -777,7 +778,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); // The proxy that failed should now be known to the proxy_service as bad. @@ -980,7 +982,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); // The proxy that failed should now be known to the proxy_service as @@ -1083,7 +1086,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); // The proxy that failed should now be known to the proxy_service as @@ -1427,7 +1431,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); // The stream shouldn't come from spdy as we are using different privacy mode @@ -1503,7 +1508,8 @@ std::unique_ptr<HttpStreamRequest> request1( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1); @@ -1511,7 +1517,8 @@ std::unique_ptr<HttpStreamRequest> request2( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1); @@ -1520,7 +1527,8 @@ std::unique_ptr<HttpStreamRequest> request3( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2); @@ -1549,7 +1557,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState()); @@ -1578,7 +1587,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); ASSERT_TRUE(nullptr != waiter.stream()); @@ -1627,7 +1637,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, LOWEST, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); EXPECT_FALSE(waiter.stream_done()); // Confirm a stream has been created by asserting that a new session @@ -1670,7 +1681,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); ASSERT_TRUE(nullptr != waiter.stream()); @@ -1712,7 +1724,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); ASSERT_TRUE(nullptr != waiter.stream()); @@ -1794,7 +1807,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); ASSERT_TRUE(nullptr != waiter.stream()); @@ -1844,7 +1858,8 @@ ->RequestWebSocketHandshakeStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, &create_helper, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); EXPECT_TRUE(nullptr == waiter.stream()); @@ -1888,7 +1903,8 @@ ->RequestWebSocketHandshakeStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, &create_helper, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); EXPECT_TRUE(nullptr == waiter.stream()); @@ -1930,7 +1946,8 @@ ->RequestWebSocketHandshakeStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, &create_helper, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); EXPECT_TRUE(nullptr == waiter.stream()); @@ -1984,7 +2001,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); EXPECT_TRUE(nullptr == waiter.websocket_stream()); @@ -2038,7 +2056,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); EXPECT_TRUE(nullptr == waiter.websocket_stream()); @@ -2124,11 +2143,13 @@ std::unique_ptr<HttpStreamRequest> request1( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter1, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); std::unique_ptr<HttpStreamRequest> request2( session->http_stream_factory()->RequestStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter2, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter1.WaitForStream(); waiter2.WaitForStream(); EXPECT_TRUE(waiter1.stream_done()); @@ -2170,7 +2191,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestBidirectionalStreamImpl( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); EXPECT_FALSE(waiter.websocket_stream()); @@ -2343,7 +2365,8 @@ std::unique_ptr<HttpStreamRequest> request( session()->http_stream_factory()->RequestBidirectionalStreamImpl( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); @@ -2408,7 +2431,8 @@ std::unique_ptr<HttpStreamRequest> request( session()->http_stream_factory()->RequestBidirectionalStreamImpl( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); @@ -2470,7 +2494,8 @@ std::unique_ptr<HttpStreamRequest> request( session()->http_stream_factory()->RequestBidirectionalStreamImpl( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); @@ -2537,7 +2562,8 @@ std::unique_ptr<HttpStreamRequest> request( session->http_stream_factory()->RequestBidirectionalStreamImpl( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); ASSERT_THAT(waiter.error_status(), IsError(ERR_FAILED)); @@ -2586,7 +2612,8 @@ ->RequestWebSocketHandshakeStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter1, &create_helper, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter1.WaitForStream(); EXPECT_TRUE(waiter1.stream_done()); ASSERT_TRUE(nullptr != waiter1.websocket_stream()); @@ -2634,7 +2661,8 @@ ->RequestWebSocketHandshakeStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter1, &create_helper, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter1.WaitForStream(); EXPECT_TRUE(waiter1.stream_done()); ASSERT_TRUE(nullptr != waiter1.websocket_stream()); @@ -2648,7 +2676,8 @@ ->RequestWebSocketHandshakeStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter2, &create_helper, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter2.WaitForStream(); EXPECT_TRUE(waiter2.stream_done()); ASSERT_TRUE(nullptr != waiter2.websocket_stream()); @@ -2715,7 +2744,8 @@ ->RequestWebSocketHandshakeStream( request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, &waiter, &create_helper, - /* enable_ip_based_pooling = */ true, NetLogWithSource())); + /* enable_ip_based_pooling = */ true, + /* enable_alternative_services = */ true, NetLogWithSource())); waiter.WaitForStream(); EXPECT_TRUE(waiter.stream_done()); EXPECT_TRUE(nullptr == waiter.stream());
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index ed6a0c8..5e8fe84a 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -1084,6 +1084,9 @@ // } EVENT_TYPE(HTTP_STREAM_JOB_PROXY_SERVER_RESOLVED) +// Emitted when a job is asked to initialize a connection. +EVENT_TYPE(HTTP_STREAM_JOB_INIT_CONNECTION) + // Identifies the NetLogSource() for the Job that fulfilled the Request. // The event parameters are: // {
diff --git a/net/quic/chromium/quic_network_transaction_unittest.cc b/net/quic/chromium/quic_network_transaction_unittest.cc index 9d5ac29..c6a8fee8 100644 --- a/net/quic/chromium/quic_network_transaction_unittest.cc +++ b/net/quic/chromium/quic_network_transaction_unittest.cc
@@ -1052,6 +1052,69 @@ SendRequestAndExpectQuicResponse("hello!"); } +// Regression test for https://crbug.com/546991. +// The server might not be able to serve a request on an alternative connection, +// and might send a 421 Misdirected Request response status to indicate this. +// HttpNetworkTransaction should reset the request and retry without using +// alternative services. +TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) { + // Set up alternative service to use QUIC. + // Note that |origins_to_force_quic_on| cannot be used in this test, because + // that overrides |enable_alternative_services|. + url::SchemeHostPort server(request_.url); + AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName, + 443); + base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); + http_server_properties_.SetAlternativeService(server, alternative_service, + expiration); + + // First try: alternative job uses QUIC, gets 421 Misdirected Request error. + MockQuicData mock_quic_data; + QuicStreamOffset request_header_offset = 0; + mock_quic_data.AddWrite(ConstructSettingsPacket( + 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, + &request_header_offset)); + mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( + 2, kClientDataStreamId1, true, true, + GetRequestHeaders("GET", "https", "/"), &request_header_offset)); + mock_quic_data.AddRead( + ConstructServerResponseHeadersPacket(1, kClientDataStreamId1, false, true, + GetResponseHeaders("421"), nullptr)); + mock_quic_data.AddWrite(ConstructClientAckAndRstPacket( + 3, kClientDataStreamId1, QUIC_STREAM_CANCELLED, 1, 1, 1)); + mock_quic_data.AddRead(ASYNC, OK); + mock_quic_data.AddSocketDataToFactory(&socket_factory_); + + // First try: main job uses TCP, connection fails. + // (A hanging connection would not work here, because the main Job on the + // second try would pool to that socket and hang.) + StaticSocketDataProvider failing_data; + MockConnect failing_connect(SYNCHRONOUS, ERR_CONNECTION_CLOSED); + failing_data.set_connect_data(failing_connect); + socket_factory_.AddSocketDataProvider(&failing_data); + socket_factory_.AddSSLSocketDataProvider(&ssl_data_); + + // Second try: there is only one job, which succeeds over HTTP/1.1. + // There is no open TCP socket (the previous TCP connection got closed), so a + // new one is opened. + // Note that if there was an alternative QUIC Job created for the second try, + // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR. + // Therefore this test ensures that no alternative Job is created on retry. + MockRead reads[] = {MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello!"), + MockRead(ASYNC, OK)}; + StaticSocketDataProvider http_data(reads, arraysize(reads), nullptr, 0); + socket_factory_.AddSocketDataProvider(&http_data); + socket_factory_.AddSSLSocketDataProvider(&ssl_data_); + + // Retry logic hides ERR_MISDIRECTED_REQUEST: transaction succeeds. + CreateSession(); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); + RunTransaction(&trans); + CheckWasHttpResponse(&trans); + CheckResponsePort(&trans, 443); + CheckResponseData(&trans, "hello!"); +} + TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) { params_.origins_to_force_quic_on.insert( HostPortPair::FromString("mail.example.org:443"));
diff --git a/net/reporting/reporting_delivery_agent.cc b/net/reporting/reporting_delivery_agent.cc new file mode 100644 index 0000000..b0d54dd --- /dev/null +++ b/net/reporting/reporting_delivery_agent.cc
@@ -0,0 +1,150 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/reporting/reporting_delivery_agent.h" + +#include <map> +#include <string> +#include <vector> + +#include "base/bind.h" +#include "base/json/json_writer.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/time/tick_clock.h" +#include "base/values.h" +#include "net/reporting/reporting_cache.h" +#include "net/reporting/reporting_endpoint_manager.h" +#include "net/reporting/reporting_report.h" +#include "net/reporting/reporting_uploader.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace net { + +namespace { + +void SerializeReports(const std::vector<const ReportingReport*>& reports, + base::TimeTicks now, + std::string* json_out) { + base::ListValue reports_value; + + for (const ReportingReport* report : reports) { + std::unique_ptr<base::DictionaryValue> report_value = + base::MakeUnique<base::DictionaryValue>(); + + report_value->SetInteger("age", (now - report->queued).InMilliseconds()); + report_value->SetString("type", report->type); + report_value->SetString("url", report->url.spec()); + report_value->Set("report", report->body->DeepCopy()); + + reports_value.Append(std::move(report_value)); + } + + bool json_written = base::JSONWriter::Write(reports_value, json_out); + DCHECK(json_written); +} + +} // namespace + +ReportingDeliveryAgent::ReportingDeliveryAgent( + base::TickClock* clock, + ReportingCache* cache, + ReportingUploader* uploader, + const BackoffEntry::Policy* endpoint_backoff_policy) + : clock_(clock), + cache_(cache), + uploader_(uploader), + endpoint_manager_(clock, cache, endpoint_backoff_policy), + weak_factory_(this) {} +ReportingDeliveryAgent::~ReportingDeliveryAgent() {} + +class ReportingDeliveryAgent::Delivery { + public: + Delivery(const GURL& endpoint, + const std::vector<const ReportingReport*>& reports) + : endpoint(endpoint), reports(reports) {} + + ~Delivery() {} + + const GURL endpoint; + const std::vector<const ReportingReport*> reports; +}; + +void ReportingDeliveryAgent::SendReports() { + std::vector<const ReportingReport*> reports; + cache_->GetReports(&reports); + + // Sort reports into (origin, group) buckets. + std::map<OriginGroup, std::vector<const ReportingReport*>> + origin_group_reports; + for (const ReportingReport* report : reports) { + OriginGroup origin_group(url::Origin(report->url), report->group); + origin_group_reports[origin_group].push_back(report); + } + + // Find endpoint for each (origin, group) bucket and sort reports into + // endpoint buckets. Don't allow concurrent deliveries to the same (origin, + // group) bucket. + std::map<GURL, std::vector<const ReportingReport*>> endpoint_reports; + for (auto& it : origin_group_reports) { + const OriginGroup& origin_group = it.first; + + if (base::ContainsKey(pending_origin_groups_, origin_group)) + continue; + + GURL endpoint_url; + if (!endpoint_manager_.FindEndpointForOriginAndGroup( + origin_group.first, origin_group.second, &endpoint_url)) { + continue; + } + + endpoint_reports[endpoint_url].insert(endpoint_reports[endpoint_url].end(), + it.second.begin(), it.second.end()); + pending_origin_groups_.insert(origin_group); + } + + // Start a delivery to each endpoint. + for (auto& it : endpoint_reports) { + const GURL& endpoint = it.first; + const std::vector<const ReportingReport*>& reports = it.second; + + endpoint_manager_.SetEndpointPending(endpoint); + cache_->SetReportsPending(reports); + + std::string json; + SerializeReports(reports, clock_->NowTicks(), &json); + + uploader_->StartUpload( + endpoint, json, + base::Bind(&ReportingDeliveryAgent::OnUploadComplete, + weak_factory_.GetWeakPtr(), + base::MakeUnique<Delivery>(endpoint, reports))); + } +} + +void ReportingDeliveryAgent::OnUploadComplete( + const std::unique_ptr<Delivery>& delivery, + ReportingUploader::Outcome outcome) { + if (outcome == ReportingUploader::Outcome::SUCCESS) { + cache_->RemoveReports(delivery->reports); + endpoint_manager_.InformOfEndpointRequest(delivery->endpoint, true); + } else { + cache_->IncrementReportsAttempts(delivery->reports); + endpoint_manager_.InformOfEndpointRequest(delivery->endpoint, false); + } + + if (outcome == ReportingUploader::Outcome::REMOVE_ENDPOINT) + cache_->RemoveClientsForEndpoint(delivery->endpoint); + + for (const ReportingReport* report : delivery->reports) { + pending_origin_groups_.erase( + OriginGroup(url::Origin(report->url), report->group)); + } + + cache_->ClearReportsPending(delivery->reports); + endpoint_manager_.ClearEndpointPending(delivery->endpoint); +} + +} // namespace net
diff --git a/net/reporting/reporting_delivery_agent.h b/net/reporting/reporting_delivery_agent.h new file mode 100644 index 0000000..f6cda81 --- /dev/null +++ b/net/reporting/reporting_delivery_agent.h
@@ -0,0 +1,99 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_REPORTING_REPORTING_DELIVERY_AGENT_H_ +#define NET_REPORTING_REPORTING_DELIVERY_AGENT_H_ + +#include <memory> +#include <set> +#include <string> +#include <utility> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "net/base/backoff_entry.h" +#include "net/base/net_export.h" +#include "net/reporting/reporting_endpoint_manager.h" +#include "net/reporting/reporting_uploader.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace base { +class TickClock; +} // namespace base + +namespace net { + +class ReportingCache; + +// Takes reports from the ReportingCache, assembles reports into deliveries to +// endpoints, and sends those deliveries using ReportingUploader. +// +// Since the Reporting spec is completely silent on issues of concurrency, the +// delivery agent handles it as so: +// +// 1. An individual report can only be included in one delivery at once -- if +// SendReports is called again while a report is being delivered, it won't +// be included in another delivery during that call to SendReports. (This is, +// in fact, made redundant by rule 3, but it's included anyway in case rule 3 +// changes.) +// +// 2. An endpoint can only be the target of one delivery at once -- if +// SendReports is called again with reports that could be delivered to that +// endpoint, they won't be delivered to that endpoint. +// +// 3. Reports for an (origin, group) tuple can only be included in one delivery +// at once -- if SendReports is called again with reports in that (origin, +// group), they won't be included in any delivery during that call to +// SendReports. (This prevents the agent from getting around rule 2 by using +// other endpoints in the same group.) +// +// 4. Reports for the same origin *can* be included in multiple parallel +// deliveries if they are in different groups within that origin. +// +// (Note that a single delivery can contain an infinite number of reports.) +// +// TODO(juliatuttle): Consider capping the maximum number of reports per +// delivery attempt. +class NET_EXPORT ReportingDeliveryAgent { + public: + // |clock|, |cache|, |uploader|, and |endpoint_backoff_policy| must all + // outlive the ReportingDeliveryAgent. + ReportingDeliveryAgent(base::TickClock* clock, + ReportingCache* cache, + ReportingUploader* uploader, + const BackoffEntry::Policy* endpoint_backoff_policy); + ~ReportingDeliveryAgent(); + + // Tries to deliver all of the reports in the cache. Reports that are already + // being delivered will not be attempted a second time, and reports that do + // not have a viable endpoint will be neither attempted nor removed. + void SendReports(); + + private: + class Delivery; + + using OriginGroup = std::pair<url::Origin, std::string>; + + void OnUploadComplete(const std::unique_ptr<Delivery>& delivery, + ReportingUploader::Outcome outcome); + + base::TickClock* clock_; + ReportingCache* cache_; + ReportingUploader* uploader_; + + ReportingEndpointManager endpoint_manager_; + + // Tracks OriginGroup tuples for which there is a pending delivery running. + // (Would be an unordered_set, but there's no hash on pair.) + std::set<OriginGroup> pending_origin_groups_; + + base::WeakPtrFactory<ReportingDeliveryAgent> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(ReportingDeliveryAgent); +}; + +} // namespace net + +#endif // NET_REPORTING_REPORTING_DELIVERY_AGENT_H_
diff --git a/net/reporting/reporting_delivery_agent_unittest.cc b/net/reporting/reporting_delivery_agent_unittest.cc new file mode 100644 index 0000000..b2d8fbfd --- /dev/null +++ b/net/reporting/reporting_delivery_agent_unittest.cc
@@ -0,0 +1,382 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/reporting/reporting_delivery_agent.h" + +#include <vector> + +#include "base/json/json_reader.h" +#include "base/memory/ptr_util.h" +#include "base/test/simple_test_tick_clock.h" +#include "base/test/values_test_util.h" +#include "base/time/time.h" +#include "base/values.h" +#include "net/base/backoff_entry.h" +#include "net/reporting/reporting_cache.h" +#include "net/reporting/reporting_report.h" +#include "net/reporting/reporting_test_util.h" +#include "net/reporting/reporting_uploader.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace net { +namespace { + +class MockUploader : public ReportingUploader { + public: + class PendingUpload { + public: + PendingUpload(MockUploader* uploader, + const GURL& url, + const std::string& json, + const Callback& callback) + : uploader_(uploader), url_(url), json_(json), callback_(callback) { + DCHECK(uploader_); + } + + ~PendingUpload() {} + + void Complete(Outcome outcome) { + callback_.Run(outcome); + // Deletes |this|. + uploader_->OnUploadComplete(this); + } + + const GURL& url() const { return url_; } + const std::string& json() const { return json_; } + + std::unique_ptr<base::Value> GetValue() const { + return base::JSONReader::Read(json_); + } + + private: + MockUploader* uploader_; + GURL url_; + std::string json_; + Callback callback_; + }; + + MockUploader() {} + ~MockUploader() override {} + + void StartUpload(const GURL& url, + const std::string& json, + const Callback& callback) override { + uploads_.push_back( + base::MakeUnique<PendingUpload>(this, url, json, callback)); + } + + const std::vector<std::unique_ptr<PendingUpload>>& pending_uploads() const { + return uploads_; + } + + void OnUploadComplete(PendingUpload* upload) { + for (auto it = uploads_.begin(); it != uploads_.end(); ++it) { + if (it->get() == upload) { + uploads_.erase(it); + return; + } + } + NOTREACHED(); + } + + private: + std::vector<std::unique_ptr<PendingUpload>> uploads_; +}; + +class ReportingDeliveryAgentTest : public ::testing::Test { + protected: + ReportingDeliveryAgentTest() + : agent_(&clock_, &cache_, &uploader_, &backoff_policy_) { + backoff_policy_.num_errors_to_ignore = 0; + backoff_policy_.initial_delay_ms = 60000; + backoff_policy_.multiply_factor = 2.0; + backoff_policy_.jitter_factor = 0.0; + backoff_policy_.maximum_backoff_ms = -1; + backoff_policy_.entry_lifetime_ms = 0; + backoff_policy_.always_use_initial_delay = false; + } + + base::TimeTicks tomorrow() { + return clock_.NowTicks() + base::TimeDelta::FromDays(1); + } + + const std::vector<std::unique_ptr<MockUploader::PendingUpload>>& + pending_uploads() const { + return uploader_.pending_uploads(); + } + + const GURL kUrl_ = GURL("https://origin/path"); + const url::Origin kOrigin_ = url::Origin(GURL("https://origin/")); + const GURL kEndpoint_ = GURL("https://endpoint/"); + const std::string kGroup_ = "group"; + const std::string kType_ = "type"; + + base::SimpleTestTickClock clock_; + ReportingCache cache_; + MockUploader uploader_; + BackoffEntry::Policy backoff_policy_; + ReportingDeliveryAgent agent_; +}; + +TEST_F(ReportingDeliveryAgentTest, SuccessfulUpload) { + static const int kAgeMillis = 12345; + + base::DictionaryValue body; + body.SetString("key", "value"); + + cache_.SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, + kGroup_, tomorrow()); + cache_.AddReport(kUrl_, kGroup_, kType_, body.CreateDeepCopy(), + clock_.NowTicks(), 0); + + clock_.Advance(base::TimeDelta::FromMilliseconds(kAgeMillis)); + + agent_.SendReports(); + + ASSERT_EQ(1u, pending_uploads().size()); + EXPECT_EQ(kEndpoint_, pending_uploads()[0]->url()); + { + auto value = pending_uploads()[0]->GetValue(); + + base::ListValue* list; + ASSERT_TRUE(value->GetAsList(&list)); + EXPECT_EQ(1u, list->GetSize()); + + base::DictionaryValue* report; + ASSERT_TRUE(list->GetDictionary(0, &report)); + EXPECT_EQ(4u, report->size()); + + ExpectDictIntegerValue(kAgeMillis, *report, "age"); + ExpectDictStringValue(kType_, *report, "type"); + ExpectDictStringValue(kUrl_.spec(), *report, "url"); + ExpectDictDictionaryValue(body, *report, "report"); + } + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + + // Successful upload should remove delivered reports. + std::vector<const ReportingReport*> reports; + cache_.GetReports(&reports); + EXPECT_TRUE(reports.empty()); + + // TODO(juliatuttle): Check that BackoffEntry was informed of success. +} + +TEST_F(ReportingDeliveryAgentTest, FailedUpload) { + cache_.SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, + kGroup_, tomorrow()); + cache_.AddReport(kUrl_, kGroup_, kType_, + base::MakeUnique<base::DictionaryValue>(), clock_.NowTicks(), + 0); + + agent_.SendReports(); + + ASSERT_EQ(1u, pending_uploads().size()); + pending_uploads()[0]->Complete(ReportingUploader::Outcome::FAILURE); + + // Failed upload should increment reports' attempts. + std::vector<const ReportingReport*> reports; + cache_.GetReports(&reports); + ASSERT_EQ(1u, reports.size()); + EXPECT_EQ(1, reports[0]->attempts); + + // Since endpoint is now failing, an upload won't be started despite a pending + // report. + ASSERT_TRUE(pending_uploads().empty()); + agent_.SendReports(); + EXPECT_TRUE(pending_uploads().empty()); +} + +TEST_F(ReportingDeliveryAgentTest, RemoveEndpointUpload) { + static const url::Origin kDifferentOrigin(GURL("https://origin2/")); + + cache_.SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, + kGroup_, tomorrow()); + cache_.SetClient(kDifferentOrigin, kEndpoint_, + ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow()); + ASSERT_TRUE(FindClientInCache(&cache_, kOrigin_, kEndpoint_)); + ASSERT_TRUE(FindClientInCache(&cache_, kDifferentOrigin, kEndpoint_)); + + cache_.AddReport(kUrl_, kGroup_, kType_, + base::MakeUnique<base::DictionaryValue>(), clock_.NowTicks(), + 0); + + agent_.SendReports(); + + ASSERT_EQ(1u, pending_uploads().size()); + pending_uploads()[0]->Complete(ReportingUploader::Outcome::REMOVE_ENDPOINT); + + // "Remove endpoint" upload should remove endpoint from *all* origins and + // increment reports' attempts. + std::vector<const ReportingReport*> reports; + cache_.GetReports(&reports); + ASSERT_EQ(1u, reports.size()); + EXPECT_EQ(1, reports[0]->attempts); + + EXPECT_FALSE(FindClientInCache(&cache_, kOrigin_, kEndpoint_)); + EXPECT_FALSE(FindClientInCache(&cache_, kDifferentOrigin, kEndpoint_)); + + // Since endpoint is now failing, an upload won't be started despite a pending + // report. + agent_.SendReports(); + EXPECT_TRUE(pending_uploads().empty()); +} + +TEST_F(ReportingDeliveryAgentTest, ConcurrentRemove) { + cache_.SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, + kGroup_, tomorrow()); + cache_.AddReport(kUrl_, kGroup_, kType_, + base::MakeUnique<base::DictionaryValue>(), clock_.NowTicks(), + 0); + + agent_.SendReports(); + ASSERT_EQ(1u, pending_uploads().size()); + + // Remove the report while the upload is running. + std::vector<const ReportingReport*> reports; + cache_.GetReports(&reports); + EXPECT_EQ(1u, reports.size()); + + const ReportingReport* report = reports[0]; + EXPECT_FALSE(cache_.IsReportDoomedForTesting(report)); + + // Report should appear removed, even though the cache has doomed it. + cache_.RemoveReports(reports); + cache_.GetReports(&reports); + EXPECT_TRUE(reports.empty()); + EXPECT_TRUE(cache_.IsReportDoomedForTesting(report)); + + // Completing upload shouldn't crash, and report should still be gone. + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + cache_.GetReports(&reports); + EXPECT_TRUE(reports.empty()); + // This is slightly sketchy since |report| has been freed, but it nonetheless + // should not be in the set of doomed reports. + EXPECT_FALSE(cache_.IsReportDoomedForTesting(report)); +} + +// Test that the agent will combine reports destined for the same endpoint, even +// if the reports are from different origins. +TEST_F(ReportingDeliveryAgentTest, + BatchReportsFromDifferentOriginsToSameEndpoint) { + static const GURL kDifferentUrl("https://origin2/path"); + static const url::Origin kDifferentOrigin(kDifferentUrl); + + cache_.SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, + kGroup_, tomorrow()); + cache_.SetClient(kDifferentOrigin, kEndpoint_, + ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow()); + + cache_.AddReport(kUrl_, kGroup_, kType_, + base::MakeUnique<base::DictionaryValue>(), clock_.NowTicks(), + 0); + cache_.AddReport(kDifferentUrl, kGroup_, kType_, + base::MakeUnique<base::DictionaryValue>(), clock_.NowTicks(), + 0); + + agent_.SendReports(); + ASSERT_EQ(1u, pending_uploads().size()); + + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + EXPECT_EQ(0u, pending_uploads().size()); +} + +// Test that the agent won't start a second upload to the same endpoint (even +// for a different origin) while one is pending, but will once it is no longer +// pending. +TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToEndpoint) { + static const GURL kDifferentUrl("https://origin2/path"); + static const url::Origin kDifferentOrigin(kDifferentUrl); + + cache_.SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, + kGroup_, tomorrow()); + cache_.SetClient(kDifferentOrigin, kEndpoint_, + ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow()); + + cache_.AddReport(kUrl_, kGroup_, kType_, + base::MakeUnique<base::DictionaryValue>(), clock_.NowTicks(), + 0); + + agent_.SendReports(); + EXPECT_EQ(1u, pending_uploads().size()); + + cache_.AddReport(kDifferentUrl, kGroup_, kType_, + base::MakeUnique<base::DictionaryValue>(), clock_.NowTicks(), + 0); + + agent_.SendReports(); + ASSERT_EQ(1u, pending_uploads().size()); + + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + EXPECT_EQ(0u, pending_uploads().size()); + + agent_.SendReports(); + ASSERT_EQ(1u, pending_uploads().size()); + + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + EXPECT_EQ(0u, pending_uploads().size()); +} + +// Test that the agent won't start a second upload for an (origin, group) while +// one is pending, even if a different endpoint is available, but will once the +// original delivery is complete and the (origin, group) is no longer pending. +TEST_F(ReportingDeliveryAgentTest, SerializeUploadsToGroup) { + static const GURL kDifferentEndpoint("https://endpoint2/"); + + cache_.SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, + kGroup_, tomorrow()); + cache_.SetClient(kOrigin_, kDifferentEndpoint, + ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow()); + + cache_.AddReport(kUrl_, kGroup_, kType_, + base::MakeUnique<base::DictionaryValue>(), clock_.NowTicks(), + 0); + + agent_.SendReports(); + EXPECT_EQ(1u, pending_uploads().size()); + + cache_.AddReport(kUrl_, kGroup_, kType_, + base::MakeUnique<base::DictionaryValue>(), clock_.NowTicks(), + 0); + + agent_.SendReports(); + EXPECT_EQ(1u, pending_uploads().size()); + + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + EXPECT_EQ(0u, pending_uploads().size()); + + agent_.SendReports(); + EXPECT_EQ(1u, pending_uploads().size()); +} + +// Tests that the agent will start parallel uploads to different groups within +// the same origin. +TEST_F(ReportingDeliveryAgentTest, ParallelizeUploadsAcrossGroups) { + static const GURL kDifferentEndpoint("https://endpoint2/"); + static const std::string kDifferentGroup("group2"); + + cache_.SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, + kGroup_, tomorrow()); + cache_.SetClient(kOrigin_, kDifferentEndpoint, + ReportingClient::Subdomains::EXCLUDE, kDifferentGroup, + tomorrow()); + + cache_.AddReport(kUrl_, kGroup_, kType_, + base::MakeUnique<base::DictionaryValue>(), clock_.NowTicks(), + 0); + cache_.AddReport(kUrl_, kDifferentGroup, kType_, + base::MakeUnique<base::DictionaryValue>(), clock_.NowTicks(), + 0); + + agent_.SendReports(); + EXPECT_EQ(2u, pending_uploads().size()); + + pending_uploads()[1]->Complete(ReportingUploader::Outcome::SUCCESS); + pending_uploads()[0]->Complete(ReportingUploader::Outcome::SUCCESS); + EXPECT_EQ(0u, pending_uploads().size()); +} + +} // namespace +} // namespace net
diff --git a/net/reporting/reporting_report.h b/net/reporting/reporting_report.h index 9739354..b1b3101 100644 --- a/net/reporting/reporting_report.h +++ b/net/reporting/reporting_report.h
@@ -29,23 +29,26 @@ int attempts); ~ReportingReport(); - // The URL of the document that triggered the report. + // The URL of the document that triggered the report. (Included in the + // delivered report.) GURL url; - // The endpoint group that should be used to deliver the report. + // The endpoint group that should be used to deliver the report. (Not included + // in the delivered report.) std::string group; - // The type of the report. + // The type of the report. (Included in the delivered report.) std::string type; - // The body of the report. + // The body of the report. (Included in the delivered report.) std::unique_ptr<const base::Value> body; - // When the report was queued. + // When the report was queued. (Included in the delivered report as an age + // relative to the time of the delivery attempt.) base::TimeTicks queued; // The number of delivery attempts made so far, not including an active - // attempt. + // attempt. (Not included in the delivered report.) int attempts = 0; private:
diff --git a/services/ui/gpu/BUILD.gn b/services/ui/gpu/BUILD.gn index c735398..c365a80 100644 --- a/services/ui/gpu/BUILD.gn +++ b/services/ui/gpu/BUILD.gn
@@ -20,6 +20,7 @@ deps = [ "//cc", + "//components/viz/frame_sinks", "//gpu/ipc:command_buffer", "//gpu/ipc/common", "//gpu/ipc/service",
diff --git a/services/ui/gpu/DEPS b/services/ui/gpu/DEPS index c0f4ae0..b6d0a2a 100644 --- a/services/ui/gpu/DEPS +++ b/services/ui/gpu/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/viz", "+gpu/command_buffer", "+gpu/config", "+gpu/ipc",
diff --git a/services/ui/gpu/gpu_main.cc b/services/ui/gpu/gpu_main.cc index cf2aad8b..03896b5 100644 --- a/services/ui/gpu/gpu_main.cc +++ b/services/ui/gpu/gpu_main.cc
@@ -8,6 +8,7 @@ #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/power_monitor/power_monitor_device_source.h" +#include "components/viz/frame_sinks/mojo_frame_sink_manager.h" #include "gpu/command_buffer/common/activity_flags.h" #include "gpu/ipc/common/gpu_memory_buffer_support.h" #include "gpu/ipc/gpu_in_process_thread_service.h" @@ -210,7 +211,7 @@ 1 /* client_id */), image_factory); - frame_sink_manager_ = base::MakeUnique<MojoFrameSinkManager>( + frame_sink_manager_ = base::MakeUnique<viz::MojoFrameSinkManager>( display_provider_.get(), std::move(request), std::move(client)); }
diff --git a/services/ui/gpu/gpu_main.h b/services/ui/gpu/gpu_main.h index 1e839880..005c6d5 100644 --- a/services/ui/gpu/gpu_main.h +++ b/services/ui/gpu/gpu_main.h
@@ -9,16 +9,20 @@ #include "base/threading/thread.h" #include "gpu/ipc/in_process_command_buffer.h" #include "gpu/ipc/service/gpu_init.h" +#include "mojo/public/cpp/bindings/binding.h" #include "services/ui/gpu/interfaces/gpu_main.mojom.h" #include "services/ui/gpu/interfaces/gpu_service.mojom.h" -#include "services/ui/surfaces/display_provider.h" -#include "services/ui/surfaces/mojo_frame_sink_manager.h" namespace gpu { class GpuMemoryBufferFactory; class ImageFactory; } +namespace viz { +class DisplayProvider; +class MojoFrameSinkManager; +} + namespace ui { class GpuService; @@ -85,8 +89,8 @@ pending_frame_sink_manager_client_info_; // Provides mojo interfaces for creating and managing FrameSinks. - std::unique_ptr<MojoFrameSinkManager> frame_sink_manager_; - std::unique_ptr<DisplayProvider> display_provider_; + std::unique_ptr<viz::MojoFrameSinkManager> frame_sink_manager_; + std::unique_ptr<viz::DisplayProvider> display_provider_; std::unique_ptr<gpu::GpuMemoryBufferFactory> gpu_memory_buffer_factory_;
diff --git a/services/ui/surfaces/BUILD.gn b/services/ui/surfaces/BUILD.gn index 2cf75e1..b63bba3 100644 --- a/services/ui/surfaces/BUILD.gn +++ b/services/ui/surfaces/BUILD.gn
@@ -8,9 +8,6 @@ sources = [ "display_output_surface.cc", "display_output_surface.h", - "display_provider.h", - "mojo_frame_sink_manager.cc", - "mojo_frame_sink_manager.h", "mus_display_provider.cc", "mus_display_provider.h", ] @@ -21,6 +18,7 @@ "//cc/ipc:interfaces", "//cc/surfaces", "//components/display_compositor", + "//components/viz/frame_sinks", "//gpu/command_buffer/client", "//gpu/command_buffer/client:gles2_interface", "//gpu/ipc:command_buffer",
diff --git a/services/ui/surfaces/DEPS b/services/ui/surfaces/DEPS index 257582d..1c1bbc83 100644 --- a/services/ui/surfaces/DEPS +++ b/services/ui/surfaces/DEPS
@@ -1,7 +1,7 @@ include_rules = [ "+cc", "+components/display_compositor", - "+components/gpu", + "+components/viz/frame_sinks", "+gpu", "+services/service_manager", "+mojo/common",
diff --git a/services/ui/surfaces/mus_display_provider.cc b/services/ui/surfaces/mus_display_provider.cc index 58e0a8b..30be7d1 100644 --- a/services/ui/surfaces/mus_display_provider.cc +++ b/services/ui/surfaces/mus_display_provider.cc
@@ -15,7 +15,6 @@ #include "cc/scheduler/begin_frame_source.h" #include "cc/surfaces/display.h" #include "cc/surfaces/display_scheduler.h" -#include "components/display_compositor/gpu_root_compositor_frame_sink.h" #include "gpu/command_buffer/client/shared_memory_limits.h" #include "gpu/command_buffer/service/image_factory.h" #include "services/ui/surfaces/display_output_surface.h"
diff --git a/services/ui/surfaces/mus_display_provider.h b/services/ui/surfaces/mus_display_provider.h index 2c111d8..f543883 100644 --- a/services/ui/surfaces/mus_display_provider.h +++ b/services/ui/surfaces/mus_display_provider.h
@@ -11,10 +11,10 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "cc/surfaces/frame_sink_id.h" +#include "components/viz/frame_sinks/display_provider.h" #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" #include "gpu/ipc/common/surface_handle.h" #include "gpu/ipc/in_process_command_buffer.h" -#include "services/ui/surfaces/display_provider.h" namespace gpu { class ImageFactory; @@ -23,7 +23,7 @@ namespace ui { // Mus implementation of DisplayProvider. This will be created in mus-gpu. -class MusDisplayProvider : public NON_EXPORTED_BASE(DisplayProvider) { +class MusDisplayProvider : public NON_EXPORTED_BASE(viz::DisplayProvider) { public: MusDisplayProvider( scoped_refptr<gpu::InProcessCommandBuffer::Service> gpu_service,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index ab62c37..6de71f0 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -11790,6 +11790,16 @@ "gtest_tests": [ { "args": [ + "--mus", + "--test-launcher-filter-file=../../testing/buildbot/filters/ash_mus_unittests.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "ash_mus_unittests" + }, + { + "args": [ "--override-use-software-gl-for-tests", "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.browser_tests.filter" ],
diff --git a/testing/buildbot/filters/ash_mus_unittests.filter b/testing/buildbot/filters/ash_mus_unittests.filter new file mode 100644 index 0000000..5ee0bfc --- /dev/null +++ b/testing/buildbot/filters/ash_mus_unittests.filter
@@ -0,0 +1,422 @@ +-AcceleratorControllerTest.DisallowedAtModalWindow +-AcceleratorControllerTest.GlobalAccelerators +-AcceleratorControllerTest.RotateScreen +-AshNativeCursorManagerTest.FractionalScale +-AshNativeCursorManagerTest.LockCursor +-AshNativeCursorManagerTest.SetCursor +-AshNativeCursorManagerTest.SetCursorSet +-AshNativeCursorManagerTest.SetDeviceScaleFactorAndRotation +-AshNativeCursorManagerTest.UIScaleShouldNotChangeCursor +-AshPopupAlignmentDelegateTest.DockedMode +-AshPopupAlignmentDelegateTest.Unified +-AutoclickTest.KeyModifiersReleased +-AutoclickTest.MouseMovement +-AutoclickTest.MovementThreshold +-AutoclickTest.MultipleKeyModifiers +-AutoclickTest.SingleKeyModifier +-AutoclickTest.SynthesizedMouseMovesIgnored +-AutoclickTest.ToggleEnabled +-AutoclickTest.UserInputCancelsAutoclick +-CursorWindowControllerTest.DSF +-CursorWindowControllerTest.MoveToDifferentDisplay +-CursorWindowControllerTest.VisibilityTest +-DIPTest.WorkArea +-DisplayConfigurationControllerTest.ErasesAnimatorOnAnimationEnded +-DisplayManagerFontTest.TextSubpixelPositioningWithDsf125External +-DisplayManagerFontTest.TextSubpixelPositioningWithDsf125Internal +-DisplayManagerFontTest.TextSubpixelPositioningWithDsf125InternalWithScaling +-DisplayManagerFontTest.TextSubpixelPositioningWithDsf200External +-DisplayManagerFontTest.TextSubpixelPositioningWithDsf200Internal +-DisplayManagerOrientationTest.LockToSpecificOrientation +-DisplayManagerOrientationTest.SaveRestoreUserRotationLock +-DisplayManagerOrientationTest.UserRotationLockReverse +-DisplayManagerTest.CheckInitializationOfRotationProperty +-DisplayManagerTest.DisplayAddRemoveAtTheSameTime +-DisplayManagerTest.EmulatorTest +-DisplayManagerTest.LayoutMorethanThreeDisplaysTest +-DisplayManagerTest.MirroredLayout +-DisplayManagerTest.NativeDisplaysChangedAfterPrimaryChange +-DisplayManagerTest.NoMirrorInThreeDisplays +-DisplayManagerTest.NoOverlappedDisplays +-DisplayManagerTest.NoOverlappedDisplaysAfterResolutionChange +-DisplayManagerTest.NoOverlappedDisplaysNotFitBetweenTwo +-DisplayManagerTest.NoOverlappedDisplaysWithDetachedDisplays +-DisplayManagerTest.NoRotateUnifiedDesktop +-DisplayManagerTest.NotifyPrimaryChange +-DisplayManagerTest.NotifyPrimaryChangeUndock +-DisplayManagerTest.OverscanInsetsTest +-DisplayManagerTest.ResolutionChangeInUnifiedMode +-DisplayManagerTest.Rotate +-DisplayManagerTest.RotateInSoftwareMirroring +-DisplayManagerTest.ScaleOnlyChange +-DisplayManagerTest.SingleDisplayToSoftwareMirroring +-DisplayManagerTest.SoftwareMirroring +-DisplayManagerTest.SoftwareMirroringWithCompositingCursor +-DisplayManagerTest.TestDeviceScaleOnlyChange +-DisplayManagerTest.TestNativeDisplaysChanged +-DisplayManagerTest.TestNativeDisplaysChangedNoInternal +-DisplayManagerTest.TouchCalibrationTest +-DisplayManagerTest.UIScale +-DisplayManagerTest.UnifiedDesktopBasic +-DisplayManagerTest.UnifiedDesktopEnabledWithExtended +-DisplayManagerTest.UnifiedDesktopWith2xDSF +-DisplayManagerTest.UpdateDisplayTest +-DisplayManagerTest.UpdateDisplayWithHostOrigin +-DisplayManagerTest.UpdateMouseCursorAfterRotateZoom +-DisplayManagerTest.UpdateThreeDisplaysWithDefaultLayout +-DisplayManagerTest.Use125DSFForUIScaling +-DisplayManagerTest.ZeroOverscanInsets +-DisplayUtilTest.RotatedDisplay +-DragDropControllerTest.CaptureLostCancelsDragDrop +-DragDropControllerTest.DragCancelAcrossDisplays +-DragDropControllerTest.DragCancelOnDisplayDisconnect +-DragDropControllerTest.DragDropInMultipleViewsMultipleWidgetsTest +-DragDropControllerTest.DragDropInMultipleViewsSingleWidgetTest +-DragDropControllerTest.DragDropInSingleViewTest +-DragDropControllerTest.DragDropWithZeroDragUpdates +-DragDropControllerTest.PressingEscapeCancelsDragDrop +-DragDropControllerTest.SyntheticEventsDuringDragDrop +-DragDropControllerTest.TouchDragDropCancelsOnLongTap +-DragDropControllerTest.TouchDragDropCompletesOnFling +-DragDropControllerTest.TouchDragDropInMultipleWindows +-DragDropControllerTest.TouchDragDropLongTapGestureIsForwarded +-DragDropControllerTest.ViewRemovedWhileInDragDropTest +-DragDropControllerTest.WindowDestroyedDuringDragDrop +-DragWindowResizerTest.CursorDeviceScaleFactor +-DragWindowResizerTest.DragWindowController +-DragWindowResizerTest.DragWindowControllerAcrossThreeDisplays +-DragWindowResizerTest.MoveWindowAcrossDisplays +-DragWindowResizerTest.WarpMousePointer +-DragWindowResizerTest.WindowDragWithMultiDisplays +-DragWindowResizerTest.WindowDragWithMultiDisplaysActiveRoot +-DragWindowResizerTest.WindowDragWithMultiDisplaysRightToLeft +-ExtendedDesktopTest.CaptureEventLocationHighDPI +-ExtendedDesktopTest.ConvertPoint +-ExtendedDesktopTest.GetRootWindowAt +-ExtendedDesktopTest.GetRootWindowMatching +-ExtendedDesktopTest.KeyEventsOnLockScreen +-ExtendedDesktopTest.TestCursor +-ExtendedMouseWarpControllerTest.IndicatorBoundsTestOnLeft +-ExtendedMouseWarpControllerTest.IndicatorBoundsTestOnRight +-ExtendedMouseWarpControllerTest.IndicatorBoundsTestOnTopBottom +-ExtendedMouseWarpControllerTest.IndicatorBoundsTestThreeDisplays +-ExtendedMouseWarpControllerTest.IndicatorBoundsTestThreeDisplaysWithLayout +-ExtendedMouseWarpControllerTest.IndicatorBoundsTestThreeDisplaysWithLayout2 +-ImmersiveFullscreenControllerTest.EndRevealViaGesture +-ImmersiveFullscreenControllerTest.MouseEventsVerticalDisplayLayout +-LaserPointerControllerTest.LaserPointerPrediction +-LaserPointerControllerTest.LaserPointerRenderer +-LockStateControllerTest.CancelLockToShutdown +-LockStateControllerTest.HonorPowerButtonInDockedMode +-LockStateControllerTest.IgnorePowerButtonIfScreenIsOff +-LockStateControllerTest.LegacyGuest +-LockStateControllerTest.LegacyLockAndShutDown +-LockStateControllerTest.LegacyNotLoggedIn +-LockStateControllerTest.Lock +-LockStateControllerTest.LockAndCancel +-LockStateControllerTest.LockAndCancelAndLockAgain +-LockStateControllerTest.LockAndUnlock +-LockStateControllerTest.LockButtonBasic +-LockStateControllerTest.LockButtonBasicGuest +-LockStateControllerTest.LockButtonBasicNotLoggedIn +-LockStateControllerTest.LockToShutdown +-LockStateControllerTest.LockWithoutButton +-LockStateControllerTest.PowerButtonPreemptsLockButton +-LockStateControllerTest.RequestAndCancelShutdownFromLockScreen +-LockStateControllerTest.RequestShutdownFromLockScreen +-LockStateControllerTest.RequestShutdownFromLoginScreen +-LockStateControllerTest.Screenshot +-LockStateControllerTest.ShutdownWhenNotLoggedIn +-LockStateControllerTest.ShutdownWithoutButton +-LockStateControllerTest.TestHiddenWallpaperLockCancel +-LockStateControllerTest.TestHiddenWallpaperLockUnlock +-LtrRtl/PanelWindowResizerTextDirectionTest.DragReordersPanelsHorizontal/0 +-LtrRtl/PanelWindowResizerTextDirectionTest.DragReordersPanelsHorizontal/1 +-MagnificationControllerTest.CenterTextCaretInViewport +-MagnificationControllerTest.CenterTextCaretNotInsideViewport +-MagnificationControllerTest.EnableAndDisable +-MagnificationControllerTest.EnableMagnifierInUnifiedDesktop +-MagnificationControllerTest.FollowFocusChanged +-MagnificationControllerTest.FollowTextInputFieldFocus +-MagnificationControllerTest.FollowTextInputFieldKeyPress +-MagnificationControllerTest.MagnifyAndUnmagnify +-MagnificationControllerTest.MoveWindow +-MagnificationControllerTest.PanWindow2xLeftToRight +-MagnificationControllerTest.PanWindow2xRightToLeft +-MagnificationControllerTest.PanWindowToLeft +-MagnificationControllerTest.PanWindowToRight +-MagnificationControllerTest.PointOfInterest +-MagnifierKeyScrollerTest.Basic +-MaximizeModeControllerTest.CloseLidWhileInMaximizeMode +-MaximizeModeControllerTest.DisplayDisconnectionDuringOverview +-MaximizeModeControllerTest.ForceClamshellModeTest +-MaximizeModeControllerTest.ForceTouchViewModeTest +-MaximizeModeControllerTest.HingeAligned +-MaximizeModeControllerTest.HingeAnglesWithLidClosed +-MaximizeModeControllerTest.InitializedWhileTabletModeSwitchOn +-MaximizeModeControllerTest.LaptopTest +-MaximizeModeControllerTest.MaximizeModeAfterExitingDockedMode +-MaximizeModeControllerTest.MaximizeModeTest +-MaximizeModeControllerTest.NoMaximizeModeWithDisabledInternalDisplay +-MaximizeModeControllerTest.StableHingeAnglesWithLidOpened +-MaximizeModeControllerTest.TabletModeTransition +-MaximizeModeControllerTest.TabletModeTransitionNoKeyboardAccelerometer +-MaximizeModeControllerTest.UnstableHingeAnglesWhenLidRecentlyOpened +-MaximizeModeControllerTest.UnstableHingeAnglesWithLidOpened +-MaximizeModeControllerTest.VerifyTouchViewEnabledDisabledCounts +-MaximizeModeControllerTest.VerticalHingeTest +-MaximizeModeControllerTest.VerticalHingeUnstableAnglesTest +-MaximizeModeControllerTest.WasLidOpenedRecentlyOverTime +-MaximizeModeWindowManagerTest.TryToDesktopSizeDragUnmaximizable +-MirrorOnBootTest.MirrorOnBoot +-MirrorWindowControllerTest.MirrorCursorBasic +-MirrorWindowControllerTest.MirrorCursorLocations +-MirrorWindowControllerTest.MirrorCursorMoveOnEnter +-MirrorWindowControllerTest.MirrorCursorRotate +-MouseCursorEventFilterTest.CursorDeviceScaleFactor +-MouseCursorEventFilterTest.SetMouseWarpModeFlag +-MouseCursorEventFilterTest.WarpMouse +-MouseCursorEventFilterTest.WarpMouseDifferentScaleDisplaysInNative +-MouseCursorEventFilterTest.WarpMouseDifferentSizeDisplays +-MultiWindowResizeControllerTest.ClickOutside +-NormalPanelPopup/PanelWindowResizerTransientTest.PanelWithTransientChild/0 +-NormalPanelPopup/PanelWindowResizerTransientTest.PanelWithTransientChild/1 +-NormalPanelPopup/PanelWindowResizerTransientTest.PanelWithTransientChild/2 +-OverviewButtonTrayTest.HideAnimationAlwaysCompletes +-PanelLayoutManagerTest.DockUndockTest +-PanelLayoutManagerTest.UndockTest +-PanelWindowResizerTest.AttachToSecondDisplay +-PanelWindowResizerTest.AttachToSecondFullscreenDisplay +-PanelWindowResizerTest.DetachAcrossDisplays +-PanelWindowResizerTest.DetachThenAttachToSecondDisplay +-PanelWindowResizerTest.DetachThenDragAcrossDisplays +-PanelWindowResizerTest.DetachThenHideShelf +-PanelWindowResizerTest.DragMovesToPanelLayer +-PanelWindowResizerTest.DragReordersPanelsVertical +-PanelWindowResizerTest.PanelDetachReattachBottom +-PanelWindowResizerTest.PanelDetachReattachLeft +-PanelWindowResizerTest.PanelDetachReattachMultipleDisplays +-PanelWindowResizerTest.PanelDetachReattachRight +-PanelWindowResizerTest.RevertDragRestoresAttachment +-PartialMagnificationControllerTest.ActivatesOnlyForPointer +-PartialMagnificationControllerTest.ActiveOnPointerDown +-PartialMagnificationControllerTest.DisablingDisablesActive +-PartialMagnificationControllerTest.InactiveByDefault +-PartialMagnificationControllerTest.MagnifierFollowsPointer +-PartialMagnificationControllerTest.MultipleDisplays +-PartialScreenshotControllerTest.BasicMouse +-PartialScreenshotControllerTest.BasicTouch +-PartialScreenshotControllerTest.JustClick +-PartialScreenshotControllerTest.LargeCursor +-PartialScreenshotControllerTest.MouseWarpTest +-PartialScreenshotControllerTest.PointerEventsWorkWhenPointerOnlyActive +-PartialScreenshotControllerTest.StartSessionWhileMousePressed +-PartialScreenshotControllerTest.TouchMousePointerHoverIgnoredWithPointerEvents +-PartialScreenshotControllerTest.TwoFingerTouch +-PartialScreenshotControllerTest.VisibilityTest +-ResizeShadowAndCursorTest.MaximizeRestore +-ResizeShadowAndCursorTest.MouseDrag +-ResizeShadowAndCursorTest.MouseHover +-ResizeShadowAndCursorTest.Touch +-ResolutionNotificationControllerTest.AcceptButton +-ResolutionNotificationControllerTest.Basic +-ResolutionNotificationControllerTest.ClickMeansAccept +-ResolutionNotificationControllerTest.Close +-ResolutionNotificationControllerTest.DisplayDisconnected +-ResolutionNotificationControllerTest.Fallback +-ResolutionNotificationControllerTest.MultipleResolutionChange +-ResolutionNotificationControllerTest.Timeout +-RootWindowControllerTest.MoveWindows_Basic +-RootWindowControllerTest.MoveWindows_LockWindowsInUnified +-RootWindowTransformersTest.ConvertHostToRootCoords +-RootWindowTransformersTest.LetterBoxPillarBox +-RootWindowTransformersTest.RotateAndMagnify +-RootWindowTransformersTest.ScaleAndMagnify +-RootWindowTransformersTest.TouchScaleAndMagnify +-ScreenLayoutObserverTest.AddingRemovingDisplayExtendedModeMessage +-ScreenLayoutObserverTest.DisplayConfigurationChangedTwice +-ScreenLayoutObserverTest.DisplayNotifications +-ScreenLayoutObserverTest.DockedModeWithExternalPrimaryDisplayMessage +-ScreenLayoutObserverTest.EnteringExitingUnifiedModeMessage +-ScreenLayoutObserverTest.ExitMirrorModeBecauseOfDockedModeMessage +-ScreenLayoutObserverTest.ExitMirrorModeBecauseOfThirdDisplayMessage +-ScreenLayoutObserverTest.ExitMirrorModeNoInternalDisplayBecauseOfDisplayRemovedMessage +-ScreenLayoutObserverTest.OverscanDisplay +-ScreenLayoutObserverTest.UpdateAfterSuppressDisplayNotification +-ScreenPositionControllerTest.ConvertHostPointToScreen +-ScreenPositionControllerTest.ConvertHostPointToScreenHiDPI +-ScreenPositionControllerTest.ConvertHostPointToScreenRotate +-ScreenPositionControllerTest.ConvertHostPointToScreenUIScale +-ScreenPositionControllerTest.ConvertToScreenWhileRemovingSecondaryDisplay +-ScreenRotationAnimatorTest.RotatesDuringRotation +-ScreenRotationAnimatorTest.RotatesToDifferentRotation +-ScreenRotationAnimatorTest.ShouldCompleteAnimations +-ScreenRotationAnimatorTest.ShouldNotifyObserver +-ScreenRotationAnimatorTest.ShouldNotifyObserverOnce +-ScreenRotationAnimatorTest.ShouldNotRotateTheSameRotation +-ScreenshotControllerTest.BreaksCapture +-ScreenshotControllerTest.MultipleDisplays +-ScreenUtilTest.ShelfDisplayBoundsInUnifiedDesktop +-ShelfLayoutManagerTest.AutoHideShelfOnScreenBoundary +-ShelfLayoutManagerTest.ShelfLayoutInUnifiedDesktop +-ShelfWindowWatcherTest.DragWindow +-ShellTest2.DontCrashWhenWindowDeleted +-ShellTest.TestPreTargetHandlerOrder +-StickyKeysOverlayTest.OverlayNotDestroyedAfterDisplayRemoved +-SystemGestureEventFilterTest.ControlWindowGetsMultiFingerGestureEvents +-SystemGestureEventFilterTest.DragLeftNearEdgeSnaps +-SystemGestureEventFilterTest.DragRightNearEdgeSnaps +-SystemGestureEventFilterTest.ThreeFingerGestureStopsDrag +-SystemGestureEventFilterTest.TwoFingerAttemptResizeLeftAndRightEdgesSimultaneously +-SystemGestureEventFilterTest.TwoFingerDrag +-SystemGestureEventFilterTest.TwoFingerDragDelayed +-SystemGestureEventFilterTest.WindowsWithMaxSizeDontSnap +-SystemTrayTest.PersistentBubble +-ToastManagerTest.PositionWithUnifiedDesktop +-TooltipControllerTest.HideTooltipWhenCursorHidden +-ToplevelWindowEventHandlerTest.Bottom +-ToplevelWindowEventHandlerTest.BottomLeft +-ToplevelWindowEventHandlerTest.BottomLeftPastMinimum +-ToplevelWindowEventHandlerTest.BottomLeftWorkArea +-ToplevelWindowEventHandlerTest.BottomRight +-ToplevelWindowEventHandlerTest.BottomRightPastMinimum +-ToplevelWindowEventHandlerTest.BottomRightWorkArea +-ToplevelWindowEventHandlerTest.BottomWorkArea +-ToplevelWindowEventHandlerTest.Caption +-ToplevelWindowEventHandlerTest.CaptureLossAfterMouseRelease +-ToplevelWindowEventHandlerTest.DontDragToNegativeY +-ToplevelWindowEventHandlerTest.DontGotWiderThanScreen +-ToplevelWindowEventHandlerTest.DragSnappedWindowToExternalDisplay +-ToplevelWindowEventHandlerTest.EscapeReverts +-ToplevelWindowEventHandlerTest.GestureAttemptMinimizeUnminimizeableWindow +-ToplevelWindowEventHandlerTest.GestureDrag +-ToplevelWindowEventHandlerTest.GestureDragCaptureLoss +-ToplevelWindowEventHandlerTest.GestureDragForUnresizableWindow +-ToplevelWindowEventHandlerTest.GestureDragMultipleWindows +-ToplevelWindowEventHandlerTest.GestureDragToRestore +-ToplevelWindowEventHandlerTest.GrowBox +-ToplevelWindowEventHandlerTest.Left +-ToplevelWindowEventHandlerTest.LeftPastMinimum +-ToplevelWindowEventHandlerTest.MinimizeMaximizeCompletes +-ToplevelWindowEventHandlerTest.Right +-ToplevelWindowEventHandlerTest.RightPastMinimum +-ToplevelWindowEventHandlerTest.RunMoveLoopFailsDuringInProgressDrag +-ToplevelWindowEventHandlerTest.Top +-ToplevelWindowEventHandlerTest.TopLeft +-ToplevelWindowEventHandlerTest.TopLeftPastMinimum +-ToplevelWindowEventHandlerTest.TopRight +-ToplevelWindowEventHandlerTest.TopRightPastMinimum +-ToplevelWindowEventHandlerTest.WindowPositionAutoManagement +-TouchHudDebugTest.DualDisplays +-TouchHudDebugTest.Headless +-TouchHudDebugTest.MirrorDisplays +-TouchHudDebugTest.RemovePrimaryDisplay +-TouchHudDebugTest.RemoveSecondaryDisplay +-TouchHudDebugTest.SingleDisplay +-TouchHudDebugTest.SwapPrimaryDisplay +-TouchHudDebugTest.SwapPrimaryThenMirrorDisplays +-TouchHudProjectionTest.DisableWhileTouching +-TouchHudProjectionTest.DoubleTouch +-TouchHudProjectionTest.TouchMoveCancel +-TouchHudProjectionTest.TouchMoveRelease +-TrayRotationLockTest.CreateDefaultView +-TrayRotationLockTest.CreateDefaultViewDuringMaximizeMode +-TrayRotationLockTest.CreateTrayViewDuringMaximizeModeAndRotationLock +-TrayRotationLockTest.DefaultViewVisibilityChangesDuringMaximizeMode +-TrayRotationLockTest.InternalDisplayNotAvailableAtCreation +-TrayRotationLockTest.PerformActionOnDefaultView +-TrayRotationLockTest.TrayViewVisibilityChangesDuringMaximizeMode +-UnifiedMouseWarpControllerTest.BoundaryTest +-UnifiedMouseWarpControllerTest.WarpMouse +-VirtualKeyboardRootWindowControllerTest.FollowInputFocus +-VirtualKeyboardRootWindowControllerTest.VirtualKeyboardOnTouchableDisplayOnly +-WallpaperControllerTest.GetMaxDisplaySize +-WebNotificationTrayTest.PopupShownOnBothDisplays +-WindowCycleControllerTest.MultiDisplayPositioning +-WindowManagerTest.ActivateOnTouch +-WindowManagerTest.MouseEventCursors +-WindowManagerTest.TestCursorClientObserver +-WindowManagerTest.UpdateCursorVisibility +-WindowManagerTest.UpdateCursorVisibilityAccelerator +-WindowManagerTest.UpdateCursorVisibilityOnKeyEvent +-WindowScreenshotControllerTest.KeyboardOperation +-WindowScreenshotControllerTest.MouseOperation +-WindowScreenshotControllerTest.MultiDisplays +-WindowSelectorTest.Basic +-WindowSelectorTest.DisplayOrientationChanged +-WindowSelectorTest.MultiMonitorReversedOrder +-WindowSelectorTest.OverviewScreenRotation +-WindowSelectorTest.OverviewWhileDragging +-WindowTreeHostManagerStartupTest.Startup +-WindowTreeHostManagerTest.BoundsUpdated +-WindowTreeHostManagerTest.ConvertHostToRootCoords +-WindowTreeHostManagerTest.DockToSingle +-WindowTreeHostManagerTest.FindNearestDisplay +-WindowTreeHostManagerTest.GetRootWindowForDisplayIdDuringDisplayDisconnection +-WindowTreeHostManagerTest.MirrorToDockedWithFullscreen +-WindowTreeHostManagerTest.OverscanInsets +-WindowTreeHostManagerTest.ReplacePrimary +-WindowTreeHostManagerTest.ReplaceSwappedPrimary +-WindowTreeHostManagerTest.Rotate +-WindowTreeHostManagerTest.ScaleRootWindow +-WindowTreeHostManagerTest.SecondaryDisplayLayout +-WindowTreeHostManagerTest.SetPrimaryWithFourDisplays +-WindowTreeHostManagerTest.SetPrimaryWithThreeDisplays +-WindowTreeHostManagerTest.SwapPrimaryById +-WindowTreeHostManagerTest.UpdateMouseLocationAfterDisplayChange +-WindowTreeHostManagerTest.UpdateMouseLocationAfterDisplayChange_2ndOnLeft +-WindowTreeHostManagerTest.UpdateMouseLocationAfterDisplayChange_PrimaryDisconnected +-WindowTreeHostManagerTest.UpdateMouseLocationAfterDisplayChange_SwapPrimary +-WorkspaceControllerTest.DragWindowKeepsShelfAutohidden +-WorkspaceControllerTest.DragWindowOverlapShelf +-WorkspaceControllerTest.TestRestoreToUserModifiedBounds +-WorkspaceEventHandlerTest.DeleteWhenDragging +-WorkspaceEventHandlerTest.DeleteWhileInRunLoop +-WorkspaceEventHandlerTest.DoubleClickCaptionTogglesMaximize +-WorkspaceEventHandlerTest.DoubleClickSingleAxisDoesntResizeHorizontalEdgeIfConstrained +-WorkspaceEventHandlerTest.DoubleClickSingleAxisDoesntResizeVerticalEdgeIfConstrained +-WorkspaceEventHandlerTest.DoubleClickSingleAxisResizeEdge +-WorkspaceEventHandlerTest.DoubleClickSingleAxisWhenSideSnapped +-WorkspaceLayoutManagerKeyboardTest.ChangeWorkAreaInNonStickyMode +-WorkspaceLayoutManagerKeyboardTest.IgnoreWorkAreaChangeinNonStickyMode +-WorkspaceWindowResizerTest.CancelSnapPhantom +-WorkspaceWindowResizerTest.CheckUserWindowManagedFlags +-WorkspaceWindowResizerTest.CtrlDragResizeToExactPosition +-WorkspaceWindowResizerTest.DontDragOffBottom +-WorkspaceWindowResizerTest.DontDragOffBottomWithMultiDisplay +-WorkspaceWindowResizerTest.DontDragOffTop +-WorkspaceWindowResizerTest.DragSnapped +-WorkspaceWindowResizerTest.DragWindowOutsideRightToSecondaryDisplay +-WorkspaceWindowResizerTest.Edge +-WorkspaceWindowResizerTest.MagneticallyAttach +-WorkspaceWindowResizerTest.MagneticallyResize_BOTTOM +-WorkspaceWindowResizerTest.MagneticallyResize_BOTTOMLEFT +-WorkspaceWindowResizerTest.MagneticallyResize_BOTTOMRIGHT +-WorkspaceWindowResizerTest.MagneticallyResize_LEFT +-WorkspaceWindowResizerTest.MagneticallyResize_RIGHT +-WorkspaceWindowResizerTest.MagneticallyResize_TOP +-WorkspaceWindowResizerTest.MagneticallyResize_TOPLEFT +-WorkspaceWindowResizerTest.MagneticallyResize_TOPRIGHT +-WorkspaceWindowResizerTest.MouseMoveWithTouchDrag +-WorkspaceWindowResizerTest.NonResizableWindows +-WorkspaceWindowResizerTest.PhantomSnapMaxSize +-WorkspaceWindowResizerTest.ResizeBottomOutsideWorkArea +-WorkspaceWindowResizerTest.ResizeSnapped +-WorkspaceWindowResizerTest.ResizeWindowOutsideBottomWorkArea +-WorkspaceWindowResizerTest.ResizeWindowOutsideLeftWorkArea +-WorkspaceWindowResizerTest.ResizeWindowOutsideRightWorkArea +-WorkspaceWindowResizerTest.RestoreClearedOnResize +-WorkspaceWindowResizerTest.RestoreToPreMaximizeCoordinates +-WorkspaceWindowResizerTest.RevertResizeOperation +-WorkspaceWindowResizerTest.SnapToEdge +-WorkspaceWindowResizerTest.SnapToWorkArea_BOTTOMLEFT +-WorkspaceWindowResizerTest.SnapToWorkArea_BOTTOMRIGHT +-WorkspaceWindowResizerTest.SnapToWorkArea_TOPLEFT +-WorkspaceWindowResizerTest.SnapToWorkArea_TOPRIGHT +-WorkspaceWindowResizerTest.StickToBothEdgeAndWindow +-WorkspaceWindowResizerTest.TestMaxSizeEnforced +-WorkspaceWindowResizerTest.TestPartialMaxSizeEnforced +-WorkspaceWindowResizerTest.TouchResizeToEdge_BOTTOM +-WorkspaceWindowResizerTest.TouchResizeToEdge_LEFT +-WorkspaceWindowResizerTest.TouchResizeToEdge_RIGHT +-WorkspaceWindowResizerTest.TouchResizeToEdge_TOP
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 4ad06da..4593ff2 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -148,6 +148,13 @@ "label": "//ash:ash_unittests", "type": "windowed_test_launcher", }, + "ash_mus_unittests": { + "label": "//ash:ash_unittests", + "type": "windowed_test_launcher", + "args": [ + "--mus", + ], + }, "audio_unittests": { "label": "//media:audio_unittests", "type": "raw",
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index 7e24bee..fed22d1 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -517,6 +517,18 @@ Bug(none) fast/box-sizing/box-sizing.html [ Failure ] Bug(none) fast/canvas/canvas-composite-video.html [ Failure ] Bug(none) fast/canvas/canvas-css-clip-path.html [ Failure ] +Bug(none) fast/canvas/OffscreenCanvas-2d-drawImage-in-worker.html [ Failure ] +Bug(none) fast/canvas/OffscreenCanvas-2d-drawImage.html [ Failure ] +Bug(none) fast/canvas/OffscreenCanvas-2d-gradients-in-worker.html [ Failure ] +Bug(none) fast/canvas/OffscreenCanvas-2d-imageSmoothing-in-worker.html [ Failure ] +Bug(none) fast/canvas/OffscreenCanvas-2d-pattern-in-worker.html [ Failure ] +Bug(none) fast/canvas/OffscreenCanvas-2d-pattern.html [ Failure ] +Bug(none) fast/canvas/OffscreenCanvas-clearRect-in-worker.html [ Failure ] +Bug(none) fast/canvas/OffscreenCanvas-fillRect-in-worker.html [ Failure ] +Bug(none) fast/canvas/OffscreenCanvas-filter-in-worker.html [ Failure ] +Bug(none) fast/canvas/OffscreenCanvas-paths-in-worker.html [ Failure ] +Bug(none) fast/canvas/OffscreenCanvas-strokeRect-in-worker.html [ Failure ] +Bug(none) fast/canvas/OffscreenCanvas-transform-shadow-in-worker.html [ Failure ] Bug(none) fast/canvas/webgl/pixelated.html [ Failure ] Bug(none) fast/clip/nestedTransparencyClip.html [ Failure ] Bug(none) fast/clip/overflow-border-radius-clip.html [ Failure ] @@ -1346,15 +1358,10 @@ crbug.com/702353 transitions/transition-end-event-destroy-iframe.html [ Timeout ] crbug.com/702353 virtual/threaded/transitions/transition-end-event-destroy-iframe.html [ Timeout ] crbug.com/702353 virtual/threaded/transitions/extra-transition.html [ Timeout ] -Bug(none) virtual/threaded/animations/composited-animations-rotate-zero-degrees.html [ Crash ] crbug.com/702365 virtual/threaded/animations/composited-filter-webkit-filter.html [ Failure ] crbug.com/702370 virtual/threaded/animations/compositor-independent-transform-cancel.html [ Failure ] -Bug(none) virtual/threaded/animations/element-animate-positive-delay.html [ Crash ] -Bug(none) virtual/threaded/animations/img-element-transform.html [ Crash ] -Bug(none) virtual/threaded/animations/inline-block-transform.html [ Crash ] crbug.com/702379 virtual/threaded/animations/skew-notsequential-compositor.html [ Failure ] crbug.com/692310 virtual/threaded/animations/sample-on-last-keyframe.html [ Timeout ] -Bug(none) virtual/threaded/animations/transitions-retarget.html [ Crash ] crbug.com/692310 virtual/threaded/animations/zoom-responsive-transform-animation.html [ Timeout ] crbug.com/692310 virtual/threaded/transitions/opacity-transition-zindex.html [ Timeout ] crbug.com/692310 virtual/threaded/transitions/unprefixed-transform.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/resources/test-helpers.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/resources/test-helpers.js index d3b8109..6bc3a868 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/resources/test-helpers.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/resources/test-helpers.js
@@ -236,6 +236,30 @@ }), description); } +// Helper for testing with Request objects. Compares simple +// attributes defined on the interfaces, as well as the headers. +function assert_request_equals(actual, expected, description) { + assert_class_string(actual, "Request", description); + ["url"].forEach(function(attribute) { + assert_equals(actual[attribute], expected[attribute], + description + " Attributes differ: " + attribute + "."); + }); + assert_header_equals(actual.headers, expected.headers, description); +} + +// Asserts that two arrays |actual| and |expected| contain the same +// set of Requests as determined by assert_request_equals(). The +// corresponding elements must occupy corresponding indices in their +// respective arrays. +function assert_request_array_equals(actual, expected, description) { + assert_true(Array.isArray(actual), description); + assert_equals(actual.length, expected.length, description); + actual.forEach(function(value, index) { + assert_request_equals(value, expected[index], + description + " : object[" + index + "]"); + }); +} + // Deletes all caches, returning a promise indicating success. function delete_all_caches() { return self.caches.keys()
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-add.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-add.js index 237ba47..c03faeb 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-add.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-add.js
@@ -84,7 +84,7 @@ }, 'Cache.add with request with null body (not consumed)'); cache_test(function(cache, test) { - return assert_promise_rejects( + return promise_rejects( test, new TypeError(), cache.add('../resources/fetch-status.py?status=206'), @@ -98,6 +98,7 @@ return new Request(url); }); return promise_rejects( + test, new TypeError(), cache.addAll(requests), 'Cache.addAll should reject with TypeError if any request fails'); @@ -116,7 +117,7 @@ return promise_rejects( test, new TypeError(), - cache.add('../resources/fetch-status.php?status=500'), + cache.add('../resources/fetch-status.py?status=500'), 'Cache.add should reject if response is !ok'); }, 'Cache.add with request that results in a status of 500');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-delete.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-delete.js index bf7841a..3cf9aeb 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-delete.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-delete.js
@@ -71,10 +71,40 @@ .then(function(result) { assert_response_equals(result, response, 'Cache.delete should leave non-matching response in the cache.'); + return cache.delete(new Request(test_url, {method: 'HEAD'}), + {ignoreMethod: true}); + }) + .then(function(result) { + assert_true(result, + 'Cache.delete should match a non-GET request ' + + ' if ignoreMethod is true.'); }); }, 'Cache.delete called with a HEAD request'); cache_test(function(cache) { + var vary_request = new Request('http://example.com/c', + {headers: {'Cookies': 'is-for-cookie'}}); + var vary_response = new Response('', {headers: {'Vary': 'Cookies'}}); + var mismatched_vary_request = new Request('http://example.com/c'); + + return cache.put(vary_request.clone(), vary_response.clone()) + .then(function() { + return cache.delete(mismatched_vary_request.clone()); + }) + .then(function(result) { + assert_false(result, + 'Cache.delete should not delete if vary does not ' + + 'match unless ignoreVary is true'); + return cache.delete(mismatched_vary_request.clone(), + {ignoreVary: true}); + }) + .then(function(result) { + assert_true(result, + 'Cache.delete should ignore vary if ignoreVary is true'); + }); + }, 'Cache.delete supports ignoreVary'); + +cache_test(function(cache) { return cache.delete(test_url) .then(function(result) { assert_false(result, @@ -83,33 +113,52 @@ }); }, 'Cache.delete with a non-existent entry'); -var cache_entries = { - a: { - request: new Request('http://example.com/abc'), - response: new Response('') +prepopulated_cache_test(simple_entries, function(cache, entries) { + return cache.matchAll(entries.a_with_query.request, + { ignoreSearch: true }) + .then(function(result) { + assert_response_array_equals( + result, + [ + entries.a.response, + entries.a_with_query.response + ]); + return cache.delete(entries.a_with_query.request, + { ignoreSearch: true }); + }) + .then(function(result) { + return cache.matchAll(entries.a_with_query.request, + { ignoreSearch: true }); + }) + .then(function(result) { + assert_response_array_equals(result, []); + }); }, + 'Cache.delete with ignoreSearch option (request with search parameters)'); - b: { - request: new Request('http://example.com/b'), - response: new Response('') +prepopulated_cache_test(simple_entries, function(cache, entries) { + return cache.matchAll(entries.a_with_query.request, + { ignoreSearch: true }) + .then(function(result) { + assert_response_array_equals( + result, + [ + entries.a.response, + entries.a_with_query.response + ]); + // cache.delete()'s behavior should be the same if ignoreSearch is + // not provided or if ignoreSearch is false. + return cache.delete(entries.a_with_query.request, + { ignoreSearch: false }); + }) + .then(function(result) { + return cache.matchAll(entries.a_with_query.request, + { ignoreSearch: true }); + }) + .then(function(result) { + assert_response_array_equals(result, [ entries.a.response ]); + }); }, - - a_with_query: { - request: new Request('http://example.com/abc?q=r'), - response: new Response('') - } -}; - -function prepopulated_cache_test(test_function, description) { - cache_test(function(cache) { - return Promise.all(Object.keys(cache_entries).map(function(k) { - return cache.put(cache_entries[k].request.clone(), - cache_entries[k].response.clone()); - })) - .then(function() { - return test_function(cache); - }); - }, description); -} + 'Cache.delete with ignoreSearch option (when it is specified as false)'); done();
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-keys.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-keys.js similarity index 100% rename from third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-keys.js rename to third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-keys.js
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-match.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-match.js index 32c9ec9..3d00f0f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-match.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-match.js
@@ -28,6 +28,23 @@ }, 'Cache.match with Request'); prepopulated_cache_test(simple_entries, function(cache, entries) { + var alt_response = new Response('', {status: 201}); + + return self.caches.open('second_matching_cache') + .then(function(cache) { + return cache.put(entries.a.request, alt_response.clone()); + }) + .then(function() { + return cache.match(entries.a.request); + }) + .then(function(result) { + assert_response_equals( + result, entries.a.response, + 'Cache.match should match the first cache.'); + }); + }, 'Cache.match with multiple cache hits'); + +prepopulated_cache_test(simple_entries, function(cache, entries) { return cache.match(new Request(entries.a.request.url)) .then(function(result) { assert_response_equals(result, entries.a.response, @@ -76,6 +93,56 @@ }, 'Cache.match with ignoreSearch option (request with search parameter)'); +cache_test(function(cache) { + var request = new Request('http://example.com/'); + var head_request = new Request('http://example.com/', {method: 'HEAD'}); + var response = new Response('foo'); + return cache.put(request.clone(), response.clone()) + .then(function() { + return cache.match(head_request.clone()); + }) + .then(function(result) { + assert_equals( + result, undefined, + 'Cache.match should resolve as undefined with a ' + + 'mismatched method.'); + return cache.match(head_request.clone(), + {ignoreMethod: true}); + }) + .then(function(result) { + assert_response_equals( + result, response, + 'Cache.match with ignoreMethod should ignore the ' + + 'method of request.'); + }); + }, 'Cache.match supports ignoreMethod'); + +cache_test(function(cache) { + var vary_request = new Request('http://example.com/c', + {headers: {'Cookies': 'is-for-cookie'}}); + var vary_response = new Response('', {headers: {'Vary': 'Cookies'}}); + var mismatched_vary_request = new Request('http://example.com/c'); + + return cache.put(vary_request.clone(), vary_response.clone()) + .then(function() { + return cache.match(mismatched_vary_request.clone()); + }) + .then(function(result) { + assert_equals( + result, undefined, + 'Cache.match should resolve as undefined with a ' + + 'mismatched vary.'); + return cache.match(mismatched_vary_request.clone(), + {ignoreVary: true}); + }) + .then(function(result) { + assert_response_equals( + result, vary_response, + 'Cache.match with ignoreVary should ignore the ' + + 'vary of request.'); + }); + }, 'Cache.match supports ignoreVary'); + prepopulated_cache_test(simple_entries, function(cache, entries) { return cache.match(entries.cat.request.url + '#mouse') .then(function(result) { @@ -166,6 +233,36 @@ }); }, 'Cache.match invoked multiple times for the same Request/Response'); +cache_test(function(cache) { + var request_url = new URL('../resources/simple.txt', location.href).href; + return fetch(request_url) + .then(function(fetch_result) { + return cache.put(new Request(request_url), fetch_result); + }) + .then(function() { + return cache.match(request_url); + }) + .then(function(result) { + return result.blob(); + }) + .then(function(blob) { + var sliced = blob.slice(2,8); + + return new Promise(function (resolve, reject) { + var reader = new FileReader(); + reader.onloadend = function(event) { + resolve(event.target.result); + }; + reader.readAsText(sliced); + }); + }) + .then(function(text) { + assert_equals(text, 'simple', + 'A Response blob returned by Cache.match should be ' + + 'sliceable.' ); + }); + }, 'Cache.match blob should be sliceable'); + prepopulated_cache_test(simple_entries, function(cache, entries) { var request = new Request(entries.a.request.clone(), {method: 'POST'}); return cache.match(request) @@ -218,7 +315,7 @@ }) .then(function(text) { assert_equals(text, data.toString(), 'cloned body text can be read correctly'); - }) + }); }, 'Cache produces large Responses that can be cloned and read correctly.'); done();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-matchAll.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-matchAll.js index feace5a9..b7c7bd63 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-matchAll.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-matchAll.js
@@ -6,7 +6,7 @@ prepopulated_cache_test(simple_entries, function(cache, entries) { return cache.matchAll('not-present-in-the-cache') .then(function(result) { - assert_response_array_equivalent( + assert_response_array_equals( result, [], 'Cache.matchAll should resolve with an empty array on failure.'); }); @@ -52,7 +52,7 @@ return cache.matchAll(entries.a.request, {ignoreSearch: true}) .then(function(result) { - assert_response_array_equivalent( + assert_response_array_equals( result, [ entries.a.response, @@ -69,7 +69,7 @@ return cache.matchAll(entries.a_with_query.request, {ignoreSearch: true}) .then(function(result) { - assert_response_array_equivalent( + assert_response_array_equals( result, [ entries.a.response, @@ -79,12 +79,62 @@ 'search parameters of request.'); }); }, - 'Cache.matchAll with ignoreSearch option (request with search parameter)'); + 'Cache.matchAll with ignoreSearch option (request with search parameters)'); + +cache_test(function(cache) { + var request = new Request('http://example.com/'); + var head_request = new Request('http://example.com/', {method: 'HEAD'}); + var response = new Response('foo'); + return cache.put(request.clone(), response.clone()) + .then(function() { + return cache.matchAll(head_request.clone()); + }) + .then(function(result) { + assert_response_array_equals( + result, [], + 'Cache.matchAll should resolve with empty array for a ' + + 'mismatched method.'); + return cache.matchAll(head_request.clone(), + {ignoreMethod: true}); + }) + .then(function(result) { + assert_response_array_equals( + result, [response], + 'Cache.matchAll with ignoreMethod should ignore the ' + + 'method of request.'); + }); + }, 'Cache.matchAll supports ignoreMethod'); + +cache_test(function(cache) { + var vary_request = new Request('http://example.com/c', + {headers: {'Cookies': 'is-for-cookie'}}); + var vary_response = new Response('', {headers: {'Vary': 'Cookies'}}); + var mismatched_vary_request = new Request('http://example.com/c'); + + return cache.put(vary_request.clone(), vary_response.clone()) + .then(function() { + return cache.matchAll(mismatched_vary_request.clone()); + }) + .then(function(result) { + assert_response_array_equals( + result, [], + 'Cache.matchAll should resolve as undefined with a ' + + 'mismatched vary.'); + return cache.matchAll(mismatched_vary_request.clone(), + {ignoreVary: true}); + }) + .then(function(result) { + assert_response_array_equals( + result, [vary_response], + 'Cache.matchAll with ignoreVary should ignore the ' + + 'vary of request.'); + }); + }, 'Cache.matchAll supports ignoreVary'); prepopulated_cache_test(simple_entries, function(cache, entries) { return cache.matchAll(entries.cat.request.url + '#mouse') .then(function(result) { - assert_response_array_equivalent( + assert_response_array_equals( result, [ entries.cat.response, @@ -96,17 +146,40 @@ prepopulated_cache_test(simple_entries, function(cache, entries) { return cache.matchAll('http') .then(function(result) { - assert_response_array_equivalent( + assert_response_array_equals( result, [], 'Cache.matchAll should treat query as a URL and not ' + 'just a string fragment.'); }); }, 'Cache.matchAll with string fragment "http" as query'); +prepopulated_cache_test(simple_entries, function(cache, entries) { + return cache.matchAll() + .then(function(result) { + assert_response_array_equals( + result, + [ + entries.a.response, + entries.b.response, + entries.a_with_query.response, + entries.A.response, + entries.a_https.response, + entries.a_org.response, + entries.cat.response, + entries.catmandu.response, + entries.cat_num_lives.response, + entries.cat_in_the_hat.response, + entries.non_2xx_response.response, + entries.error_response.response + ], + 'Cache.matchAll without parameters should match all entries.'); + }); + }, 'Cache.matchAll without parameters'); + prepopulated_cache_test(vary_entries, function(cache, entries) { return cache.matchAll('http://example.com/c') .then(function(result) { - assert_response_array_equivalent( + assert_response_array_equals( result, [ entries.vary_cookie_absent.response @@ -122,7 +195,7 @@ {headers: {'Cookies': 'none-of-the-above'}})); }) .then(function(result) { - assert_response_array_equivalent( + assert_response_array_equals( result, [ ], @@ -137,7 +210,7 @@ {headers: {'Cookies': 'is-for-cookie'}})); }) .then(function(result) { - assert_response_array_equivalent( + assert_response_array_equals( result, [entries.vary_cookie_is_cookie.response], 'Cache.matchAll should match the entire header if a vary header ' + @@ -149,15 +222,16 @@ return cache.matchAll('http://example.com/c', {ignoreVary: true}) .then(function(result) { - assert_response_array_equivalent( + assert_response_array_equals( result, [ entries.vary_cookie_is_cookie.response, entries.vary_cookie_is_good.response, entries.vary_cookie_absent.response ], - 'Cache.matchAll should honor "ignoreVary" parameter.'); + 'Cache.matchAll should support multiple vary request/response ' + + 'pairs.'); }); - }, 'Cache.matchAll with "ignoreVary" parameter'); + }, 'Cache.matchAll with multiple vary pairs'); done();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-put.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-put.js index 9e9fd67a..467e0b3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-put.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-put.js
@@ -102,18 +102,32 @@ }); }, 'Cache.put with an empty response body'); -cache_test(function(cache) { +cache_test(function(cache, test) { var request = new Request(test_url); var response = new Response('', { status: 206, headers: [['Content-Type', 'text/plain']] }); - return assert_promise_rejects( - cache.put(request, response), + return promise_rejects( + test, new TypeError(), + cache.put(request, response), 'Cache.put should reject 206 Responses with a TypeError.'); - }, 'Cache.put with 206 response'); + }, 'Cache.put with synthetic 206 response'); + +cache_test(function(cache, test) { + var test_url = new URL('../resources/fetch-status.py?status=206', location.href).href; + var request = new Request(test_url); + var response; + return fetch(test_url) + .then(function(fetch_result) { + assert_equals(fetch_result.status, 206, + 'Test framework error: The status code should be 206.'); + response = fetch_result.clone(); + return promise_rejects(test, new TypeError, cache.put(request, fetch_result)); + }); + }, 'Cache.put with HTTP 206 response'); cache_test(function(cache) { var test_url = new URL('../resources/fetch-status.py?status=500', location.href).href;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-storage-match.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-storage-match.js index 21517b1e..3546520 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-storage-match.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-storage-match.js
@@ -133,4 +133,110 @@ }); }, 'CacheStorageMatch with no caches available but name provided'); +cache_test(function(cache) { + var transaction = create_unique_transaction(); + + return self.caches.delete('') + .then(function() { + return self.caches.has(''); + }) + .then(function(has_cache) { + assert_false(has_cache, "The cache should not exist."); + return cache.put(transaction.request, transaction.response.clone()); + }) + .then(function() { + return self.caches.match(transaction.request, {cacheName: ''}); + }) + .then(function(response) { + assert_equals(response, undefined, + 'The response should not be found.'); + return self.caches.open(''); + }) + .then(function(cache) { + return cache.put(transaction.request, transaction.response); + }) + .then(function() { + return self.caches.match(transaction.request, {cacheName: ''}); + }) + .then(function(response) { + assert_response_equals(response, transaction.response, + 'The response should be matched.'); + return self.caches.delete(''); + }); +}, 'CacheStorageMatch with empty cache name provided'); + +cache_test(function(cache) { + var request = new Request('http://example.com/?foo'); + var no_query_request = new Request('http://example.com/'); + var response = new Response('foo'); + return cache.put(request.clone(), response.clone()) + .then(function() { + return self.caches.match(no_query_request.clone()); + }) + .then(function(result) { + assert_equals( + result, undefined, + 'CacheStorageMatch should resolve as undefined with a ' + + 'mismatched query.'); + return self.caches.match(no_query_request.clone(), + {ignoreSearch: true}); + }) + .then(function(result) { + assert_response_equals( + result, response, + 'CacheStorageMatch with ignoreSearch should ignore the ' + + 'query of the request.'); + }); + }, 'CacheStorageMatch supports ignoreSearch'); + +cache_test(function(cache) { + var request = new Request('http://example.com/'); + var head_request = new Request('http://example.com/', {method: 'HEAD'}); + var response = new Response('foo'); + return cache.put(request.clone(), response.clone()) + .then(function() { + return self.caches.match(head_request.clone()); + }) + .then(function(result) { + assert_equals( + result, undefined, + 'CacheStorageMatch should resolve as undefined with a ' + + 'mismatched method.'); + return self.caches.match(head_request.clone(), + {ignoreMethod: true}); + }) + .then(function(result) { + assert_response_equals( + result, response, + 'CacheStorageMatch with ignoreMethod should ignore the ' + + 'method of request.'); + }); + }, 'Cache.match supports ignoreMethod'); + +cache_test(function(cache) { + var vary_request = new Request('http://example.com/c', + {headers: {'Cookies': 'is-for-cookie'}}); + var vary_response = new Response('', {headers: {'Vary': 'Cookies'}}); + var mismatched_vary_request = new Request('http://example.com/c'); + + return cache.put(vary_request.clone(), vary_response.clone()) + .then(function() { + return self.caches.match(mismatched_vary_request.clone()); + }) + .then(function(result) { + assert_equals( + result, undefined, + 'CacheStorageMatch should resolve as undefined with a ' + + ' mismatched vary.'); + return self.caches.match(mismatched_vary_request.clone(), + {ignoreVary: true}); + }) + .then(function(result) { + assert_response_equals( + result, vary_response, + 'CacheStorageMatch with ignoreVary should ignore the ' + + 'vary of request.'); + }); + }, 'CacheStorageMatch supports ignoreVary'); + done();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-storage.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-storage.js index 521d3bbc..2011afd6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-storage.js +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/script-tests/cache-storage.js
@@ -16,6 +16,40 @@ }, 'CacheStorage.open'); promise_test(function(t) { + var cache_name = 'cache-storage/bar'; + var first_cache = null; + var second_cache = null; + return self.caches.open(cache_name) + .then(function(cache) { + first_cache = cache; + return self.caches.delete(cache_name); + }) + .then(function() { + return first_cache.add('../resources/simple.txt'); + }) + .then(function() { + return self.caches.keys(); + }) + .then(function(cache_names) { + assert_equals(cache_names.indexOf(cache_name), -1); + return self.caches.open(cache_name); + }) + .then(function(cache) { + second_cache = cache; + return second_cache.keys(); + }) + .then(function(keys) { + assert_equals(keys.length, 0); + return first_cache.keys(); + }) + .then(function(keys) { + assert_equals(keys.length, 1); + // Clean up + return self.caches.delete(cache_name); + }); + }, 'CacheStorage.delete dooms, but does not delete immediately'); + +promise_test(function(t) { // Note that this test may collide with other tests running in the same // origin that also uses an empty cache name. var cache_name = '';
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt index 7c119fd..9fd4e9d5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-add.https-expected.txt
@@ -1,5 +1,4 @@ This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Partial response (status code 206) is unsupported PASS Cache.add and Cache.addAll PASS Cache.add called with no arguments PASS Cache.add called with relative URL specified as a string @@ -8,8 +7,8 @@ PASS Cache.add called with POST request PASS Cache.add called twice with the same Request object PASS Cache.add with request with null body (not consumed) -FAIL Cache.add with 206 response promise_test: Unhandled rejection with value: object "ReferenceError: assert_promise_rejects is not defined" -FAIL Cache.addAll with 206 response promise_test: Unhandled rejection with value: object "TypeError: test.unreached_func is not a function" +PASS Cache.add with 206 response +PASS Cache.addAll with 206 response PASS Cache.add with request that results in a status of 404 PASS Cache.add with request that results in a status of 500 PASS Cache.addAll with no arguments
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-keys.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-keys.https.html new file mode 100644 index 0000000..736f74d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-keys.https.html
@@ -0,0 +1,10 @@ +<!DOCTYPE html> +<title>Cache.keys</title> +<link rel="help" href="https://w3c.github.io/ServiceWorker/#cache-keys"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../../service-worker/resources/test-helpers.sub.js"></script> +<script> +service_worker_test('../script-tests/cache-keys.js'); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt index 018ed9a..54610b7 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-matchAll.https-expected.txt
@@ -6,10 +6,13 @@ PASS Cache.matchAll with new Request PASS Cache.matchAll with HEAD PASS Cache.matchAll with ignoreSearch option (request with no search parameters) -PASS Cache.matchAll with ignoreSearch option (request with search parameter) +PASS Cache.matchAll with ignoreSearch option (request with search parameters) +PASS Cache.matchAll supports ignoreMethod +PASS Cache.matchAll supports ignoreVary PASS Cache.matchAll with URL containing fragment PASS Cache.matchAll with string fragment "http" as query +PASS Cache.matchAll without parameters FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0 -FAIL Cache.matchAll with "ignoreVary" parameter assert_equals: Cache.matchAll should honor "ignoreVary" parameter. expected 3 but got 1 +FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1 Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-put.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-put.https-expected.txt deleted file mode 100644 index e4f0fbbb..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-put.https-expected.txt +++ /dev/null
@@ -1,26 +0,0 @@ -This is a testharness.js-based test. -PASS Cache.put -PASS Cache.put called with simple Request and Response -PASS Cache.put called with Request and Response from fetch() -PASS Cache.put with Request without a body -PASS Cache.put with Response without a body -PASS Cache.put with a Response containing an empty URL -PASS Cache.put with an empty response body -FAIL Cache.put with 206 response promise_test: Unhandled rejection with value: object "ReferenceError: assert_promise_rejects is not defined" -PASS Cache.put with HTTP 500 response -PASS Cache.put called twice with matching Requests and different Responses -PASS Cache.put called twice with request URLs that differ only by a fragment -PASS Cache.put with a string request -PASS Cache.put with an invalid response -PASS Cache.put with a non-HTTP/HTTPS request -PASS Cache.put with a relative URL -PASS Cache.put with a non-GET request -PASS Cache.put with a null response -PASS Cache.put with a POST request -PASS Cache.put with a used response body -PASS getReader() after Cache.put -PASS Cache.put with a VARY:* Response -PASS Cache.put with an embedded VARY:* Response -PASS Cache.put should store Response.redirect() correctly -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt index f76f79a..85d43b2 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/serviceworker/cache-storage.https-expected.txt
@@ -1,6 +1,7 @@ This is a testharness.js-based test. PASS CacheStorage PASS CacheStorage.open +PASS CacheStorage.delete dooms, but does not delete immediately PASS CacheStorage.open with an empty name PASS CacheStorage.open with no arguments PASS CacheStorage.has with existing cache
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt index 1cc3111..7e9d8ad 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-add.https-expected.txt
@@ -1,5 +1,4 @@ This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Partial response (status code 206) is unsupported PASS Cache.add called with no arguments PASS Cache.add called with relative URL specified as a string PASS Cache.add called with non-HTTP/HTTPS URL @@ -7,8 +6,8 @@ PASS Cache.add called with POST request PASS Cache.add called twice with the same Request object PASS Cache.add with request with null body (not consumed) -FAIL Cache.add with 206 response promise_test: Unhandled rejection with value: object "ReferenceError: assert_promise_rejects is not defined" -FAIL Cache.addAll with 206 response promise_test: Unhandled rejection with value: object "TypeError: test.unreached_func is not a function" +PASS Cache.add with 206 response +PASS Cache.addAll with 206 response PASS Cache.add with request that results in a status of 404 PASS Cache.add with request that results in a status of 500 PASS Cache.addAll with no arguments
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-keys.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-keys.https.html new file mode 100644 index 0000000..8398c33 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-keys.https.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<title>Cache Storage: Cache.keys</title> +<link rel="help" href="https://w3c.github.io/ServiceWorker/#cache-keys"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../resources/test-helpers.js"></script> +<script src="../script-tests/cache-keys.js"></script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt index 1ed3602..c1f964f4 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-matchAll.https-expected.txt
@@ -5,10 +5,13 @@ PASS Cache.matchAll with new Request PASS Cache.matchAll with HEAD PASS Cache.matchAll with ignoreSearch option (request with no search parameters) -PASS Cache.matchAll with ignoreSearch option (request with search parameter) +PASS Cache.matchAll with ignoreSearch option (request with search parameters) +PASS Cache.matchAll supports ignoreMethod +PASS Cache.matchAll supports ignoreVary PASS Cache.matchAll with URL containing fragment PASS Cache.matchAll with string fragment "http" as query +PASS Cache.matchAll without parameters FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0 -FAIL Cache.matchAll with "ignoreVary" parameter assert_equals: Cache.matchAll should honor "ignoreVary" parameter. expected 3 but got 1 +FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1 Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-put.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-put.https-expected.txt deleted file mode 100644 index 6941437..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-put.https-expected.txt +++ /dev/null
@@ -1,25 +0,0 @@ -This is a testharness.js-based test. -PASS Cache.put called with simple Request and Response -PASS Cache.put called with Request and Response from fetch() -PASS Cache.put with Request without a body -PASS Cache.put with Response without a body -PASS Cache.put with a Response containing an empty URL -PASS Cache.put with an empty response body -FAIL Cache.put with 206 response promise_test: Unhandled rejection with value: object "ReferenceError: assert_promise_rejects is not defined" -PASS Cache.put with HTTP 500 response -PASS Cache.put called twice with matching Requests and different Responses -PASS Cache.put called twice with request URLs that differ only by a fragment -PASS Cache.put with a string request -PASS Cache.put with an invalid response -PASS Cache.put with a non-HTTP/HTTPS request -PASS Cache.put with a relative URL -PASS Cache.put with a non-GET request -PASS Cache.put with a null response -PASS Cache.put with a POST request -PASS Cache.put with a used response body -PASS getReader() after Cache.put -PASS Cache.put with a VARY:* Response -PASS Cache.put with an embedded VARY:* Response -PASS Cache.put should store Response.redirect() correctly -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt index 11b3bb4..ca03dd7 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/window/cache-storage.https-expected.txt
@@ -1,5 +1,6 @@ This is a testharness.js-based test. PASS CacheStorage.open +PASS CacheStorage.delete dooms, but does not delete immediately PASS CacheStorage.open with an empty name PASS CacheStorage.open with no arguments PASS CacheStorage.has with existing cache
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt index 1cc3111..7e9d8ad 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-add.https-expected.txt
@@ -1,5 +1,4 @@ This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Partial response (status code 206) is unsupported PASS Cache.add called with no arguments PASS Cache.add called with relative URL specified as a string PASS Cache.add called with non-HTTP/HTTPS URL @@ -7,8 +6,8 @@ PASS Cache.add called with POST request PASS Cache.add called twice with the same Request object PASS Cache.add with request with null body (not consumed) -FAIL Cache.add with 206 response promise_test: Unhandled rejection with value: object "ReferenceError: assert_promise_rejects is not defined" -FAIL Cache.addAll with 206 response promise_test: Unhandled rejection with value: object "TypeError: test.unreached_func is not a function" +PASS Cache.add with 206 response +PASS Cache.addAll with 206 response PASS Cache.add with request that results in a status of 404 PASS Cache.add with request that results in a status of 500 PASS Cache.addAll with no arguments
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-keys.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-keys.https.html similarity index 67% rename from third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-keys.html rename to third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-keys.https.html index d8ea2b7..6bafe21 100644 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-keys.html +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-keys.https.html
@@ -1,6 +1,7 @@ <!DOCTYPE html> <title>Cache.keys</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-keys"> +<link rel="help" href="https://w3c.github.io/ServiceWorker/#cache-keys"> +<meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt index 1ed3602..c1f964f4 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-matchAll.https-expected.txt
@@ -5,10 +5,13 @@ PASS Cache.matchAll with new Request PASS Cache.matchAll with HEAD PASS Cache.matchAll with ignoreSearch option (request with no search parameters) -PASS Cache.matchAll with ignoreSearch option (request with search parameter) +PASS Cache.matchAll with ignoreSearch option (request with search parameters) +PASS Cache.matchAll supports ignoreMethod +PASS Cache.matchAll supports ignoreVary PASS Cache.matchAll with URL containing fragment PASS Cache.matchAll with string fragment "http" as query +PASS Cache.matchAll without parameters FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0 -FAIL Cache.matchAll with "ignoreVary" parameter assert_equals: Cache.matchAll should honor "ignoreVary" parameter. expected 3 but got 1 +FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1 Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-put.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-put.https-expected.txt deleted file mode 100644 index 6941437..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-put.https-expected.txt +++ /dev/null
@@ -1,25 +0,0 @@ -This is a testharness.js-based test. -PASS Cache.put called with simple Request and Response -PASS Cache.put called with Request and Response from fetch() -PASS Cache.put with Request without a body -PASS Cache.put with Response without a body -PASS Cache.put with a Response containing an empty URL -PASS Cache.put with an empty response body -FAIL Cache.put with 206 response promise_test: Unhandled rejection with value: object "ReferenceError: assert_promise_rejects is not defined" -PASS Cache.put with HTTP 500 response -PASS Cache.put called twice with matching Requests and different Responses -PASS Cache.put called twice with request URLs that differ only by a fragment -PASS Cache.put with a string request -PASS Cache.put with an invalid response -PASS Cache.put with a non-HTTP/HTTPS request -PASS Cache.put with a relative URL -PASS Cache.put with a non-GET request -PASS Cache.put with a null response -PASS Cache.put with a POST request -PASS Cache.put with a used response body -PASS getReader() after Cache.put -PASS Cache.put with a VARY:* Response -PASS Cache.put with an embedded VARY:* Response -PASS Cache.put should store Response.redirect() correctly -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt index 11b3bb4..ca03dd7 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/cache-storage/worker/cache-storage.https-expected.txt
@@ -1,5 +1,6 @@ This is a testharness.js-based test. PASS CacheStorage.open +PASS CacheStorage.delete dooms, but does not delete immediately PASS CacheStorage.open with an empty name PASS CacheStorage.open with no arguments PASS CacheStorage.has with existing cache
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/common.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/common.html deleted file mode 100644 index 91e57771..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/common.html +++ /dev/null
@@ -1,50 +0,0 @@ -<!DOCTYPE html> -<title>Cache Storage: Verify that Window and Workers see same storage</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> - -function wait_for_message(worker) { - return new Promise(function(resolve) { - worker.addEventListener('message', function listener(e) { - resolve(e.data); - worker.removeEventListener('message', listener); - }); - }); -} - -promise_test(function(t) { - var cache_name = 'common-test'; - return self.caches.delete(cache_name) - .then(function() { - var worker = new Worker('resources/common-worker.js'); - worker.postMessage({name: cache_name}); - return wait_for_message(worker); - }) - .then(function(message) { - return self.caches.open(cache_name); - }) - .then(function(cache) { - return Promise.all([ - cache.match('https://example.com/a'), - cache.match('https://example.com/b'), - cache.match('https://example.com/c') - ]); - }) - .then(function(responses) { - return Promise.all(responses.map( - function(response) { return response.text(); } - )); - }) - .then(function(bodies) { - assert_equals(bodies[0], 'a', - 'Body should match response put by worker'); - assert_equals(bodies[1], 'b', - 'Body should match response put by worker'); - assert_equals(bodies[2], 'c', - 'Body should match response put by worker'); - }); -}, 'Window sees cache puts by Worker'); - -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/blank.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/blank.html deleted file mode 100644 index a3c3a46..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/blank.html +++ /dev/null
@@ -1,2 +0,0 @@ -<!DOCTYPE html> -<title>Empty doc</title>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/common-worker.js b/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/common-worker.js deleted file mode 100644 index d0e8544b5..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/common-worker.js +++ /dev/null
@@ -1,15 +0,0 @@ -self.onmessage = function(e) { - var cache_name = e.data.name; - - self.caches.open(cache_name) - .then(function(cache) { - return Promise.all([ - cache.put('https://example.com/a', new Response('a')), - cache.put('https://example.com/b', new Response('b')), - cache.put('https://example.com/c', new Response('c')) - ]); - }) - .then(function() { - self.postMessage('ok'); - }); -};
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/fetch-status.php b/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/fetch-status.php deleted file mode 100644 index 2d1dddaa..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/fetch-status.php +++ /dev/null
@@ -1,3 +0,0 @@ -<?php -header ("HTTP/1.1 " . $_GET["status"]); -?> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/iframe.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/iframe.html deleted file mode 100644 index a2f1e50..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/iframe.html +++ /dev/null
@@ -1,18 +0,0 @@ -<!DOCTYPE html> -<title>ok</title> -<script> -window.onmessage = function(e) { - var id = e.data.id; - try { - var name = 'checkallowed'; - self.caches.open(name).then(function (cache) { - self.caches.delete(name); - window.parent.postMessage({id: id, result: 'allowed'}, '*'); - }).catch(function(e) { - window.parent.postMessage({id: id, result: 'denied', name: e.name, message: e.message}, '*'); - }); - } catch (e) { - window.parent.postMessage({id: id, result: 'unexpecteddenied', name: e.name, message: e.message}, '*'); - } -}; -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/test-helpers.js b/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/test-helpers.js deleted file mode 100644 index 61ddd12..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/resources/test-helpers.js +++ /dev/null
@@ -1,302 +0,0 @@ -(function() { - var next_cache_index = 1; - - // Returns a promise that resolves to a newly created Cache object. The - // returned Cache will be destroyed when |test| completes. - function create_temporary_cache(test) { - var uniquifier = String(++next_cache_index); - var cache_name = self.location.pathname + '/' + uniquifier; - - test.add_cleanup(function() { - self.caches.delete(cache_name); - }); - - return self.caches.delete(cache_name) - .then(function() { - return self.caches.open(cache_name); - }); - } - - self.create_temporary_cache = create_temporary_cache; -})(); - -// Runs |test_function| with a temporary unique Cache passed in as the only -// argument. The function is run as a part of Promise chain owned by -// promise_test(). As such, it is expected to behave in a manner identical (with -// the exception of the argument) to a function passed into promise_test(). -// -// E.g.: -// cache_test(function(cache) { -// // Do something with |cache|, which is a Cache object. -// }, "Some Cache test"); -function cache_test(test_function, description) { - promise_test(function(test) { - return create_temporary_cache(test) - .then(cache => test_function(cache, test)); - }, description); -} - -// A set of Request/Response pairs to be used with prepopulated_cache_test(). -var simple_entries = [ - { - name: 'a', - request: new Request('http://example.com/a'), - response: new Response('') - }, - - { - name: 'b', - request: new Request('http://example.com/b'), - response: new Response('') - }, - - { - name: 'a_with_query', - request: new Request('http://example.com/a?q=r'), - response: new Response('') - }, - - { - name: 'A', - request: new Request('http://example.com/A'), - response: new Response('') - }, - - { - name: 'a_https', - request: new Request('https://example.com/a'), - response: new Response('') - }, - - { - name: 'a_org', - request: new Request('http://example.org/a'), - response: new Response('') - }, - - { - name: 'cat', - request: new Request('http://example.com/cat'), - response: new Response('') - }, - - { - name: 'catmandu', - request: new Request('http://example.com/catmandu'), - response: new Response('') - }, - - { - name: 'cat_num_lives', - request: new Request('http://example.com/cat?lives=9'), - response: new Response('') - }, - - { - name: 'cat_in_the_hat', - request: new Request('http://example.com/cat/in/the/hat'), - response: new Response('') - }, - - { - name: 'non_2xx_response', - request: new Request('http://example.com/non2xx'), - response: new Response('', {status: 404, statusText: 'nope'}) - }, - - { - name: 'error_response', - request: new Request('http://example.com/error'), - response: Response.error() - }, -]; - -// A set of Request/Response pairs to be used with prepopulated_cache_test(). -// These contain a mix of test cases that use Vary headers. -var vary_entries = [ - { - name: 'vary_cookie_is_cookie', - request: new Request('http://example.com/c', - {headers: {'Cookies': 'is-for-cookie'}}), - response: new Response('', - {headers: {'Vary': 'Cookies'}}) - }, - - { - name: 'vary_cookie_is_good', - request: new Request('http://example.com/c', - {headers: {'Cookies': 'is-good-enough-for-me'}}), - response: new Response('', - {headers: {'Vary': 'Cookies'}}) - }, - - { - name: 'vary_cookie_absent', - request: new Request('http://example.com/c'), - response: new Response('', - {headers: {'Vary': 'Cookies'}}) - } -]; - -// Run |test_function| with a Cache object and a map of entries. Prior to the -// call, the Cache is populated by cache entries from |entries|. The latter is -// expected to be an Object mapping arbitrary keys to objects of the form -// {request: <Request object>, response: <Response object>}. The entries are -// added sequentially so that tests can verify the ordering of the cache -// methods. -// -// |test_function| should return a Promise that can be used with promise_test. -function prepopulated_cache_test(entries, test_function, description) { - cache_test(function(cache) { - var hash = {}; - var resolveMethod = null; - - var promise = new Promise(function(resolve, reject) { - resolveMethod = resolve; - }) - .then(function() { - assert_equals(Object.keys(hash).length, entries.length); - return test_function(cache, hash); - }); - - // Add the entries to the cache sequentially. - // TODO(jkarlin): Once async/await is available use it to prettify this - // code. - var i = 0; - var processNextEntry = function(i) { - if (i == entries.length) { - resolveMethod(); - return; - } - entry = entries[i]; - hash[entry.name] = entry; - cache.put(entry.request.clone(), entry.response.clone()) - .then(function() { - processNextEntry(i+1); - }) - .catch(function(e) { - assert_unreached( - 'Test setup failed for entry ' + entry.name + ': ' + e); - }) - } - - processNextEntry(0); - return promise; - }, description); -} - -// Helper for testing with Headers objects. Compares Headers instances -// by serializing |expected| and |actual| to arrays and comparing. -function assert_header_equals(actual, expected, description) { - assert_class_string(actual, "Headers", description); - var header; - var actual_headers = []; - var expected_headers = []; - for (header of actual) - actual_headers.push(header[0] + ": " + header[1]); - for (header of expected) - expected_headers.push(header[0] + ": " + header[1]); - assert_array_equals(actual_headers, expected_headers, - description + " Headers differ."); -} - -// Helper for testing with Response objects. Compares simple -// attributes defined on the interfaces, as well as the headers. It -// does not compare the response bodies. -function assert_response_equals(actual, expected, description) { - assert_class_string(actual, "Response", description); - ["type", "url", "status", "ok", "statusText"].forEach(function(attribute) { - assert_equals(actual[attribute], expected[attribute], - description + " Attributes differ: " + attribute + "."); - }); - assert_header_equals(actual.headers, expected.headers, description); -} - -// Asserts that two arrays |actual| and |expected| contain the same -// set of Responses as determined by assert_response_equals(). The -// corresponding elements must occupy corresponding indices in their -// respective arrays. -function assert_response_array_equals(actual, expected, description) { - assert_true(Array.isArray(actual), description); - assert_equals(actual.length, expected.length, description); - actual.forEach(function(value, index) { - assert_response_equals(value, expected[index], - description + " : object[" + index + "]"); - }); -} - -// Equivalent to assert_in_array, but uses assert_response_equals. -function assert_response_in_array(actual, expected_array, description) { - assert_true(expected_array.some(function(element) { - try { - assert_response_equals(actual, element); - return true; - } catch (e) { - return false; - } - }), description); -} - -// Helper for testing with Request objects. Compares simple -// attributes defined on the interfaces, as well as the headers. -function assert_request_equals(actual, expected, description) { - assert_class_string(actual, "Request", description); - ["url"].forEach(function(attribute) { - assert_equals(actual[attribute], expected[attribute], - description + " Attributes differ: " + attribute + "."); - }); - assert_header_equals(actual.headers, expected.headers, description); -} - -// TODO(zino): Should remove this function once keys() returns request -// keys in key insertion order. Please see http://crbug.com/627821. -// -// Assert that the two arrays |actual| and |expected| contain the same -// set of Requests as determined by assert_request_equals. The order -// is not significant. -// -// |expected| is assumed to not contain any duplicates. -function assert_request_array_equivalent(actual, expected, description) { - assert_true(Array.isArray(actual), description); - assert_equals(actual.length, expected.length, description); - expected.forEach(function(expected_element) { - // assert_request_in_array treats the first argument as being - // 'actual', and the second as being 'expected array'. We are - // switching them around because we want to be resilient - // against the |actual| array containing duplicates. - assert_request_in_array(expected_element, actual, description); - }); -} - -// Asserts that two arrays |actual| and |expected| contain the same -// set of Requests as determined by assert_request_equals(). The -// corresponding elements must occupy corresponding indices in their -// respective arrays. -function assert_request_array_equals(actual, expected, description) { - assert_true(Array.isArray(actual), description); - assert_equals(actual.length, expected.length, description); - actual.forEach(function(value, index) { - assert_request_equals(value, expected[index], - description + " : object[" + index + "]"); - }); -} - -// Equivalent to assert_in_array, but uses assert_request_equals. -function assert_request_in_array(actual, expected_array, description) { - assert_true(expected_array.some(function(element) { - try { - assert_request_equals(actual, element); - return true; - } catch (e) { - return false; - } - }), description); -} - -// Deletes all caches, returning a promise indicating success. -function delete_all_caches() { - return self.caches.keys() - .then(function(keys) { - return Promise.all(keys.map(self.caches.delete.bind(self.caches))); - }); -}
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-add.js b/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-add.js deleted file mode 100644 index c3039b1..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-add.js +++ /dev/null
@@ -1,265 +0,0 @@ -if (self.importScripts) { - importScripts('/resources/testharness.js'); - importScripts('../resources/test-helpers.js'); -} - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.add(), - 'Cache.add should throw a TypeError when no arguments are given.'); - }, 'Cache.add called with no arguments'); - -cache_test(function(cache) { - return cache.add('../resources/simple.txt') - .then(function(result) { - assert_equals(result, undefined, - 'Cache.add should resolve with undefined on success.'); - return cache.match('../resources/simple.txt'); - }) - .then(function(response) { - assert_class_string(response, 'Response', - 'Cache.add should put a resource in the cache.'); - return response.text(); - }) - .then(function(body) { - assert_equals(body, 'a simple text file\n', - 'Cache.add should retrieve the correct body.'); - }); - }, 'Cache.add called with relative URL specified as a string'); - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.add('javascript://this-is-not-http-mmkay'), - 'Cache.add should throw a TypeError for non-HTTP/HTTPS URLs.'); - }, 'Cache.add called with non-HTTP/HTTPS URL'); - -cache_test(function(cache) { - var request = new Request('../resources/simple.txt'); - return cache.add(request) - .then(function(result) { - assert_equals(result, undefined, - 'Cache.add should resolve with undefined on success.'); - }); - }, 'Cache.add called with Request object'); - -cache_test(function(cache, test) { - var request = new Request('../resources/simple.txt', - {method: 'POST', body: 'This is a body.'}); - return promise_rejects( - test, - new TypeError(), - cache.add(request), - 'Cache.add should throw a TypeError for non-GET requests.'); - }, 'Cache.add called with POST request'); - -cache_test(function(cache) { - var request = new Request('../resources/simple.txt'); - return cache.add(request) - .then(function(result) { - assert_equals(result, undefined, - 'Cache.add should resolve with undefined on success.'); - }) - .then(function() { - return cache.add(request); - }) - .then(function(result) { - assert_equals(result, undefined, - 'Cache.add should resolve with undefined on success.'); - }); - }, 'Cache.add called twice with the same Request object'); - -cache_test(function(cache) { - var request = new Request('../resources/simple.txt'); - return request.text() - .then(function() { - assert_false(request.bodyUsed); - }) - .then(function() { - return cache.add(request); - }); - }, 'Cache.add called with Request object with a used body'); - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.add('this-does-not-exist-please-dont-create-it'), - 'Cache.add should reject if response is !ok'); - }, 'Cache.add with request that results in a status of 404'); - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.add('../resources/fetch-status.php?status=500'), - 'Cache.add should reject if response is !ok'); - }, 'Cache.add with request that results in a status of 500'); - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.add('../resources/fetch-status.php?status=206'), - 'Cache.add should reject on partial response'); - }, 'Cache.add with request that results in a status of 206'); - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.addAll(['../resources/simple.txt', - '../resources/fetch-status.php?status=206']), - 'Cache.addAll should reject on partial response'); - }, 'Cache.addAll with request that results in a status of 206'); - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.addAll(), - 'Cache.addAll with no arguments should throw TypeError.'); - }, 'Cache.addAll with no arguments'); - -cache_test(function(cache, test) { - // Assumes the existence of ../resources/simple.txt and ../resources/blank.html - var urls = ['../resources/simple.txt', undefined, '../resources/blank.html']; - return promise_rejects( - test, - new TypeError(), - cache.addAll(), - 'Cache.addAll should throw TypeError for an undefined argument.'); - }, 'Cache.addAll with a mix of valid and undefined arguments'); - -cache_test(function(cache) { - return cache.addAll([]) - .then(function(result) { - assert_equals(result, undefined, - 'Cache.addAll should resolve with undefined on ' + - 'success.'); - return cache.keys(); - }) - .then(function(result) { - assert_equals(result.length, 0, - 'There should be no entry in the cache.'); - }); - }, 'Cache.addAll with an empty array'); - -cache_test(function(cache) { - // Assumes the existence of ../resources/simple.txt and - // ../resources/blank.html - var urls = ['../resources/simple.txt', - self.location.href, - '../resources/blank.html']; - return cache.addAll(urls) - .then(function(result) { - assert_equals(result, undefined, - 'Cache.addAll should resolve with undefined on ' + - 'success.'); - return Promise.all( - urls.map(function(url) { return cache.match(url); })); - }) - .then(function(responses) { - assert_class_string( - responses[0], 'Response', - 'Cache.addAll should put a resource in the cache.'); - assert_class_string( - responses[1], 'Response', - 'Cache.addAll should put a resource in the cache.'); - assert_class_string( - responses[2], 'Response', - 'Cache.addAll should put a resource in the cache.'); - return Promise.all( - responses.map(function(response) { return response.text(); })); - }) - .then(function(bodies) { - assert_equals( - bodies[0], 'a simple text file\n', - 'Cache.add should retrieve the correct body.'); - assert_equals( - bodies[2], '<!DOCTYPE html>\n<title>Empty doc</title>\n', - 'Cache.add should retrieve the correct body.'); - }); - }, 'Cache.addAll with string URL arguments'); - -cache_test(function(cache) { - // Assumes the existence of ../resources/simple.txt and - // ../resources/blank.html - var urls = ['../resources/simple.txt', - self.location.href, - '../resources/blank.html']; - var requests = urls.map(function(url) { - return new Request(url); - }); - return cache.addAll(requests) - .then(function(result) { - assert_equals(result, undefined, - 'Cache.addAll should resolve with undefined on ' + - 'success.'); - return Promise.all( - urls.map(function(url) { return cache.match(url); })); - }) - .then(function(responses) { - assert_class_string( - responses[0], 'Response', - 'Cache.addAll should put a resource in the cache.'); - assert_class_string( - responses[1], 'Response', - 'Cache.addAll should put a resource in the cache.'); - assert_class_string( - responses[2], 'Response', - 'Cache.addAll should put a resource in the cache.'); - return Promise.all( - responses.map(function(response) { return response.text(); })); - }) - .then(function(bodies) { - assert_equals( - bodies[0], 'a simple text file\n', - 'Cache.add should retrieve the correct body.'); - assert_equals( - bodies[2], '<!DOCTYPE html>\n<title>Empty doc</title>\n', - 'Cache.add should retrieve the correct body.'); - }); - }, 'Cache.addAll with Request arguments'); - -cache_test(function(cache, test) { - // Assumes that ../resources/simple.txt and ../resources/blank.html exist. - // The second resource does not. - var urls = ['../resources/simple.txt', - 'this-resource-should-not-exist', - '../resources/blank.html']; - var requests = urls.map(function(url) { - return new Request(url); - }); - return promise_rejects( - test, - new TypeError(), - cache.addAll(requests), - 'Cache.addAll should reject with TypeError if any request fails') - .then(function() { - return Promise.all(urls.map(function(url) { - return cache.match(url); - })); - }) - .then(function(matches) { - assert_array_equals( - matches, - [undefined, undefined, undefined], - 'If any response fails, no response should be added to cache'); - }); - }, 'Cache.addAll with a mix of succeeding and failing requests'); - -cache_test(function(cache, test) { - var request = new Request('../resources/simple.txt'); - return promise_rejects( - test, - 'InvalidStateError', - cache.addAll([request, request]), - 'Cache.addAll should throw InvalidStateError if the same request is added ' + - 'twice.'); - }, 'Cache.addAll called with the same Request object specified twice'); - -done();
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-delete.js b/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-delete.js deleted file mode 100644 index eb38f4a..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-delete.js +++ /dev/null
@@ -1,164 +0,0 @@ -if (self.importScripts) { - importScripts('/resources/testharness.js'); - importScripts('../resources/test-helpers.js'); -} - -var test_url = 'https://example.com/foo'; - -// Construct a generic Request object. The URL is |test_url|. All other fields -// are defaults. -function new_test_request() { - return new Request(test_url); -} - -// Construct a generic Response object. -function new_test_response() { - return new Response('Hello world!', { status: 200 }); -} - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.delete(), - 'Cache.delete should reject with a TypeError when called with no ' + - 'arguments.'); - }, 'Cache.delete with no arguments'); - -cache_test(function(cache) { - return cache.put(new_test_request(), new_test_response()) - .then(function() { - return cache.delete(test_url); - }) - .then(function(result) { - assert_true(result, - 'Cache.delete should resolve with "true" if an entry ' + - 'was successfully deleted.'); - return cache.match(test_url); - }) - .then(function(result) { - assert_equals(result, undefined, - 'Cache.delete should remove matching entries from cache.'); - }); - }, 'Cache.delete called with a string URL'); - -cache_test(function(cache) { - var request = new Request(test_url); - return cache.put(request, new_test_response()) - .then(function() { - return cache.delete(request); - }) - .then(function(result) { - assert_true(result, - 'Cache.delete should resolve with "true" if an entry ' + - 'was successfully deleted.'); - }); - }, 'Cache.delete called with a Request object'); - -cache_test(function(cache) { - var request = new Request(test_url); - var response = new_test_response(); - return cache.put(request, response) - .then(function() { - return cache.delete(new Request(test_url, {method: 'HEAD'})); - }) - .then(function(result) { - assert_false(result, - 'Cache.delete should not match a non-GET request ' + - 'unless ignoreMethod option is set.'); - return cache.match(test_url); - }) - .then(function(result) { - assert_response_equals(result, response, - 'Cache.delete should leave non-matching response in the cache.'); - return cache.delete(new Request(test_url, {method: 'HEAD'}), - {ignoreMethod: true}); - }) - .then(function(result) { - assert_true(result, - 'Cache.delete should match a non-GET request ' + - ' if ignoreMethod is true.') - }); - }, 'Cache.delete called with a HEAD request'); - -cache_test(function(cache) { - var vary_request = new Request('http://example.com/c', - {headers: {'Cookies': 'is-for-cookie'}}); - var vary_response = new Response('', {headers: {'Vary': 'Cookies'}}); - var mismatched_vary_request = new Request('http://example.com/c'); - - return cache.put(vary_request.clone(), vary_response.clone()) - .then(function() { - return cache.delete(mismatched_vary_request.clone()); - }) - .then(function(result) { - assert_false(result, - 'Cache.delete should not delete if vary does not ' + - 'match unless ignoreVary is true'); - return cache.delete(mismatched_vary_request.clone(), - {ignoreVary: true}); - }) - .then(function(result) { - assert_true(result, - 'Cache.delete should ignore vary if ignoreVary is true'); - }); - }, 'Cache.delete supports ignoreVary'); - -cache_test(function(cache) { - return cache.delete(test_url) - .then(function(result) { - assert_false(result, - 'Cache.delete should resolve with "false" if there ' + - 'are no matching entries.'); - }); - }, 'Cache.delete with a non-existent entry'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.matchAll(entries.a_with_query.request, - { ignoreSearch: true }) - .then(function(result) { - assert_response_array_equals( - result, - [ - entries.a.response, - entries.a_with_query.response - ]); - return cache.delete(entries.a_with_query.request, - { ignoreSearch: true }); - }) - .then(function(result) { - return cache.matchAll(entries.a_with_query.request, - { ignoreSearch: true }); - }) - .then(function(result) { - assert_response_array_equals(result, []); - }); - }, - 'Cache.delete with ignoreSearch option (request with search parameters)'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.matchAll(entries.a_with_query.request, - { ignoreSearch: true }) - .then(function(result) { - assert_response_array_equals( - result, - [ - entries.a.response, - entries.a_with_query.response - ]); - // cache.delete()'s behavior should be the same if ignoreSearch is - // not provided or if ignoreSearch is false. - return cache.delete(entries.a_with_query.request, - { ignoreSearch: false }); - }) - .then(function(result) { - return cache.matchAll(entries.a_with_query.request, - { ignoreSearch: true }); - }) - .then(function(result) { - assert_response_array_equals(result, [ entries.a.response ]); - }); - }, - 'Cache.delete with ignoreSearch option (when it is specified as false)'); - -done();
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-match.js b/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-match.js deleted file mode 100644 index 30d9f5b7..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-match.js +++ /dev/null
@@ -1,297 +0,0 @@ -if (self.importScripts) { - importScripts('/resources/testharness.js'); - importScripts('../resources/test-helpers.js'); -} - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.match('not-present-in-the-cache') - .then(function(result) { - assert_equals(result, undefined, - 'Cache.match failures should resolve with undefined.'); - }); - }, 'Cache.match with no matching entries'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.match(entries.a.request.url) - .then(function(result) { - assert_response_equals(result, entries.a.response, - 'Cache.match should match by URL.'); - }); - }, 'Cache.match with URL'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.match(entries.a.request) - .then(function(result) { - assert_response_equals(result, entries.a.response, - 'Cache.match should match by Request.'); - }); - }, 'Cache.match with Request'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - var alt_response = new Response('', {status: 201}); - - return self.caches.open('second_matching_cache') - .then(function(cache) { - return cache.put(entries.a.request, alt_response.clone()); - }) - .then(function() { - return cache.match(entries.a.request) - }) - .then(function(result) { - assert_response_equals( - result, entries.a.response, - 'Cache.match should match the first cache.'); - }); - }, 'Cache.match with multiple cache hits'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.match(new Request(entries.a.request.url)) - .then(function(result) { - assert_response_equals(result, entries.a.response, - 'Cache.match should match by Request.'); - }); - }, 'Cache.match with new Request'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.match(new Request(entries.a.request.url, {method: 'HEAD'})) - .then(function(result) { - assert_equals(result, undefined, - 'Cache.match should not match HEAD Request.'); - }); - }, 'Cache.match with HEAD'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.match(entries.a.request, - {ignoreSearch: true}) - .then(function(result) { - assert_response_in_array( - result, - [ - entries.a.response, - entries.a_with_query.response - ], - 'Cache.match with ignoreSearch should ignore the ' + - 'search parameters of cached request.'); - }); - }, - 'Cache.match with ignoreSearch option (request with no search ' + - 'parameters)'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.match(entries.a_with_query.request, - {ignoreSearch: true}) - .then(function(result) { - assert_response_in_array( - result, - [ - entries.a.response, - entries.a_with_query.response - ], - 'Cache.match with ignoreSearch should ignore the ' + - 'search parameters of request.'); - }); - }, - 'Cache.match with ignoreSearch option (request with search parameter)'); - -cache_test(function(cache) { - var request = new Request('http://example.com/'); - var head_request = new Request('http://example.com/', {method: 'HEAD'}); - var response = new Response('foo'); - return cache.put(request.clone(), response.clone()) - .then(function() { - return cache.match(head_request.clone()); - }) - .then(function(result) { - assert_equals( - result, undefined, - 'Cache.match should resolve as undefined with a ' + - 'mismatched method.'); - return cache.match(head_request.clone(), - {ignoreMethod: true}); - }) - .then(function(result) { - assert_response_equals( - result, response, - 'Cache.match with ignoreMethod should ignore the ' + - 'method of request.'); - }); - }, 'Cache.match supports ignoreMethod'); - -cache_test(function(cache) { - var vary_request = new Request('http://example.com/c', - {headers: {'Cookies': 'is-for-cookie'}}); - var vary_response = new Response('', {headers: {'Vary': 'Cookies'}}); - var mismatched_vary_request = new Request('http://example.com/c'); - - return cache.put(vary_request.clone(), vary_response.clone()) - .then(function() { - return cache.match(mismatched_vary_request.clone()); - }) - .then(function(result) { - assert_equals( - result, undefined, - 'Cache.match should resolve as undefined with a ' + - 'mismatched vary.'); - return cache.match(mismatched_vary_request.clone(), - {ignoreVary: true}); - }) - .then(function(result) { - assert_response_equals( - result, vary_response, - 'Cache.match with ignoreVary should ignore the ' + - 'vary of request.'); - }); - }, 'Cache.match supports ignoreVary'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.match(entries.cat.request.url + '#mouse') - .then(function(result) { - assert_response_equals(result, entries.cat.response, - 'Cache.match should ignore URL fragment.'); - }); - }, 'Cache.match with URL containing fragment'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.match('http') - .then(function(result) { - assert_equals( - result, undefined, - 'Cache.match should treat query as a URL and not ' + - 'just a string fragment.'); - }); - }, 'Cache.match with string fragment "http" as query'); - -prepopulated_cache_test(vary_entries, function(cache, entries) { - return cache.match('http://example.com/c') - .then(function(result) { - assert_response_in_array( - result, - [ - entries.vary_cookie_absent.response - ], - 'Cache.match should honor "Vary" header.'); - }); - }, 'Cache.match with responses containing "Vary" header'); - -cache_test(function(cache) { - var request = new Request('http://example.com'); - var response; - var request_url = new URL('../resources/simple.txt', location.href).href; - return fetch(request_url) - .then(function(fetch_result) { - response = fetch_result; - assert_equals( - response.url, request_url, - '[https://fetch.spec.whatwg.org/#dom-response-url] ' + - 'Reponse.url should return the URL of the response.'); - return cache.put(request, response.clone()); - }) - .then(function() { - return cache.match(request.url); - }) - .then(function(result) { - assert_response_equals( - result, response, - 'Cache.match should return a Response object that has the same ' + - 'properties as the stored response.'); - return cache.match(response.url); - }) - .then(function(result) { - assert_equals( - result, undefined, - 'Cache.match should not match cache entry based on response URL.'); - }); - }, 'Cache.match with Request and Response objects with different URLs'); - -cache_test(function(cache) { - var request_url = new URL('../resources/simple.txt', location.href).href; - return fetch(request_url) - .then(function(fetch_result) { - return cache.put(new Request(request_url), fetch_result); - }) - .then(function() { - return cache.match(request_url); - }) - .then(function(result) { - return result.text(); - }) - .then(function(body_text) { - assert_equals(body_text, 'a simple text file\n', - 'Cache.match should return a Response object with a ' + - 'valid body.'); - }) - .then(function() { - return cache.match(request_url); - }) - .then(function(result) { - return result.text(); - }) - .then(function(body_text) { - assert_equals(body_text, 'a simple text file\n', - 'Cache.match should return a Response object with a ' + - 'valid body each time it is called.'); - }); - }, 'Cache.match invoked multiple times for the same Request/Response'); - -cache_test(function(cache) { - var request_url = new URL('../resources/simple.txt', location.href).href; - return fetch(request_url) - .then(function(fetch_result) { - return cache.put(new Request(request_url), fetch_result); - }) - .then(function() { - return cache.match(request_url); - }) - .then(function(result) { - return result.blob(); - }) - .then(function(blob) { - sliced = blob.slice(2,8); - - return new Promise(function (resolve, reject) { - reader = new FileReader(); - reader.onloadend = function(event) { - resolve(event.target.result); - } - reader.readAsText(sliced); - }); - }) - .then(function(text) { - assert_equals(text, 'simple', - 'A Response blob returned by Cache.match should be ' + - 'sliceable.' ); - }); - }, 'Cache.match blob should be sliceable'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - var request = new Request(entries.a.request.clone(), {method: 'POST'}); - return cache.match(request) - .then(function(result) { - assert_equals(result, undefined, - 'Cache.match should not find a match'); - }); - }, 'Cache.match with POST Request'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - var response = entries.non_2xx_response.response; - return cache.match(entries.non_2xx_response.request.url) - .then(function(result) { - assert_response_equals( - result, entries.non_2xx_response.response, - 'Cache.match should return a Response object that has the ' + - 'same properties as a stored non-2xx response.'); - }); - }, 'Cache.match with a non-2xx Response'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - var response = entries.error_response.response; - return cache.match(entries.error_response.request.url) - .then(function(result) { - assert_response_equals( - result, entries.error_response.response, - 'Cache.match should return a Response object that has the ' + - 'same properties as a stored network error response.'); - }); - }, 'Cache.match with a network error Response'); - -done();
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-matchAll.js b/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-matchAll.js deleted file mode 100644 index b7c7bd63..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-matchAll.js +++ /dev/null
@@ -1,237 +0,0 @@ -if (self.importScripts) { - importScripts('/resources/testharness.js'); - importScripts('../resources/test-helpers.js'); -} - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.matchAll('not-present-in-the-cache') - .then(function(result) { - assert_response_array_equals( - result, [], - 'Cache.matchAll should resolve with an empty array on failure.'); - }); - }, 'Cache.matchAll with no matching entries'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.matchAll(entries.a.request.url) - .then(function(result) { - assert_response_array_equals(result, [entries.a.response], - 'Cache.matchAll should match by URL.'); - }); - }, 'Cache.matchAll with URL'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.matchAll(entries.a.request) - .then(function(result) { - assert_response_array_equals( - result, [entries.a.response], - 'Cache.matchAll should match by Request.'); - }); - }, 'Cache.matchAll with Request'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.matchAll(new Request(entries.a.request.url)) - .then(function(result) { - assert_response_array_equals( - result, [entries.a.response], - 'Cache.matchAll should match by Request.'); - }); - }, 'Cache.matchAll with new Request'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.matchAll(new Request(entries.a.request.url, {method: 'HEAD'}), - {ignoreSearch: true}) - .then(function(result) { - assert_response_array_equals( - result, [], - 'Cache.matchAll should not match HEAD Request.'); - }); - }, 'Cache.matchAll with HEAD'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.matchAll(entries.a.request, - {ignoreSearch: true}) - .then(function(result) { - assert_response_array_equals( - result, - [ - entries.a.response, - entries.a_with_query.response - ], - 'Cache.matchAll with ignoreSearch should ignore the ' + - 'search parameters of cached request.'); - }); - }, - 'Cache.matchAll with ignoreSearch option (request with no search ' + - 'parameters)'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.matchAll(entries.a_with_query.request, - {ignoreSearch: true}) - .then(function(result) { - assert_response_array_equals( - result, - [ - entries.a.response, - entries.a_with_query.response - ], - 'Cache.matchAll with ignoreSearch should ignore the ' + - 'search parameters of request.'); - }); - }, - 'Cache.matchAll with ignoreSearch option (request with search parameters)'); - -cache_test(function(cache) { - var request = new Request('http://example.com/'); - var head_request = new Request('http://example.com/', {method: 'HEAD'}); - var response = new Response('foo'); - return cache.put(request.clone(), response.clone()) - .then(function() { - return cache.matchAll(head_request.clone()); - }) - .then(function(result) { - assert_response_array_equals( - result, [], - 'Cache.matchAll should resolve with empty array for a ' + - 'mismatched method.'); - return cache.matchAll(head_request.clone(), - {ignoreMethod: true}); - }) - .then(function(result) { - assert_response_array_equals( - result, [response], - 'Cache.matchAll with ignoreMethod should ignore the ' + - 'method of request.'); - }); - }, 'Cache.matchAll supports ignoreMethod'); - -cache_test(function(cache) { - var vary_request = new Request('http://example.com/c', - {headers: {'Cookies': 'is-for-cookie'}}); - var vary_response = new Response('', {headers: {'Vary': 'Cookies'}}); - var mismatched_vary_request = new Request('http://example.com/c'); - - return cache.put(vary_request.clone(), vary_response.clone()) - .then(function() { - return cache.matchAll(mismatched_vary_request.clone()); - }) - .then(function(result) { - assert_response_array_equals( - result, [], - 'Cache.matchAll should resolve as undefined with a ' + - 'mismatched vary.'); - return cache.matchAll(mismatched_vary_request.clone(), - {ignoreVary: true}); - }) - .then(function(result) { - assert_response_array_equals( - result, [vary_response], - 'Cache.matchAll with ignoreVary should ignore the ' + - 'vary of request.'); - }); - }, 'Cache.matchAll supports ignoreVary'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.matchAll(entries.cat.request.url + '#mouse') - .then(function(result) { - assert_response_array_equals( - result, - [ - entries.cat.response, - ], - 'Cache.matchAll should ignore URL fragment.'); - }); - }, 'Cache.matchAll with URL containing fragment'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.matchAll('http') - .then(function(result) { - assert_response_array_equals( - result, [], - 'Cache.matchAll should treat query as a URL and not ' + - 'just a string fragment.'); - }); - }, 'Cache.matchAll with string fragment "http" as query'); - -prepopulated_cache_test(simple_entries, function(cache, entries) { - return cache.matchAll() - .then(function(result) { - assert_response_array_equals( - result, - [ - entries.a.response, - entries.b.response, - entries.a_with_query.response, - entries.A.response, - entries.a_https.response, - entries.a_org.response, - entries.cat.response, - entries.catmandu.response, - entries.cat_num_lives.response, - entries.cat_in_the_hat.response, - entries.non_2xx_response.response, - entries.error_response.response - ], - 'Cache.matchAll without parameters should match all entries.'); - }); - }, 'Cache.matchAll without parameters'); - -prepopulated_cache_test(vary_entries, function(cache, entries) { - return cache.matchAll('http://example.com/c') - .then(function(result) { - assert_response_array_equals( - result, - [ - entries.vary_cookie_absent.response - ], - 'Cache.matchAll should exclude matches if a vary header is ' + - 'missing in the query request, but is present in the cached ' + - 'request.'); - }) - - .then(function() { - return cache.matchAll( - new Request('http://example.com/c', - {headers: {'Cookies': 'none-of-the-above'}})); - }) - .then(function(result) { - assert_response_array_equals( - result, - [ - ], - 'Cache.matchAll should exclude matches if a vary header is ' + - 'missing in the cached request, but is present in the query ' + - 'request.'); - }) - - .then(function() { - return cache.matchAll( - new Request('http://example.com/c', - {headers: {'Cookies': 'is-for-cookie'}})); - }) - .then(function(result) { - assert_response_array_equals( - result, - [entries.vary_cookie_is_cookie.response], - 'Cache.matchAll should match the entire header if a vary header ' + - 'is present in both the query and cached requests.'); - }); - }, 'Cache.matchAll with responses containing "Vary" header'); - -prepopulated_cache_test(vary_entries, function(cache, entries) { - return cache.matchAll('http://example.com/c', - {ignoreVary: true}) - .then(function(result) { - assert_response_array_equals( - result, - [ - entries.vary_cookie_is_cookie.response, - entries.vary_cookie_is_good.response, - entries.vary_cookie_absent.response - ], - 'Cache.matchAll should support multiple vary request/response ' + - 'pairs.'); - }); - }, 'Cache.matchAll with multiple vary pairs'); - -done();
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-put.js b/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-put.js deleted file mode 100644 index 1517f94..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-put.js +++ /dev/null
@@ -1,306 +0,0 @@ -if (self.importScripts) { - importScripts('/resources/testharness.js'); - importScripts('../resources/test-helpers.js'); -} - -var test_url = 'https://example.com/foo'; -var test_body = 'Hello world!'; - -cache_test(function(cache) { - var request = new Request(test_url); - var response = new Response(test_body); - return cache.put(request, response) - .then(function(result) { - assert_equals(result, undefined, - 'Cache.put should resolve with undefined on success.'); - }); - }, 'Cache.put called with simple Request and Response'); - -cache_test(function(cache) { - var test_url = new URL('../resources/simple.txt', location.href).href; - var request = new Request(test_url); - var response; - return fetch(test_url) - .then(function(fetch_result) { - response = fetch_result.clone(); - return cache.put(request, fetch_result); - }) - .then(function() { - return cache.match(test_url); - }) - .then(function(result) { - assert_response_equals(result, response, - 'Cache.put should update the cache with ' + - 'new request and response.'); - return result.text(); - }) - .then(function(body) { - assert_equals(body, 'a simple text file\n', - 'Cache.put should store response body.'); - }); - }, 'Cache.put called with Request and Response from fetch()'); - -cache_test(function(cache) { - var request = new Request(test_url); - var response = new Response(test_body); - assert_false(request.bodyUsed, - '[https://fetch.spec.whatwg.org/#dom-body-bodyused] ' + - 'Request.bodyUsed should be initially false.'); - return cache.put(request, response) - .then(function() { - assert_false(request.bodyUsed, - 'Cache.put should not mark empty request\'s body used'); - }); - }, 'Cache.put with Request without a body'); - -cache_test(function(cache) { - var request = new Request(test_url); - var response = new Response(); - assert_false(response.bodyUsed, - '[https://fetch.spec.whatwg.org/#dom-body-bodyused] ' + - 'Response.bodyUsed should be initially false.'); - return cache.put(request, response) - .then(function() { - assert_false(response.bodyUsed, - 'Cache.put should not mark empty response\'s body used'); - }); - }, 'Cache.put with Response without a body'); - -cache_test(function(cache) { - var request = new Request(test_url); - var response = new Response(test_body); - return cache.put(request, response.clone()) - .then(function() { - return cache.match(test_url); - }) - .then(function(result) { - assert_response_equals(result, response, - 'Cache.put should update the cache with ' + - 'new Request and Response.'); - }); - }, 'Cache.put with a Response containing an empty URL'); - -cache_test(function(cache) { - var request = new Request(test_url); - var response = new Response('', { - status: 200, - headers: [['Content-Type', 'text/plain']] - }); - return cache.put(request, response) - .then(function() { - return cache.match(test_url); - }) - .then(function(result) { - assert_equals(result.status, 200, 'Cache.put should store status.'); - assert_equals(result.headers.get('Content-Type'), 'text/plain', - 'Cache.put should store headers.'); - return result.text(); - }) - .then(function(body) { - assert_equals(body, '', - 'Cache.put should store response body.'); - }); - }, 'Cache.put with an empty response body'); - -cache_test(function(cache) { - var test_url = new URL('../resources/fetch-status.php?status=500', location.href).href; - var request = new Request(test_url); - var response; - return fetch(test_url) - .then(function(fetch_result) { - assert_equals(fetch_result.status, 500, - 'Test framework error: The status code should be 500.'); - response = fetch_result.clone(); - return cache.put(request, fetch_result); - }) - .then(function() { - return cache.match(test_url); - }) - .then(function(result) { - assert_response_equals(result, response, - 'Cache.put should update the cache with ' + - 'new request and response.'); - return result.text(); - }) - .then(function(body) { - assert_equals(body, '', - 'Cache.put should store response body.'); - }); - }, 'Cache.put with HTTP 500 response'); - -cache_test(function(cache, test) { - var test_url = new URL('../resources/fetch-status.php?status=206', location.href).href; - var request = new Request(test_url); - var response; - return fetch(test_url) - .then(function(fetch_result) { - assert_equals(fetch_result.status, 206, - 'Test framework error: The status code should be 206.'); - response = fetch_result.clone(); - return promise_rejects(test, new TypeError, cache.put(request, fetch_result)); - }); - }, 'Cache.put with HTTP 206 response'); - -cache_test(function(cache) { - var alternate_response_body = 'New body'; - var alternate_response = new Response(alternate_response_body, - { statusText: 'New status' }); - return cache.put(new Request(test_url), - new Response('Old body', { statusText: 'Old status' })) - .then(function() { - return cache.put(new Request(test_url), alternate_response.clone()); - }) - .then(function() { - return cache.match(test_url); - }) - .then(function(result) { - assert_response_equals(result, alternate_response, - 'Cache.put should replace existing ' + - 'response with new response.'); - return result.text(); - }) - .then(function(body) { - assert_equals(body, alternate_response_body, - 'Cache put should store new response body.'); - }); - }, 'Cache.put called twice with matching Requests and different Responses'); - -cache_test(function(cache) { - var first_url = test_url; - var second_url = first_url + '#(O_o)'; - var alternate_response_body = 'New body'; - var alternate_response = new Response(alternate_response_body, - { statusText: 'New status' }); - return cache.put(new Request(first_url), - new Response('Old body', { statusText: 'Old status' })) - .then(function() { - return cache.put(new Request(second_url), alternate_response.clone()); - }) - .then(function() { - return cache.match(test_url); - }) - .then(function(result) { - assert_response_equals(result, alternate_response, - 'Cache.put should replace existing ' + - 'response with new response.'); - return result.text(); - }) - .then(function(body) { - assert_equals(body, alternate_response_body, - 'Cache put should store new response body.'); - }); - }, 'Cache.put called twice with request URLs that differ only by a fragment'); - -cache_test(function(cache) { - var url = 'http://example.com/foo'; - return cache.put(url, new Response('some body')) - .then(function() { return cache.match(url); }) - .then(function(response) { return response.text(); }) - .then(function(body) { - assert_equals(body, 'some body', - 'Cache.put should accept a string as request.'); - }); - }, 'Cache.put with a string request'); - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.put(new Request(test_url), 'Hello world!'), - 'Cache.put should only accept a Response object as the response.'); - }, 'Cache.put with an invalid response'); - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.put(new Request('file:///etc/passwd'), - new Response(test_body)), - 'Cache.put should reject non-HTTP/HTTPS requests with a TypeError.'); - }, 'Cache.put with a non-HTTP/HTTPS request'); - -cache_test(function(cache) { - var response = new Response(test_body); - return cache.put(new Request('relative-url'), response.clone()) - .then(function() { - return cache.match(new URL('relative-url', location.href).href); - }) - .then(function(result) { - assert_response_equals(result, response, - 'Cache.put should accept a relative URL ' + - 'as the request.'); - }); - }, 'Cache.put with a relative URL'); - -cache_test(function(cache, test) { - var request = new Request('http://example.com/foo', { method: 'HEAD' }); - return promise_rejects( - test, - new TypeError(), - cache.put(request, new Response(test_body)), - 'Cache.put should throw a TypeError for non-GET requests.'); - }, 'Cache.put with a non-GET request'); - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.put(new Request(test_url), null), - 'Cache.put should throw a TypeError for a null response.'); - }, 'Cache.put with a null response'); - -cache_test(function(cache, test) { - var request = new Request(test_url, {method: 'POST', body: test_body}); - return promise_rejects( - test, - new TypeError(), - cache.put(request, new Response(test_body)), - 'Cache.put should throw a TypeError for a POST request.'); - }, 'Cache.put with a POST request'); - -cache_test(function(cache) { - var response = new Response(test_body); - assert_false(response.bodyUsed, - '[https://fetch.spec.whatwg.org/#dom-body-bodyused] ' + - 'Response.bodyUsed should be initially false.'); - return response.text().then(function() { - assert_true( - response.bodyUsed, - '[https://fetch.spec.whatwg.org/#concept-body-consume-body] ' + - 'The text() method should make the body disturbed.'); - var request = new Request(test_url); - return cache.put(request, response).then(() => { - assert_unreached('cache.put should be rejected'); - }, () => {}); - }); - }, 'Cache.put with a used response body'); - -cache_test(function(cache) { - var response = new Response(test_body); - return cache.put(new Request(test_url), response) - .then(function() { - assert_throws(new TypeError(), () => response.body.getReader()); - }); - }, 'getReader() after Cache.put'); - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.put(new Request(test_url), - new Response(test_body, { headers: { VARY: '*' }})), - 'Cache.put should reject VARY:* Responses with a TypeError.'); - }, 'Cache.put with a VARY:* Response'); - -cache_test(function(cache, test) { - return promise_rejects( - test, - new TypeError(), - cache.put(new Request(test_url), - new Response(test_body, - { headers: { VARY: 'Accept-Language,*' }})), - 'Cache.put should reject Responses with an embedded VARY:* with a ' + - 'TypeError.'); - }, 'Cache.put with an embedded VARY:* Response'); - -done();
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage-keys.js b/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage-keys.js deleted file mode 100644 index ef06ccdf..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage-keys.js +++ /dev/null
@@ -1,35 +0,0 @@ -if (self.importScripts) { - importScripts('/resources/testharness.js'); - importScripts('../resources/test-helpers.js'); -} - -var test_cache_list = - ['', 'example', 'Another cache name', 'A', 'a', 'ex ample']; - -promise_test(function(test) { - return self.caches.keys() - .then(function(keys) { - assert_true(Array.isArray(keys), - 'CacheStorage.keys should return an Array.'); - return Promise.all(keys.map(function(key) { - return self.caches.delete(key); - })); - }) - .then(function() { - return Promise.all(test_cache_list.map(function(key) { - return self.caches.open(key); - })); - }) - - .then(function() { return self.caches.keys(); }) - .then(function(keys) { - assert_true(Array.isArray(keys), - 'CacheStorage.keys should return an Array.'); - assert_array_equals(keys, - test_cache_list, - 'CacheStorage.keys should only return ' + - 'existing caches.'); - }); - }, 'CacheStorage keys'); - -done();
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage-match.js b/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage-match.js deleted file mode 100644 index f6126f0..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage-match.js +++ /dev/null
@@ -1,243 +0,0 @@ -if (self.importScripts) { - importScripts('/resources/testharness.js'); - importScripts('../resources/test-helpers.js'); -} - -(function() { - var next_index = 1; - - // Returns a transaction (request, response, and url) for a unique URL. - function create_unique_transaction(test) { - var uniquifier = String(next_index++); - var url = 'http://example.com/' + uniquifier; - - return { - request: new Request(url), - response: new Response('hello'), - url: url - }; - } - - self.create_unique_transaction = create_unique_transaction; -})(); - -cache_test(function(cache) { - var transaction = create_unique_transaction(); - - return cache.put(transaction.request.clone(), transaction.response.clone()) - .then(function() { - return self.caches.match(transaction.request); - }) - .then(function(response) { - assert_response_equals(response, transaction.response, - 'The response should not have changed.'); - }); -}, 'CacheStorageMatch with no cache name provided'); - -cache_test(function(cache) { - var transaction = create_unique_transaction(); - - var test_cache_list = ['a', 'b', 'c']; - return cache.put(transaction.request.clone(), transaction.response.clone()) - .then(function() { - return Promise.all(test_cache_list.map(function(key) { - return self.caches.open(key); - })); - }) - .then(function() { - return self.caches.match(transaction.request); - }) - .then(function(response) { - assert_response_equals(response, transaction.response, - 'The response should not have changed.'); - }); -}, 'CacheStorageMatch from one of many caches'); - -promise_test(function(test) { - var transaction = create_unique_transaction(); - - var test_cache_list = ['x', 'y', 'z']; - return Promise.all(test_cache_list.map(function(key) { - return self.caches.open(key); - })) - .then(function() { return self.caches.open('x'); }) - .then(function(cache) { - return cache.put(transaction.request.clone(), - transaction.response.clone()); - }) - .then(function() { - return self.caches.match(transaction.request, {cacheName: 'x'}); - }) - .then(function(response) { - assert_response_equals(response, transaction.response, - 'The response should not have changed.'); - }) - .then(function() { - return self.caches.match(transaction.request, {cacheName: 'y'}); - }) - .then(function(response) { - assert_equals(response, undefined, - 'Cache y should not have a response for the request.'); - }); -}, 'CacheStorageMatch from one of many caches by name'); - -cache_test(function(cache) { - var transaction = create_unique_transaction(); - return cache.put(transaction.url, transaction.response.clone()) - .then(function() { - return self.caches.match(transaction.request); - }) - .then(function(response) { - assert_response_equals(response, transaction.response, - 'The response should not have changed.'); - }); -}, 'CacheStorageMatch a string request'); - -cache_test(function(cache) { - var transaction = create_unique_transaction(); - return cache.put(transaction.request.clone(), transaction.response.clone()) - .then(function() { - return self.caches.match(new Request(transaction.request.url, - {method: 'HEAD'})); - }) - .then(function(response) { - assert_equals(response, undefined, - 'A HEAD request should not be matched'); - }); -}, 'CacheStorageMatch a HEAD request'); - -promise_test(function(test) { - var transaction = create_unique_transaction(); - return self.caches.match(transaction.request) - .then(function(response) { - assert_equals(response, undefined, - 'The response should not be found.'); - }); -}, 'CacheStorageMatch with no cached entry'); - -promise_test(function(test) { - var transaction = create_unique_transaction(); - return self.caches.has('foo') - .then(function(has_foo) { - assert_false(has_foo, "The cache should not exist."); - return self.caches.match(transaction.request, {cacheName: 'foo'}); - }) - .then(function(response) { - assert_equals(response, undefined, - 'The match with bad cache name should resolve to ' + - 'undefined.'); - return self.caches.has('foo'); - }) - .then(function(has_foo) { - assert_false(has_foo, "The cache should still not exist."); - }); -}, 'CacheStorageMatch with no caches available but name provided'); - -cache_test(function(cache) { - var transaction = create_unique_transaction(); - - return self.caches.delete('') - .then(function() { - return self.caches.has(''); - }) - .then(function(has_cache) { - assert_false(has_cache, "The cache should not exist."); - return cache.put(transaction.request, transaction.response.clone()); - }) - .then(function() { - return self.caches.match(transaction.request, {cacheName: ''}); - }) - .then(function(response) { - assert_equals(response, undefined, - 'The response should not be found.'); - return self.caches.open(''); - }) - .then(function(cache) { - return cache.put(transaction.request, transaction.response); - }) - .then(function() { - return self.caches.match(transaction.request, {cacheName: ''}); - }) - .then(function(response) { - assert_response_equals(response, transaction.response, - 'The response should be matched.'); - return self.caches.delete(''); - }); -}, 'CacheStorageMatch with empty cache name provided'); - - -cache_test(function(cache) { - var request = new Request('http://example.com/?foo'); - var no_query_request = new Request('http://example.com/'); - var response = new Response('foo'); - return cache.put(request.clone(), response.clone()) - .then(function() { - return self.caches.match(no_query_request.clone()); - }) - .then(function(result) { - assert_equals( - result, undefined, - 'CacheStorageMatch should resolve as undefined with a ' + - 'mismatched query.'); - return self.caches.match(no_query_request.clone(), - {ignoreSearch: true}); - }) - .then(function(result) { - assert_response_equals( - result, response, - 'CacheStorageMatch with ignoreSearch should ignore the ' + - 'query of the request.'); - }); - }, 'CacheStorageMatch supports ignoreSearch'); - -cache_test(function(cache) { - var request = new Request('http://example.com/'); - var head_request = new Request('http://example.com/', {method: 'HEAD'}); - var response = new Response('foo'); - return cache.put(request.clone(), response.clone()) - .then(function() { - return self.caches.match(head_request.clone()); - }) - .then(function(result) { - assert_equals( - result, undefined, - 'CacheStorageMatch should resolve as undefined with a ' + - 'mismatched method.'); - return self.caches.match(head_request.clone(), - {ignoreMethod: true}); - }) - .then(function(result) { - assert_response_equals( - result, response, - 'CacheStorageMatch with ignoreMethod should ignore the ' + - 'method of request.'); - }); - }, 'Cache.match supports ignoreMethod'); - -cache_test(function(cache) { - var vary_request = new Request('http://example.com/c', - {headers: {'Cookies': 'is-for-cookie'}}); - var vary_response = new Response('', {headers: {'Vary': 'Cookies'}}); - var mismatched_vary_request = new Request('http://example.com/c'); - - return cache.put(vary_request.clone(), vary_response.clone()) - .then(function() { - return self.caches.match(mismatched_vary_request.clone()); - }) - .then(function(result) { - assert_equals( - result, undefined, - 'CacheStorageMatch should resolve as undefined with a ' + - ' mismatched vary.'); - return self.caches.match(mismatched_vary_request.clone(), - {ignoreVary: true}); - }) - .then(function(result) { - assert_response_equals( - result, vary_response, - 'CacheStorageMatch with ignoreVary should ignore the ' + - 'vary of request.'); - }); - }, 'CacheStorageMatch supports ignoreVary'); - -done();
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage.js b/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage.js deleted file mode 100644 index dd5e39d..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage.js +++ /dev/null
@@ -1,239 +0,0 @@ -if (self.importScripts) { - importScripts('/resources/testharness.js'); - importScripts('../resources/test-helpers.js'); -} - -promise_test(function(t) { - var cache_name = 'cache-storage/foo'; - return self.caches.delete(cache_name) - .then(function() { - return self.caches.open(cache_name); - }) - .then(function(cache) { - assert_true(cache instanceof Cache, - 'CacheStorage.open should return a Cache.'); - }); - }, 'CacheStorage.open'); - -promise_test(function(t) { - var cache_name = 'cache-storage/bar'; - var first_cache = null; - var second_cache = null; - return self.caches.open(cache_name) - .then(function(cache) { - first_cache = cache; - return self.caches.delete(cache_name); - }) - .then(function() { - return first_cache.add('../resources/simple.txt'); - }) - .then(function() { - return self.caches.keys(); - }) - .then(function(cache_names) { - assert_equals(cache_names.indexOf(cache_name), -1); - return self.caches.open(cache_name); - }) - .then(function(cache) { - second_cache = cache; - return second_cache.keys(); - }) - .then(function(keys) { - assert_equals(keys.length, 0); - return first_cache.keys(); - }) - .then(function(keys) { - assert_equals(keys.length, 1); - // Clean up - return self.caches.delete(cache_name); - }) - }, 'CacheStorage.delete dooms'); - -promise_test(function(t) { - // Note that this test may collide with other tests running in the same - // origin that also uses an empty cache name. - var cache_name = ''; - return self.caches.delete(cache_name) - .then(function() { - return self.caches.open(cache_name); - }) - .then(function(cache) { - assert_true(cache instanceof Cache, - 'CacheStorage.open should accept an empty name.'); - }); - }, 'CacheStorage.open with an empty name'); - -promise_test(function(t) { - return promise_rejects( - t, - new TypeError(), - self.caches.open(), - 'CacheStorage.open should throw TypeError if called with no arguments.'); - }, 'CacheStorage.open with no arguments'); - -promise_test(function(t) { - var test_cases = [ - { - name: 'cache-storage/lowercase', - should_not_match: - [ - 'cache-storage/Lowercase', - ' cache-storage/lowercase', - 'cache-storage/lowercase ' - ] - }, - { - name: 'cache-storage/has a space', - should_not_match: - [ - 'cache-storage/has' - ] - }, - { - name: 'cache-storage/has\000_in_the_name', - should_not_match: - [ - 'cache-storage/has', - 'cache-storage/has_in_the_name' - ] - } - ]; - return Promise.all(test_cases.map(function(testcase) { - var cache_name = testcase.name; - return self.caches.delete(cache_name) - .then(function() { - return self.caches.open(cache_name); - }) - .then(function() { - return self.caches.has(cache_name); - }) - .then(function(result) { - assert_true(result, - 'CacheStorage.has should return true for existing ' + - 'cache.'); - }) - .then(function() { - return Promise.all( - testcase.should_not_match.map(function(cache_name) { - return self.caches.has(cache_name) - .then(function(result) { - assert_false(result, - 'CacheStorage.has should only perform ' + - 'exact matches on cache names.'); - }); - })); - }) - .then(function() { - return self.caches.delete(cache_name); - }); - })); - }, 'CacheStorage.has with existing cache'); - -promise_test(function(t) { - return self.caches.has('cheezburger') - .then(function(result) { - assert_false(result, - 'CacheStorage.has should return false for ' + - 'nonexistent cache.'); - }); - }, 'CacheStorage.has with nonexistent cache'); - -promise_test(function(t) { - var cache_name = 'cache-storage/open'; - var cache; - return self.caches.delete(cache_name) - .then(function() { - return self.caches.open(cache_name); - }) - .then(function(result) { - cache = result; - }) - .then(function() { - return cache.add('../resources/simple.txt'); - }) - .then(function() { - return self.caches.open(cache_name); - }) - .then(function(result) { - assert_true(result instanceof Cache, - 'CacheStorage.open should return a Cache object'); - assert_not_equals(result, cache, - 'CacheStorage.open should return a new Cache ' + - 'object each time its called.'); - return Promise.all([cache.keys(), result.keys()]); - }) - .then(function(results) { - var expected_urls = results[0].map(function(r) { return r.url }); - var actual_urls = results[1].map(function(r) { return r.url }); - assert_array_equals(actual_urls, expected_urls, - 'CacheStorage.open should return a new Cache ' + - 'object for the same backing store.'); - }); - }, 'CacheStorage.open with existing cache'); - -promise_test(function(t) { - var cache_name = 'cache-storage/delete'; - - return self.caches.delete(cache_name) - .then(function() { - return self.caches.open(cache_name); - }) - .then(function() { return self.caches.delete(cache_name); }) - .then(function(result) { - assert_true(result, - 'CacheStorage.delete should return true after ' + - 'deleting an existing cache.'); - }) - - .then(function() { return self.caches.has(cache_name); }) - .then(function(cache_exists) { - assert_false(cache_exists, - 'CacheStorage.has should return false after ' + - 'fulfillment of CacheStorage.delete promise.'); - }); - }, 'CacheStorage.delete with existing cache'); - -promise_test(function(t) { - return self.caches.delete('cheezburger') - .then(function(result) { - assert_false(result, - 'CacheStorage.delete should return false for a ' + - 'nonexistent cache.'); - }); - }, 'CacheStorage.delete with nonexistent cache'); - -promise_test(function(t) { - var unpaired_name = 'unpaired\uD800'; - var converted_name = 'unpaired\uFFFD'; - - // The test assumes that a cache with converted_name does not - // exist, but if the implementation fails the test then such - // a cache will be created. Start off in a fresh state by - // deleting all caches. - return delete_all_caches() - .then(function() { - return self.caches.has(converted_name); - }) - .then(function(cache_exists) { - assert_false(cache_exists, - 'Test setup failure: cache should not exist'); - }) - .then(function() { return self.caches.open(unpaired_name); }) - .then(function() { return self.caches.keys(); }) - .then(function(keys) { - assert_true(keys.indexOf(unpaired_name) !== -1, - 'keys should include cache with bad name'); - }) - .then(function() { return self.caches.has(unpaired_name); }) - .then(function(cache_exists) { - assert_true(cache_exists, - 'CacheStorage names should be not be converted.'); - }) - .then(function() { return self.caches.has(converted_name); }) - .then(function(cache_exists) { - assert_false(cache_exists, - 'CacheStorage names should be not be converted.'); - }); - }, 'CacheStorage names are DOMStrings not USVStrings'); - -done();
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-add-expected.txt b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-add-expected.txt deleted file mode 100644 index 54eb6d6..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-add-expected.txt +++ /dev/null
@@ -1,22 +0,0 @@ -This is a testharness.js-based test. -PASS Cache.add and Cache.addAll -PASS Cache.add called with no arguments -PASS Cache.add called with relative URL specified as a string -PASS Cache.add called with non-HTTP/HTTPS URL -PASS Cache.add called with Request object -PASS Cache.add called with POST request -PASS Cache.add called twice with the same Request object -PASS Cache.add called with Request object with a used body -PASS Cache.add with request that results in a status of 404 -PASS Cache.add with request that results in a status of 500 -PASS Cache.add with request that results in a status of 206 -PASS Cache.addAll with request that results in a status of 206 -PASS Cache.addAll with no arguments -PASS Cache.addAll with a mix of valid and undefined arguments -PASS Cache.addAll with an empty array -PASS Cache.addAll with string URL arguments -PASS Cache.addAll with Request arguments -PASS Cache.addAll with a mix of succeeding and failing requests -FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-add.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-add.html deleted file mode 100644 index 2ab4623..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-add.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!DOCTYPE html> -<title>Cache.add and Cache.addAll</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-add"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../../serviceworker/resources/test-helpers.js"></script> -<script> -service_worker_test('../script-tests/cache-add.js'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-delete.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-delete.html deleted file mode 100644 index 39c6a6c..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-delete.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!DOCTYPE html> -<title>Cache.delete</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-delete"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../../serviceworker/resources/test-helpers.js"></script> -<script> -service_worker_test('../script-tests/cache-delete.js'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-keys.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-keys.html deleted file mode 100644 index 50361e617..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-keys.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!DOCTYPE html> -<title>Cache.keys</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-keys"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../../serviceworker/resources/test-helpers.js"></script> -<script> -service_worker_test('../script-tests/cache-keys.js'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-match.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-match.html deleted file mode 100644 index 15684e6..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-match.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!DOCTYPE html> -<title>Cache.match</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-match"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../../serviceworker/resources/test-helpers.js"></script> -<script> -service_worker_test('../script-tests/cache-match.js'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-matchAll-expected.txt b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-matchAll-expected.txt deleted file mode 100644 index 54610b7..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-matchAll-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -This is a testharness.js-based test. -PASS Cache.matchAll -PASS Cache.matchAll with no matching entries -PASS Cache.matchAll with URL -PASS Cache.matchAll with Request -PASS Cache.matchAll with new Request -PASS Cache.matchAll with HEAD -PASS Cache.matchAll with ignoreSearch option (request with no search parameters) -PASS Cache.matchAll with ignoreSearch option (request with search parameters) -PASS Cache.matchAll supports ignoreMethod -PASS Cache.matchAll supports ignoreVary -PASS Cache.matchAll with URL containing fragment -PASS Cache.matchAll with string fragment "http" as query -PASS Cache.matchAll without parameters -FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0 -FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1 -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-matchAll.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-matchAll.html deleted file mode 100644 index 1799c5f9..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-matchAll.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!DOCTYPE html> -<title>Cache.matchAll</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-matchall"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../../serviceworker/resources/test-helpers.js"></script> -<script> -service_worker_test('../script-tests/cache-matchAll.js'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-put.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-put.html deleted file mode 100644 index b2adbe5..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-put.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!DOCTYPE html> -<title>Cache.put</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-put"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../../serviceworker/resources/test-helpers.js"></script> -<script> -service_worker_test('../script-tests/cache-put.js'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-storage-expected.txt b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-storage-expected.txt deleted file mode 100644 index bcf4840..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-storage-expected.txt +++ /dev/null
@@ -1,14 +0,0 @@ -This is a testharness.js-based test. -PASS CacheStorage -PASS CacheStorage.open -PASS CacheStorage.delete dooms -PASS CacheStorage.open with an empty name -PASS CacheStorage.open with no arguments -PASS CacheStorage.has with existing cache -PASS CacheStorage.has with nonexistent cache -PASS CacheStorage.open with existing cache -PASS CacheStorage.delete with existing cache -PASS CacheStorage.delete with nonexistent cache -FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-storage-keys.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-storage-keys.html deleted file mode 100644 index f07531c..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-storage-keys.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!DOCTYPE html> -<title>CacheStorage.keys</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../../serviceworker/resources/test-helpers.js"></script> -<script> -service_worker_test('../script-tests/cache-storage-keys.js'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-storage-match.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-storage-match.html deleted file mode 100644 index b59dbe75..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-storage-match.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!DOCTYPE html> -<title>CacheStorage.match</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage-match"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../../serviceworker/resources/test-helpers.js"></script> -<script> -service_worker_test('../script-tests/cache-storage-match.js'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-storage.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-storage.html deleted file mode 100644 index ad2d06b..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/cache-storage.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!DOCTYPE html> -<title>CacheStorage</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../../serviceworker/resources/test-helpers.js"></script> -<script> -service_worker_test('../script-tests/cache-storage.js'); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/ignore-search-with-credentials.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/ignore-search-with-credentials.html index 79efb80..daefa60 100644 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/ignore-search-with-credentials.html +++ b/third_party/WebKit/LayoutTests/http/tests/cachestorage/serviceworker/ignore-search-with-credentials.html
@@ -2,7 +2,6 @@ <title>Cache Storage: ignore search with credentials</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="../resources/test-helpers.js"></script> <script src="../../serviceworker/resources/test-helpers.js"></script> <script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-add-expected.txt b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-add-expected.txt deleted file mode 100644 index 390c26d..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-add-expected.txt +++ /dev/null
@@ -1,21 +0,0 @@ -This is a testharness.js-based test. -PASS Cache.add called with no arguments -PASS Cache.add called with relative URL specified as a string -PASS Cache.add called with non-HTTP/HTTPS URL -PASS Cache.add called with Request object -PASS Cache.add called with POST request -PASS Cache.add called twice with the same Request object -PASS Cache.add called with Request object with a used body -PASS Cache.add with request that results in a status of 404 -PASS Cache.add with request that results in a status of 500 -PASS Cache.add with request that results in a status of 206 -PASS Cache.addAll with request that results in a status of 206 -PASS Cache.addAll with no arguments -PASS Cache.addAll with a mix of valid and undefined arguments -PASS Cache.addAll with an empty array -PASS Cache.addAll with string URL arguments -PASS Cache.addAll with Request arguments -PASS Cache.addAll with a mix of succeeding and failing requests -FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-add.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-add.html deleted file mode 100644 index 7688a70..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-add.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!DOCTYPE html> -<title>Cache Storage: Cache.add and Cache.addAll</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-add"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../resources/test-helpers.js"></script> -<script src="../script-tests/cache-add.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-delete.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-delete.html deleted file mode 100644 index a6476020..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-delete.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!DOCTYPE html> -<title>Cache Storage: Cache.delete</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-delete"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../resources/test-helpers.js"></script> -<script src="../script-tests/cache-delete.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-keys.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-keys.html deleted file mode 100644 index fce29ab..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-keys.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!DOCTYPE html> -<title>Cache.keys</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-keys"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../resources/test-helpers.js"></script> -<script src="../script-tests/cache-keys.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-match.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-match.html deleted file mode 100644 index 1b9cc21..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-match.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!DOCTYPE html> -<title>Cache Storage: Cache.match</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-match"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../resources/test-helpers.js"></script> -<script src="../script-tests/cache-match.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-matchAll-expected.txt b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-matchAll-expected.txt deleted file mode 100644 index c1f964f4..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-matchAll-expected.txt +++ /dev/null
@@ -1,17 +0,0 @@ -This is a testharness.js-based test. -PASS Cache.matchAll with no matching entries -PASS Cache.matchAll with URL -PASS Cache.matchAll with Request -PASS Cache.matchAll with new Request -PASS Cache.matchAll with HEAD -PASS Cache.matchAll with ignoreSearch option (request with no search parameters) -PASS Cache.matchAll with ignoreSearch option (request with search parameters) -PASS Cache.matchAll supports ignoreMethod -PASS Cache.matchAll supports ignoreVary -PASS Cache.matchAll with URL containing fragment -PASS Cache.matchAll with string fragment "http" as query -PASS Cache.matchAll without parameters -FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0 -FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1 -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-matchAll.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-matchAll.html deleted file mode 100644 index 835bbdfa..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-matchAll.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!DOCTYPE html> -<title>Cache Storage: Cache.matchAll</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-matchall"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../resources/test-helpers.js"></script> -<script src="../script-tests/cache-matchAll.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-put.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-put.html deleted file mode 100644 index 54215f4..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-put.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!DOCTYPE html> -<title>Cache Storage: Cache.put</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-put"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../resources/test-helpers.js"></script> -<script src="../script-tests/cache-put.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-storage-expected.txt b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-storage-expected.txt deleted file mode 100644 index 636c290..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-storage-expected.txt +++ /dev/null
@@ -1,13 +0,0 @@ -This is a testharness.js-based test. -PASS CacheStorage.open -PASS CacheStorage.delete dooms -PASS CacheStorage.open with an empty name -PASS CacheStorage.open with no arguments -PASS CacheStorage.has with existing cache -PASS CacheStorage.has with nonexistent cache -PASS CacheStorage.open with existing cache -PASS CacheStorage.delete with existing cache -PASS CacheStorage.delete with nonexistent cache -FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-storage-keys.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-storage-keys.html deleted file mode 100644 index d92baa1..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-storage-keys.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!DOCTYPE html> -<title>Cache Storage: CacheStorage.keys</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../resources/test-helpers.js"></script> -<script src="../script-tests/cache-storage-keys.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-storage-match.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-storage-match.html deleted file mode 100644 index 453f90f..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-storage-match.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!DOCTYPE html> -<title>Cache Storage: CacheStorage.match</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage-match"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../resources/test-helpers.js"></script> -<script src="../script-tests/cache-storage-match.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-storage.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-storage.html deleted file mode 100644 index d27206b..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/cache-storage.html +++ /dev/null
@@ -1,7 +0,0 @@ -<!DOCTYPE html> -<title>Cache Storage: CacheStorage</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="../resources/test-helpers.js"></script> -<script src="../script-tests/cache-storage.js"></script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/sandboxed-iframes-expected.txt b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/sandboxed-iframes-expected.txt deleted file mode 100644 index c7f21fea..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/sandboxed-iframes-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ - -This is a testharness.js-based test. -PASS Sandboxed iframe with allow-same-origin is allowed access -FAIL Sandboxed iframe without allow-same-origin is denied access assert_equals: Access should be denied if sandbox lacks allow-same-origin expected "denied" but got "unexpecteddenied" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/sandboxed-iframes.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/sandboxed-iframes.html deleted file mode 100644 index 37dceeb9f..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/window/sandboxed-iframes.html +++ /dev/null
@@ -1,65 +0,0 @@ -<!DOCTYPE html> -<title>Cache Storage: Verify access in sandboxed iframes</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> - -function load_iframe(src, sandbox) { - return new Promise(function(resolve, reject) { - var iframe = document.createElement('iframe'); - iframe.onload = function() { resolve(iframe); }; - - iframe.sandbox = sandbox; - iframe.src = src; - - document.documentElement.appendChild(iframe); - }); -} - -function wait_for_message(id) { - return new Promise(function(resolve) { - self.addEventListener('message', function listener(e) { - if (e.data.id === id) { - resolve(e.data); - self.removeEventListener('message', listener); - } - }); - }); -} - -var counter = 0; - -promise_test(function(t) { - return load_iframe('../resources/iframe.html', - 'allow-scripts allow-same-origin') - .then(function(iframe) { - var id = ++counter; - iframe.contentWindow.postMessage({id: id}, '*'); - return wait_for_message(id); - }) - .then(function(message) { - assert_equals( - message.result, 'allowed', - 'Access should be allowed if sandbox has allow-same-origin'); - }); -}, 'Sandboxed iframe with allow-same-origin is allowed access'); - -promise_test(function(t) { - return load_iframe('../resources/iframe.html', - 'allow-scripts') - .then(function(iframe) { - var id = ++counter; - iframe.contentWindow.postMessage({id: id}, '*'); - return wait_for_message(id); - }) - .then(function(message) { - assert_equals( - message.result, 'denied', - 'Access should be denied if sandbox lacks allow-same-origin'); - assert_equals(message.name, 'SecurityError', - 'Failure should be a SecurityError'); - }); -}, 'Sandboxed iframe without allow-same-origin is denied access'); - -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-add-expected.txt b/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-add-expected.txt deleted file mode 100644 index 390c26d..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-add-expected.txt +++ /dev/null
@@ -1,21 +0,0 @@ -This is a testharness.js-based test. -PASS Cache.add called with no arguments -PASS Cache.add called with relative URL specified as a string -PASS Cache.add called with non-HTTP/HTTPS URL -PASS Cache.add called with Request object -PASS Cache.add called with POST request -PASS Cache.add called twice with the same Request object -PASS Cache.add called with Request object with a used body -PASS Cache.add with request that results in a status of 404 -PASS Cache.add with request that results in a status of 500 -PASS Cache.add with request that results in a status of 206 -PASS Cache.addAll with request that results in a status of 206 -PASS Cache.addAll with no arguments -PASS Cache.addAll with a mix of valid and undefined arguments -PASS Cache.addAll with an empty array -PASS Cache.addAll with string URL arguments -PASS Cache.addAll with Request arguments -PASS Cache.addAll with a mix of succeeding and failing requests -FAIL Cache.addAll called with the same Request object specified twice assert_unreached: Should have rejected: Cache.addAll should throw InvalidStateError if the same request is added twice. Reached unreachable code -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-add.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-add.html deleted file mode 100644 index b6aa9da..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-add.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!DOCTYPE html> -<title>Cache.add and Cache.addAll</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-add"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> -fetch_tests_from_worker(new Worker('../script-tests/cache-add.js')); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-delete.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-delete.html deleted file mode 100644 index 902be7e..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-delete.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!DOCTYPE html> -<title>Cache.delete</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-delete"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> -fetch_tests_from_worker(new Worker('../script-tests/cache-delete.js')); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-match.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-match.html deleted file mode 100644 index 158de35..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-match.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!DOCTYPE html> -<title>Cache.match</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-match"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> -fetch_tests_from_worker(new Worker('../script-tests/cache-match.js')); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-matchAll-expected.txt b/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-matchAll-expected.txt deleted file mode 100644 index c1f964f4..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-matchAll-expected.txt +++ /dev/null
@@ -1,17 +0,0 @@ -This is a testharness.js-based test. -PASS Cache.matchAll with no matching entries -PASS Cache.matchAll with URL -PASS Cache.matchAll with Request -PASS Cache.matchAll with new Request -PASS Cache.matchAll with HEAD -PASS Cache.matchAll with ignoreSearch option (request with no search parameters) -PASS Cache.matchAll with ignoreSearch option (request with search parameters) -PASS Cache.matchAll supports ignoreMethod -PASS Cache.matchAll supports ignoreVary -PASS Cache.matchAll with URL containing fragment -PASS Cache.matchAll with string fragment "http" as query -PASS Cache.matchAll without parameters -FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0 -FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1 -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-matchAll.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-matchAll.html deleted file mode 100644 index 673c73d5..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-matchAll.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!DOCTYPE html> -<title>Cache.matchAll</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-matchall"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> -fetch_tests_from_worker(new Worker('../script-tests/cache-matchAll.js')); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-put.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-put.html deleted file mode 100644 index ea242db6..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-put.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!DOCTYPE html> -<title>Cache.put</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-put"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> -fetch_tests_from_worker(new Worker('../script-tests/cache-put.js')); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-storage-expected.txt b/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-storage-expected.txt deleted file mode 100644 index 636c290..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-storage-expected.txt +++ /dev/null
@@ -1,13 +0,0 @@ -This is a testharness.js-based test. -PASS CacheStorage.open -PASS CacheStorage.delete dooms -PASS CacheStorage.open with an empty name -PASS CacheStorage.open with no arguments -PASS CacheStorage.has with existing cache -PASS CacheStorage.has with nonexistent cache -PASS CacheStorage.open with existing cache -PASS CacheStorage.delete with existing cache -PASS CacheStorage.delete with nonexistent cache -FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-storage-keys.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-storage-keys.html deleted file mode 100644 index 9f34f5a..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-storage-keys.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!DOCTYPE html> -<title>CacheStorage.keys</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> -fetch_tests_from_worker(new Worker('../script-tests/cache-storage-keys.js')); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-storage-match.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-storage-match.html deleted file mode 100644 index 9d2d47b..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-storage-match.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!DOCTYPE html> -<title>CacheStorage.match</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage-match"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> -fetch_tests_from_worker(new Worker('../script-tests/cache-storage-match.js')); -</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-storage.html b/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-storage.html deleted file mode 100644 index 4162824..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/worker/cache-storage.html +++ /dev/null
@@ -1,8 +0,0 @@ -<!DOCTYPE html> -<title>CacheStorage</title> -<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script> -fetch_tests_from_worker(new Worker('../script-tests/cache-storage.js')); -</script>
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-aggregated-details-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-aggregated-details-expected.txt index c25824f8..a35a8b4 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-aggregated-details-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-aggregated-details-expected.txt
@@ -1,62 +1,6 @@ CallTree Group by: None - a: 0.000 11.125 - b: 0.000 11.125 - c: 8.250 8.250 - e: 0.000 2.875 - g: 2.875 2.875 - sin: 0.000 9.875 - f: 0.000 9.875 - l: 0.000 9.875 - a: 9.875 9.875 - x: 0.000 1.000 - y: 0.600 1.000 - z: 0.000 0.200 - w: 0.200 0.200 - w: 0.200 0.200 - recursive_a: 0.101 0.215 - recursive_b: 0.102 0.114 - recursive_a: 0.004 0.012 - recursive_b: 0.008 0.008 - f: 0.000 0.125 - l: 0.000 0.125 - a: 0.025 0.125 - Layout: 0.100 0.100 - -BottomUp Group by: None - a: 9.900 21.125 - l: 9.900 10.000 - f: 9.900 10.000 - sin: 9.875 9.875 - c: 8.250 8.250 - b: 8.250 8.250 - a: 8.250 8.250 - g: 2.875 2.875 - e: 2.875 2.875 - b: 2.875 2.875 - a: 2.875 2.875 - y: 0.600 1.000 - x: 0.600 1.000 - w: 0.400 0.400 - z: 0.200 0.200 - y: 0.200 0.200 - x: 0.200 0.200 - y: 0.200 0.200 - x: 0.200 0.200 - recursive_b: 0.110 0.114 - recursive_a: 0.110 0.114 - recursive_b: 0.008 0.008 - recursive_a: 0.008 0.008 - recursive_a: 0.105 0.215 - recursive_b: 0.004 0.012 - recursive_a: 0.004 0.012 - Layout: 0.100 0.100 - a: 0.100 0.100 - l: 0.100 0.100 - f: 0.100 0.100 - -CallTree Group by: EventName - JavaScript: 0.101 22.340 + Function Call: 17.660 40.000 a: 0.000 11.125 b: 0.000 11.125 c: 8.250 8.250 @@ -70,352 +14,544 @@ f: 0.000 9.875 l: 0.000 9.875 a: 9.875 9.875 - x: 0.000 1.000 - y: 0.600 1.000 - z: 0.000 0.200 + Function Call: 0.000 1.000 + x: 0.000 1.000 + y: 0.600 1.000 + z: 0.000 0.200 + w: 0.200 0.200 w: 0.200 0.200 - w: 0.200 0.200 recursive_a: 0.101 0.215 recursive_b: 0.102 0.114 recursive_a: 0.004 0.012 recursive_b: 0.008 0.008 +BottomUp Group by: None + Function Call: 17.660 40.000 + Function Call: 0.000 1.000 + a: 9.900 21.125 + Function Call: 0.000 11.125 + l: 9.900 10.000 + f: 9.900 10.000 + Function Call: 0.025 0.125 + sin: 9.875 9.875 + Function Call: 9.875 9.875 + c: 8.250 8.250 + b: 8.250 8.250 + a: 8.250 8.250 + Function Call: 8.250 8.250 + g: 2.875 2.875 + e: 2.875 2.875 + b: 2.875 2.875 + a: 2.875 2.875 + Function Call: 2.875 2.875 + y: 0.600 1.000 + x: 0.600 1.000 + Function Call: 0.600 1.000 + Function Call: 0.600 1.000 + w: 0.400 0.400 + z: 0.200 0.200 + y: 0.200 0.200 + x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 + y: 0.200 0.200 + x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 + recursive_b: 0.110 0.114 + recursive_a: 0.110 0.114 + recursive_b: 0.008 0.008 + recursive_a: 0.008 0.008 + Function Call: 0.008 0.008 + Function Call: 0.102 0.106 + recursive_a: 0.105 0.215 + recursive_b: 0.004 0.012 + recursive_a: 0.004 0.012 + Function Call: 0.004 0.012 + Function Call: 0.101 0.203 + Layout: 0.100 0.100 + a: 0.100 0.100 + l: 0.100 0.100 + f: 0.100 0.100 + Function Call: 0.100 0.100 + +CallTree Group by: EventName + Function Call: 17.660 40.000 + Function Call: 17.660 40.000 + a: 0.000 11.125 + b: 0.000 11.125 + c: 8.250 8.250 + e: 0.000 2.875 + g: 2.875 2.875 + f: 0.000 0.125 + l: 0.000 0.125 + a: 0.025 0.125 + Layout: 0.100 0.100 + sin: 0.000 9.875 + f: 0.000 9.875 + l: 0.000 9.875 + a: 9.875 9.875 + Function Call: 0.000 1.000 + x: 0.000 1.000 + y: 0.600 1.000 + z: 0.000 0.200 + w: 0.200 0.200 + w: 0.200 0.200 + recursive_a: 0.101 0.215 + recursive_b: 0.102 0.114 + recursive_a: 0.004 0.012 + recursive_b: 0.008 0.008 + BottomUp Group by: EventName JavaScript: 22.240 22.240 c: 8.250 8.250 b: 8.250 8.250 a: 8.250 8.250 + Function Call: 8.250 8.250 a: 9.900 21.125 + Function Call: 0.000 11.125 l: 9.900 10.000 f: 9.900 10.000 + Function Call: 0.025 0.125 sin: 9.875 9.875 + Function Call: 9.875 9.875 g: 2.875 2.875 e: 2.875 2.875 b: 2.875 2.875 a: 2.875 2.875 + Function Call: 2.875 2.875 w: 0.400 0.400 z: 0.200 0.200 y: 0.200 0.200 x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 y: 0.200 0.200 x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 y: 0.600 1.000 x: 0.600 1.000 + Function Call: 0.600 1.000 + Function Call: 0.600 1.000 recursive_b: 0.110 0.114 recursive_a: 0.110 0.114 recursive_b: 0.008 0.008 recursive_a: 0.008 0.008 + Function Call: 0.008 0.008 + Function Call: 0.102 0.106 recursive_a: 0.105 0.215 recursive_b: 0.004 0.012 recursive_a: 0.004 0.012 + Function Call: 0.004 0.012 + Function Call: 0.101 0.203 + Function Call: 17.660 17.660 + Function Call: 17.660 40.000 + Function Call: 0.000 1.000 Layout: 0.100 0.100 Layout: 0.100 0.100 a: 0.100 0.100 l: 0.100 0.100 f: 0.100 0.100 + Function Call: 0.100 0.100 CallTree Group by: Category - Scripting: 0.101 22.340 - a: 0.000 11.125 - b: 0.000 11.125 - c: 8.250 8.250 - e: 0.000 2.875 - g: 2.875 2.875 - f: 0.000 0.125 - l: 0.000 0.125 - a: 0.025 0.125 - Layout: 0.100 0.100 - sin: 0.000 9.875 - f: 0.000 9.875 - l: 0.000 9.875 - a: 9.875 9.875 - x: 0.000 1.000 - y: 0.600 1.000 - z: 0.000 0.200 - w: 0.200 0.200 - w: 0.200 0.200 - recursive_a: 0.101 0.215 - recursive_b: 0.102 0.114 - recursive_a: 0.004 0.012 - recursive_b: 0.008 0.008 + Scripting: 17.660 40.000 + Function Call: 17.660 40.000 + a: 0.000 11.125 + b: 0.000 11.125 + c: 8.250 8.250 + e: 0.000 2.875 + g: 2.875 2.875 + f: 0.000 0.125 + l: 0.000 0.125 + a: 0.025 0.125 + Layout: 0.100 0.100 + sin: 0.000 9.875 + f: 0.000 9.875 + l: 0.000 9.875 + a: 9.875 9.875 + Function Call: 0.000 1.000 + x: 0.000 1.000 + y: 0.600 1.000 + z: 0.000 0.200 + w: 0.200 0.200 + w: 0.200 0.200 + recursive_a: 0.101 0.215 + recursive_b: 0.102 0.114 + recursive_a: 0.004 0.012 + recursive_b: 0.008 0.008 BottomUp Group by: Category - Scripting: 22.240 22.240 + Scripting: 39.900 39.900 c: 8.250 8.250 b: 8.250 8.250 a: 8.250 8.250 + Function Call: 8.250 8.250 a: 9.900 21.125 + Function Call: 0.000 11.125 l: 9.900 10.000 f: 9.900 10.000 + Function Call: 0.025 0.125 sin: 9.875 9.875 + Function Call: 9.875 9.875 g: 2.875 2.875 e: 2.875 2.875 b: 2.875 2.875 a: 2.875 2.875 + Function Call: 2.875 2.875 + Function Call: 17.660 40.000 + Function Call: 0.000 1.000 w: 0.400 0.400 z: 0.200 0.200 y: 0.200 0.200 x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 y: 0.200 0.200 x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 y: 0.600 1.000 x: 0.600 1.000 + Function Call: 0.600 1.000 + Function Call: 0.600 1.000 recursive_b: 0.110 0.114 recursive_a: 0.110 0.114 recursive_b: 0.008 0.008 recursive_a: 0.008 0.008 + Function Call: 0.008 0.008 + Function Call: 0.102 0.106 recursive_a: 0.105 0.215 recursive_b: 0.004 0.012 recursive_a: 0.004 0.012 + Function Call: 0.004 0.012 + Function Call: 0.101 0.203 Rendering: 0.100 0.100 Layout: 0.100 0.100 a: 0.100 0.100 l: 0.100 0.100 f: 0.100 0.100 + Function Call: 0.100 0.100 CallTree Group by: Domain - unattributed: 0.000 12.250 - a: 0.000 11.125 - b: 0.000 11.125 - c: 8.250 8.250 - e: 0.000 2.875 - g: 2.875 2.875 - f: 0.000 0.125 - l: 0.000 0.125 - a: 0.025 0.125 - Layout: 0.100 0.100 - x: 0.000 1.000 - y: 0.600 1.000 - z: 0.000 0.200 - w: 0.200 0.200 - w: 0.200 0.200 - [V8 Runtime]: 0.000 9.875 - sin: 0.000 9.875 - f: 0.000 9.875 - l: 0.000 9.875 - a: 9.875 9.875 - abc.com: 0.101 0.215 - recursive_a: 0.101 0.215 - recursive_b: 0.102 0.114 - recursive_a: 0.004 0.012 - recursive_b: 0.008 0.008 + unattributed: 17.660 40.000 + Function Call: 17.660 40.000 + a: 0.000 11.125 + b: 0.000 11.125 + c: 8.250 8.250 + e: 0.000 2.875 + g: 2.875 2.875 + f: 0.000 0.125 + l: 0.000 0.125 + a: 0.025 0.125 + Layout: 0.100 0.100 + sin: 0.000 9.875 + f: 0.000 9.875 + l: 0.000 9.875 + a: 9.875 9.875 + Function Call: 0.000 1.000 + x: 0.000 1.000 + y: 0.600 1.000 + z: 0.000 0.200 + w: 0.200 0.200 + w: 0.200 0.200 + recursive_a: 0.101 0.215 + recursive_b: 0.102 0.114 + recursive_a: 0.004 0.012 + recursive_b: 0.008 0.008 BottomUp Group by: Domain - unattributed: 22.125 22.125 + unattributed: 39.785 39.785 c: 8.250 8.250 b: 8.250 8.250 a: 8.250 8.250 + Function Call: 8.250 8.250 a: 9.900 21.125 + Function Call: 0.000 11.125 l: 9.900 10.000 f: 9.900 10.000 + Function Call: 0.025 0.125 sin: 9.875 9.875 + Function Call: 9.875 9.875 g: 2.875 2.875 e: 2.875 2.875 b: 2.875 2.875 a: 2.875 2.875 + Function Call: 2.875 2.875 Layout: 0.100 0.100 a: 0.100 0.100 l: 0.100 0.100 f: 0.100 0.100 + Function Call: 0.100 0.100 + Function Call: 17.660 40.000 + Function Call: 0.000 1.000 w: 0.400 0.400 z: 0.200 0.200 y: 0.200 0.200 x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 y: 0.200 0.200 x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 y: 0.600 1.000 x: 0.600 1.000 + Function Call: 0.600 1.000 + Function Call: 0.600 1.000 abc.com: 0.215 0.215 recursive_b: 0.110 0.114 recursive_a: 0.110 0.114 recursive_b: 0.008 0.008 recursive_a: 0.008 0.008 + Function Call: 0.008 0.008 + Function Call: 0.102 0.106 recursive_a: 0.105 0.215 recursive_b: 0.004 0.012 recursive_a: 0.004 0.012 + Function Call: 0.004 0.012 + Function Call: 0.101 0.203 CallTree Group by: Subdomain - unattributed: 0.000 12.250 - a: 0.000 11.125 - b: 0.000 11.125 - c: 8.250 8.250 - e: 0.000 2.875 - g: 2.875 2.875 - f: 0.000 0.125 - l: 0.000 0.125 - a: 0.025 0.125 - Layout: 0.100 0.100 - x: 0.000 1.000 - y: 0.600 1.000 - z: 0.000 0.200 - w: 0.200 0.200 - w: 0.200 0.200 - [V8 Runtime]: 0.000 9.875 - sin: 0.000 9.875 - f: 0.000 9.875 - l: 0.000 9.875 - a: 9.875 9.875 - xyz.abc.com: 0.101 0.215 - recursive_a: 0.101 0.215 - recursive_b: 0.102 0.114 - recursive_a: 0.004 0.012 - recursive_b: 0.008 0.008 + unattributed: 17.660 40.000 + Function Call: 17.660 40.000 + a: 0.000 11.125 + b: 0.000 11.125 + c: 8.250 8.250 + e: 0.000 2.875 + g: 2.875 2.875 + f: 0.000 0.125 + l: 0.000 0.125 + a: 0.025 0.125 + Layout: 0.100 0.100 + sin: 0.000 9.875 + f: 0.000 9.875 + l: 0.000 9.875 + a: 9.875 9.875 + Function Call: 0.000 1.000 + x: 0.000 1.000 + y: 0.600 1.000 + z: 0.000 0.200 + w: 0.200 0.200 + w: 0.200 0.200 + recursive_a: 0.101 0.215 + recursive_b: 0.102 0.114 + recursive_a: 0.004 0.012 + recursive_b: 0.008 0.008 BottomUp Group by: Subdomain - unattributed: 22.125 22.125 + unattributed: 39.785 39.785 c: 8.250 8.250 b: 8.250 8.250 a: 8.250 8.250 + Function Call: 8.250 8.250 a: 9.900 21.125 + Function Call: 0.000 11.125 l: 9.900 10.000 f: 9.900 10.000 + Function Call: 0.025 0.125 sin: 9.875 9.875 + Function Call: 9.875 9.875 g: 2.875 2.875 e: 2.875 2.875 b: 2.875 2.875 a: 2.875 2.875 + Function Call: 2.875 2.875 Layout: 0.100 0.100 a: 0.100 0.100 l: 0.100 0.100 f: 0.100 0.100 + Function Call: 0.100 0.100 + Function Call: 17.660 40.000 + Function Call: 0.000 1.000 w: 0.400 0.400 z: 0.200 0.200 y: 0.200 0.200 x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 y: 0.200 0.200 x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 y: 0.600 1.000 x: 0.600 1.000 + Function Call: 0.600 1.000 + Function Call: 0.600 1.000 xyz.abc.com: 0.215 0.215 recursive_b: 0.110 0.114 recursive_a: 0.110 0.114 recursive_b: 0.008 0.008 recursive_a: 0.008 0.008 + Function Call: 0.008 0.008 + Function Call: 0.102 0.106 recursive_a: 0.105 0.215 recursive_b: 0.004 0.012 recursive_a: 0.004 0.012 + Function Call: 0.004 0.012 + Function Call: 0.101 0.203 CallTree Group by: URL - unattributed: 0.000 12.250 - a: 0.000 11.125 - b: 0.000 11.125 - c: 8.250 8.250 - e: 0.000 2.875 - g: 2.875 2.875 - f: 0.000 0.125 - l: 0.000 0.125 - a: 0.025 0.125 - Layout: 0.100 0.100 - x: 0.000 1.000 - y: 0.600 1.000 - z: 0.000 0.200 - w: 0.200 0.200 - w: 0.200 0.200 - native math.js: 0.000 9.875 - sin: 0.000 9.875 - f: 0.000 9.875 - l: 0.000 9.875 - a: 9.875 9.875 - http://xyz.abc.com/rec.js: 0.101 0.215 - recursive_a: 0.101 0.215 - recursive_b: 0.102 0.114 - recursive_a: 0.004 0.012 - recursive_b: 0.008 0.008 + unattributed: 17.660 40.000 + Function Call: 17.660 40.000 + a: 0.000 11.125 + b: 0.000 11.125 + c: 8.250 8.250 + e: 0.000 2.875 + g: 2.875 2.875 + f: 0.000 0.125 + l: 0.000 0.125 + a: 0.025 0.125 + Layout: 0.100 0.100 + sin: 0.000 9.875 + f: 0.000 9.875 + l: 0.000 9.875 + a: 9.875 9.875 + Function Call: 0.000 1.000 + x: 0.000 1.000 + y: 0.600 1.000 + z: 0.000 0.200 + w: 0.200 0.200 + w: 0.200 0.200 + recursive_a: 0.101 0.215 + recursive_b: 0.102 0.114 + recursive_a: 0.004 0.012 + recursive_b: 0.008 0.008 BottomUp Group by: URL - unattributed: 22.125 22.125 + unattributed: 39.785 39.785 c: 8.250 8.250 b: 8.250 8.250 a: 8.250 8.250 + Function Call: 8.250 8.250 a: 9.900 21.125 + Function Call: 0.000 11.125 l: 9.900 10.000 f: 9.900 10.000 + Function Call: 0.025 0.125 sin: 9.875 9.875 + Function Call: 9.875 9.875 g: 2.875 2.875 e: 2.875 2.875 b: 2.875 2.875 a: 2.875 2.875 + Function Call: 2.875 2.875 Layout: 0.100 0.100 a: 0.100 0.100 l: 0.100 0.100 f: 0.100 0.100 + Function Call: 0.100 0.100 + Function Call: 17.660 40.000 + Function Call: 0.000 1.000 w: 0.400 0.400 z: 0.200 0.200 y: 0.200 0.200 x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 y: 0.200 0.200 x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 y: 0.600 1.000 x: 0.600 1.000 + Function Call: 0.600 1.000 + Function Call: 0.600 1.000 http://xyz.abc.com/rec.js: 0.215 0.215 recursive_b: 0.110 0.114 recursive_a: 0.110 0.114 recursive_b: 0.008 0.008 recursive_a: 0.008 0.008 + Function Call: 0.008 0.008 + Function Call: 0.102 0.106 recursive_a: 0.105 0.215 recursive_b: 0.004 0.012 recursive_a: 0.004 0.012 + Function Call: 0.004 0.012 + Function Call: 0.101 0.203 CallTree Group by: Frame - subframe-url1: 0.000 21.125 - a: 0.000 11.125 - b: 0.000 11.125 - c: 8.250 8.250 - e: 0.000 2.875 - g: 2.875 2.875 - f: 0.000 0.125 - l: 0.000 0.125 - a: 0.025 0.125 - Layout: 0.100 0.100 - sin: 0.000 9.875 - f: 0.000 9.875 - l: 0.000 9.875 - a: 9.875 9.875 - subframe-url3: 0.101 1.215 - x: 0.000 1.000 - y: 0.600 1.000 - z: 0.000 0.200 - w: 0.200 0.200 - w: 0.200 0.200 - recursive_a: 0.101 0.215 - recursive_b: 0.102 0.114 - recursive_a: 0.004 0.012 - recursive_b: 0.008 0.008 + subframe-url1: 8.875 30.000 + Function Call: 8.875 30.000 + a: 0.000 11.125 + b: 0.000 11.125 + c: 8.250 8.250 + e: 0.000 2.875 + g: 2.875 2.875 + f: 0.000 0.125 + l: 0.000 0.125 + a: 0.025 0.125 + Layout: 0.100 0.100 + sin: 0.000 9.875 + f: 0.000 9.875 + l: 0.000 9.875 + a: 9.875 9.875 + subframe-url3: 8.785 10.000 + Function Call: 8.785 10.000 + Function Call: 0.000 1.000 + x: 0.000 1.000 + y: 0.600 1.000 + z: 0.000 0.200 + w: 0.200 0.200 + w: 0.200 0.200 + recursive_a: 0.101 0.215 + recursive_b: 0.102 0.114 + recursive_a: 0.004 0.012 + recursive_b: 0.008 0.008 BottomUp Group by: Frame - subframe-url1: 21.025 21.025 + subframe-url1: 38.685 38.685 c: 8.250 8.250 b: 8.250 8.250 a: 8.250 8.250 + Function Call: 8.250 8.250 a: 9.900 21.125 + Function Call: 0.000 11.125 l: 9.900 10.000 f: 9.900 10.000 + Function Call: 0.025 0.125 sin: 9.875 9.875 + Function Call: 9.875 9.875 g: 2.875 2.875 e: 2.875 2.875 b: 2.875 2.875 a: 2.875 2.875 + Function Call: 2.875 2.875 + Function Call: 17.660 40.000 + Function Call: 0.000 1.000 subframe-url3: 1.215 1.215 w: 0.400 0.400 z: 0.200 0.200 y: 0.200 0.200 x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 y: 0.200 0.200 x: 0.200 0.200 + Function Call: 0.200 0.200 + Function Call: 0.200 0.200 y: 0.600 1.000 x: 0.600 1.000 + Function Call: 0.600 1.000 + Function Call: 0.600 1.000 recursive_b: 0.110 0.114 recursive_a: 0.110 0.114 recursive_b: 0.008 0.008 recursive_a: 0.008 0.008 + Function Call: 0.008 0.008 + Function Call: 0.102 0.106 recursive_a: 0.105 0.215 recursive_b: 0.004 0.012 recursive_a: 0.004 0.012 + Function Call: 0.004 0.012 + Function Call: 0.101 0.203 "subframe-name2": 0.100 0.100 Layout: 0.100 0.100 a: 0.100 0.100 l: 0.100 0.100 f: 0.100 0.100 + Function Call: 0.100 0.100 EventLog Function Call: 8.875 30.000
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/masking-clipping-hidpi-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/masking-clipping-hidpi-expected.txt index 14c0dd1..552422a1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/masking-clipping-hidpi-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/masking-clipping-hidpi-expected.txt
@@ -5,18 +5,18 @@ LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGResourceMasker {mask} [id="textMask"] [maskUnits=objectBoundingBox] [maskContentUnits=userSpaceOnUse] LayoutSVGRect {rect} at (0,0) size 800x600 [fill={[type=SOLID] [color=#FFFFFF]}] [x=0.00] [y=0.00] [width=800.00] [height=600.00] - LayoutSVGText {text} at (0,-2) size 164.86x18 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (0,-2) size 164.86x18 + LayoutSVGText {text} at (0,-2.50) size 164.86x18.50 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (0,-2.50) size 164.86x18.50 chunk 1 text run 1 at (0.00,12.00) startOffset 0 endOffset 26 width 164.87: "This text should be sharp." LayoutSVGRect {rect} at (0,0) size 200x100 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=200.00] [height=100.00] LayoutSVGRect {rect} at (0,0) size 200x100 [fill={[type=SOLID] [color=#FFFFFF]}] [x=0.00] [y=0.00] [width=200.00] [height=100.00] - [masker="textMask"] LayoutSVGResourceMasker {mask} at (0,-2) size 220x112 + [masker="textMask"] LayoutSVGResourceMasker {mask} at (0,-2.50) size 220x112.50 LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGResourceLinearGradient {linearGradient} [id="blackGradient"] [gradientUnits=objectBoundingBox] [start=(0,0)] [end=(1,0)] LayoutSVGGradientStop {stop} [offset=0.00] [color=#000000] LayoutSVGGradientStop {stop} [offset=1.00] [color=#000000] - LayoutSVGText {text} at (0,22) size 291.03x18 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (0,22) size 291.03x18 + LayoutSVGText {text} at (0,21.50) size 291.03x18.50 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (0,21.50) size 291.03x18.50 chunk 1 text run 1 at (0.00,36.00) startOffset 0 endOffset 47 width 291.04: "This text and the circles should also be sharp." LayoutSVGHiddenContainer {defs} at (0,0) size 0x0 LayoutSVGResourceClipper {clipPath} [id="circleClipPath"] [clipPathUnits=objectBoundingBox]
diff --git a/third_party/WebKit/PerformanceTests/Canvas/transferFromImageBitmap.html b/third_party/WebKit/PerformanceTests/Canvas/transferFromImageBitmap.html new file mode 100644 index 0000000..d50fb83 --- /dev/null +++ b/third_party/WebKit/PerformanceTests/Canvas/transferFromImageBitmap.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<body> +<script src="../resources/runner.js"></script> +<script src="resources/canvas_runner.js"></script> +<script> +var source = new OffscreenCanvas(2000, 1000); +var ctx = source.getContext("2d"); +var destination = document.createElement('canvas'); +var destinationCtx = destination.getContext('bitmaprenderer') + +window.onload = function () { + CanvasRunner.start({ + description: "This bench test checks the speed of tranferring 2D context content to a 'bitmaprenderer' context.", + doRun: doRun + }); +} + +function doRun() { + ctx.fillRect(0, 0, 1, 1); + var img = source.transferToImageBitmap(); + destinationCtx.transferFromImageBitmap(img); +} +</script> +</body> +</html>
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptModule.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptModule.cpp index 3e38b06..20d810889 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptModule.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptModule.cpp
@@ -89,7 +89,7 @@ v8::Local<v8::String> specifier, v8::Local<v8::Module> referrer) { v8::Isolate* isolate = context->GetIsolate(); - Modulator* modulator = V8PerContextData::from(context)->modulator(); + Modulator* modulator = Modulator::from(V8PerContextData::from(context)); DCHECK(modulator); ScriptModule referrerRecord(isolate, referrer);
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp index 44bd116..e46c0198 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp
@@ -147,8 +147,7 @@ auto modulator = new ScriptModuleTestModulator(); auto resolver = modulator->testScriptModuleResolver(); - auto contextData = V8PerContextData::from(scope.context()); - contextData->setModulator(modulator); + Modulator::setModulator(&scope.frame(), modulator); ScriptModule module = ScriptModule::compile( scope.isolate(), "export const a = 42;", "foo.js", SharableCrossOrigin); @@ -165,8 +164,7 @@ auto modulator = new ScriptModuleTestModulator(); auto resolver = modulator->testScriptModuleResolver(); - auto contextData = V8PerContextData::from(scope.context()); - contextData->setModulator(modulator); + Modulator::setModulator(&scope.frame(), modulator); ScriptModule moduleA = ScriptModule::compile( scope.isolate(), "export const a = 'a';", "foo.js", SharableCrossOrigin);
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptState.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptState.cpp index 2c52799..13598e6 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptState.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptState.cpp
@@ -6,7 +6,6 @@ #include "bindings/core/v8/V8Binding.h" #include "core/dom/ExecutionContext.h" -#include "core/frame/LocalDOMWindow.h" namespace blink { @@ -75,9 +74,4 @@ ASSERT_NOT_REACHED(); } -LocalDOMWindow* ScriptState::domWindow() const { - v8::HandleScope scope(m_isolate); - return toLocalDOMWindow(context()); -} - } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptState.h b/third_party/WebKit/Source/bindings/core/v8/ScriptState.h index 3c1d09bf..7935856 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptState.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptState.h
@@ -16,7 +16,6 @@ namespace blink { -class LocalDOMWindow; class DOMWrapperWorld; class ExecutionContext; class ScriptValue; @@ -137,7 +136,6 @@ v8::Isolate* isolate() const { return m_isolate; } DOMWrapperWorld& world() const { return *m_world; } - LocalDOMWindow* domWindow() const; virtual ExecutionContext* getExecutionContext() const; virtual void setExecutionContext(ExecutionContext*);
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp b/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp index b8871675..a4ed0e9 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp
@@ -56,7 +56,7 @@ return; } - LocalDOMWindow* window = scriptState->domWindow(); + LocalDOMWindow* window = LocalDOMWindow::from(scriptState); CustomElementRegistry* registry = window->customElements(); // 3. Let definition be the entry in registry with constructor equal to
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerContextData.cpp b/third_party/WebKit/Source/bindings/core/v8/V8PerContextData.cpp index ed7bab5..cca39faf 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8PerContextData.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8PerContextData.cpp
@@ -36,7 +36,6 @@ #include "bindings/core/v8/ScriptState.h" #include "bindings/core/v8/V8Binding.h" #include "bindings/core/v8/V8ObjectConstructor.h" -#include "core/dom/Modulator.h" #include "platform/InstanceCounters.h" #include "platform/wtf/PtrUtil.h" #include "platform/wtf/StringExtras.h" @@ -189,14 +188,16 @@ m_customElementBindings.push_back(std::move(binding)); } -void V8PerContextData::setModulator(Modulator* modulator) { - DCHECK(!m_modulator); - DCHECK(modulator); - m_modulator = modulator; +void V8PerContextData::addData(const char* key, Data* data) { + m_dataMap.set(key, data); } -void V8PerContextData::clearModulator() { - m_modulator = nullptr; +void V8PerContextData::clearData(const char* key) { + m_dataMap.erase(key); +} + +V8PerContextData::Data* V8PerContextData::getData(const char* key) { + return m_dataMap.at(key); } } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8PerContextData.h b/third_party/WebKit/Source/bindings/core/v8/V8PerContextData.h index b31b96dc..1b93a41 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8PerContextData.h +++ b/third_party/WebKit/Source/bindings/core/v8/V8PerContextData.h
@@ -49,7 +49,6 @@ namespace blink { -class Modulator; class V8DOMActivityLogger; class V8PerContextData; @@ -104,9 +103,14 @@ m_activityLogger = activityLogger; } - Modulator* modulator() const { return m_modulator.get(); } - void setModulator(Modulator*); - void clearModulator(); + // Garbage collected classes that use V8PerContextData to hold an instance + // should subclass Data, and use addData / clearData / getData to manage the + // instance. + class CORE_EXPORT Data : public GarbageCollectedMixin {}; + + void addData(const char* key, Data*); + void clearData(const char* key); + Data* getData(const char* key); private: V8PerContextData(v8::Local<v8::Context>); @@ -138,7 +142,8 @@ // This is owned by a static hash map in V8DOMActivityLogger. V8DOMActivityLogger* m_activityLogger; - Persistent<Modulator> m_modulator; + using DataMap = PersistentHeapHashMap<const char*, Member<Data>>; + DataMap m_dataMap; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/Modulator.cpp b/third_party/WebKit/Source/core/dom/Modulator.cpp index 5d6d1f3..8350bcc 100644 --- a/third_party/WebKit/Source/core/dom/Modulator.cpp +++ b/third_party/WebKit/Source/core/dom/Modulator.cpp
@@ -9,16 +9,41 @@ namespace blink { -Modulator* Modulator::from(LocalFrame* frame) { +namespace { +const char kPerContextDataKey[] = "Modulator"; + +V8PerContextData* getPerContextData(LocalFrame* frame) { ScriptState* scriptState = toScriptStateForMainWorld(frame); if (!scriptState) return nullptr; - // TODO(kouhei): setModulator in V8PerContextData when we land ModulatorImpl. - return scriptState->perContextData()->modulator(); + return scriptState->perContextData(); +} +} // namespace + +Modulator* Modulator::from(LocalFrame* frame) { + return from(getPerContextData(frame)); +} + +Modulator* Modulator::from(V8PerContextData* perContextData) { + if (!perContextData) + return nullptr; + return static_cast<Modulator*>(perContextData->getData(kPerContextDataKey)); } Modulator::~Modulator() {} +void Modulator::setModulator(LocalFrame* frame, Modulator* modulator) { + V8PerContextData* perContextData = getPerContextData(frame); + DCHECK(perContextData); + perContextData->addData(kPerContextDataKey, modulator); +} + +void Modulator::clearModulator(LocalFrame* frame) { + V8PerContextData* perContextData = getPerContextData(frame); + DCHECK(perContextData); + perContextData->clearData(kPerContextDataKey); +} + KURL Modulator::resolveModuleSpecifier(const String& moduleRequest, const KURL& baseURL) { // Step 1. Apply the URL parser to specifier. If the result is not failure,
diff --git a/third_party/WebKit/Source/core/dom/Modulator.h b/third_party/WebKit/Source/core/dom/Modulator.h index 4d6c90c..953c784 100644 --- a/third_party/WebKit/Source/core/dom/Modulator.h +++ b/third_party/WebKit/Source/core/dom/Modulator.h
@@ -5,6 +5,7 @@ #ifndef Modulator_h #define Modulator_h +#include "bindings/core/v8/V8PerContextData.h" #include "core/CoreExport.h" #include "platform/heap/Handle.h" #include "platform/loader/fetch/AccessControlStatus.h" @@ -40,11 +41,18 @@ // https://html.spec.whatwg.org/#environment-settings-object // // A Modulator also serves as an entry point for various module spec algorithms. -class CORE_EXPORT Modulator : public GarbageCollectedFinalized<Modulator> { +class CORE_EXPORT Modulator : public GarbageCollectedFinalized<Modulator>, + public V8PerContextData::Data { + USING_GARBAGE_COLLECTED_MIXIN(Modulator); + public: static Modulator* from(LocalFrame*); + static Modulator* from(V8PerContextData*); virtual ~Modulator(); + static void setModulator(LocalFrame*, Modulator*); + static void clearModulator(LocalFrame*); + DEFINE_INLINE_VIRTUAL_TRACE() {} virtual ScriptModuleResolver* scriptModuleResolver() = 0;
diff --git a/third_party/WebKit/Source/core/events/Event.cpp b/third_party/WebKit/Source/core/events/Event.cpp index 7fb7457..7b1ffdc 100644 --- a/third_party/WebKit/Source/core/events/Event.cpp +++ b/third_party/WebKit/Source/core/events/Event.cpp
@@ -341,9 +341,9 @@ double Event::timeStamp(ScriptState* scriptState) const { double timeStamp = 0; - if (scriptState && scriptState->domWindow()) { + if (scriptState && LocalDOMWindow::from(scriptState)) { Performance* performance = - DOMWindowPerformance::performance(*scriptState->domWindow()); + DOMWindowPerformance::performance(*LocalDOMWindow::from(scriptState)); double timestampSeconds = (m_platformTimeStamp - TimeTicks()).InSecondsF(); timeStamp = performance->monotonicTimeToDOMHighResTimeStamp(timestampSeconds);
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.h b/third_party/WebKit/Source/core/frame/ImageBitmap.h index 99fd4d5..0f784e14 100644 --- a/third_party/WebKit/Source/core/frame/ImageBitmap.h +++ b/third_party/WebKit/Source/core/frame/ImageBitmap.h
@@ -96,9 +96,7 @@ using WebType = sk_sp<SkImage>; static ImageBitmap* take(ScriptPromiseResolver*, sk_sp<SkImage>); - StaticBitmapImage* bitmapImage() const { - return (m_image) ? m_image.get() : nullptr; - } + PassRefPtr<StaticBitmapImage> bitmapImage() const { return m_image; } PassRefPtr<Uint8Array> copyBitmapData(AlphaDisposition = DontPremultiplyAlpha, DataColorFormat = RGBAColorType); unsigned long width() const;
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp index 9843ef9e..10c101a 100644 --- a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp +++ b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
@@ -134,7 +134,7 @@ ASSERT_NE(imageBitmapExteriorCrop->bitmapImage()->imageForCurrentFrame(), imageElement->cachedImage()->getImage()->imageForCurrentFrame()); - StaticBitmapImage* emptyImage = imageBitmapOutsideCrop->bitmapImage(); + RefPtr<StaticBitmapImage> emptyImage = imageBitmapOutsideCrop->bitmapImage(); ASSERT_NE(emptyImage->imageForCurrentFrame(), imageElement->cachedImage()->getImage()->imageForCurrentFrame()); }
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp index 8828f7e..6d96972 100644 --- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp +++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -328,6 +328,11 @@ return document; } +LocalDOMWindow* LocalDOMWindow::from(const ScriptState* scriptState) { + v8::HandleScope scope(scriptState->isolate()); + return blink::toLocalDOMWindow(scriptState->context()); +} + Document* LocalDOMWindow::installNewDocument(const String& mimeType, const DocumentInit& init, bool forceXHTML) {
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h index 2e809219..1c60362b 100644 --- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h +++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
@@ -100,6 +100,8 @@ return new LocalDOMWindow(frame); } + static LocalDOMWindow* from(const ScriptState*); + ~LocalDOMWindow() override; LocalFrame* frame() const { return toLocalFrame(DOMWindow::frame()); }
diff --git a/third_party/WebKit/Source/core/frame/PRESUBMIT.py b/third_party/WebKit/Source/core/frame/PRESUBMIT.py index 589861b..4d105e3 100644 --- a/third_party/WebKit/Source/core/frame/PRESUBMIT.py +++ b/third_party/WebKit/Source/core/frame/PRESUBMIT.py
@@ -74,11 +74,17 @@ START_MARKER = '^enum Feature : uint32_t {' END_MARKER = '^NumberOfFeatures' - if update_histogram_enum.HistogramNeedsUpdate( - histogram_enum_name='FeatureObserver', - source_enum_path=source_path, - start_marker=START_MARKER, - end_marker=END_MARKER): + should_update_histogram, duplicated_values = update_histogram_enum.HistogramNeedsUpdate( + histogram_enum_name='FeatureObserver', + source_enum_path=source_path, + start_marker=START_MARKER, + end_marker=END_MARKER) + if duplicated_values: + return [output_api.PresubmitPromptWarning( + 'UseCounter::Feature has been updated and there exists duplicated ' + 'values between (%s) and (%s)' % duplicated_values, + items=[source_path])] + if should_update_histogram: return [output_api.PresubmitPromptWarning( 'UseCounter::Feature has been updated and the UMA mapping needs to ' 'be regenerated. Please run update_use_counter_feature_enum.py in '
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp index 21d70d8..56a560a 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -284,7 +284,7 @@ !m_context->creationAttributes().alpha()) { // In the alpha false case, canvas is initially opaque even though there is // no ImageBuffer, so we need to trigger an invalidation. - didDraw(FloatRect(0, 0, size().width(), size().height())); + didDraw(); } setNeedsCompositingUpdate(); @@ -293,7 +293,7 @@ } bool HTMLCanvasElement::shouldBeDirectComposited() const { - return (m_context && m_context->isAccelerated()) || + return (m_context && m_context->isComposited()) || (hasImageBuffer() && buffer()->isExpensiveToPaint()) || (!!m_surfaceLayerBridge); } @@ -326,6 +326,10 @@ buffer()->didDraw(rect); } +void HTMLCanvasElement::didDraw() { + didDraw(FloatRect(0, 0, size().width(), size().height())); +} + void HTMLCanvasElement::finalizeFrame() { if (hasImageBuffer()) m_imageBuffer->finalizeFrame(); @@ -345,7 +349,7 @@ void HTMLCanvasElement::didDisableAcceleration() { // We must force a paint invalidation on the canvas even if it's // content did not change because it layer was destroyed. - didDraw(FloatRect(0, 0, size().width(), size().height())); + didDraw(); } void HTMLCanvasElement::restoreCanvasMatrixClipStack( @@ -364,7 +368,7 @@ if (lb) { FloatRect mappedDirtyRect = mapRect(m_dirtyRect, srcRect, FloatRect(lb->contentBoxRect())); - if (m_context->isAccelerated()) { + if (m_context->isComposited()) { // Accelerated 2D canvases need the dirty rect to be expressed relative // to the content box, as opposed to the layout box. mappedDirtyRect.move(-lb->contentBoxOffset()); @@ -373,13 +377,20 @@ } else { invalidationRect = m_dirtyRect; } + + if (m_dirtyRect.isEmpty()) + return; + if (hasImageBuffer()) { m_imageBuffer->doPaintInvalidation(invalidationRect); } } - if (m_dirtyRect.isEmpty()) - return; + if (m_context->getContextType() == + CanvasRenderingContext::ContextImageBitmap && + m_context->platformLayer()) { + m_context->platformLayer()->invalidate(); + } notifyListenersCanvasChanged(); m_didNotifyListenersForCurrentFrame = true; @@ -390,9 +401,9 @@ LayoutBox* ro = layoutBox(); // Canvas content updates do not need to be propagated as - // paint invalidations if the canvas is accelerated, since + // paint invalidations if the canvas is composited separately, since // the canvas contents are sent separately through a texture layer. - if (ro && (!m_context || !m_context->isAccelerated())) { + if (ro && (!m_context || !m_context->isComposited())) { // If ro->contentBoxRect() is larger than srcRect the canvas's image is // being stretched, so we need to account for color bleeding caused by the // interpollation filter. @@ -500,7 +511,7 @@ if (placeholderFrame()) return false; DCHECK(m_context); - if (!m_context->isAccelerated()) + if (!m_context->isComposited()) return true; if (layoutBox() && layoutBox()->hasAcceleratedCompositing()) return false; @@ -1288,8 +1299,8 @@ if (ExpensiveCanvasHeuristicParameters:: DisableAccelerationToAvoidReadbacks && !RuntimeEnabledFeatures::canvas2dFixedRenderingModeEnabled() && - hint == PreferNoAcceleration && m_context->isAccelerated() && - hasImageBuffer()) { + hint == PreferNoAcceleration && hasImageBuffer() && + buffer()->isAccelerated()) { buffer()->disableAcceleration(); } RefPtr<Image> image = renderingContext()->getImage(hint, reason);
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h index 4e8b7732..45e689b 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.h +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
@@ -134,6 +134,7 @@ // Used for rendering void didDraw(const FloatRect&); + void didDraw(); void paint(GraphicsContext&, const LayoutRect&);
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp index 83c4ec96..17d7da4 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
@@ -168,6 +168,11 @@ needsFinalizeFrame(); } +void CanvasRenderingContext::didDraw() { + canvas()->didDraw(); + needsFinalizeFrame(); +} + void CanvasRenderingContext::needsFinalizeFrame() { if (!m_finalizeFrameScheduled) { m_finalizeFrameScheduled = true; @@ -178,7 +183,6 @@ void CanvasRenderingContext::didProcessTask() { Platform::current()->currentThread()->removeTaskObserver(this); m_finalizeFrameScheduled = false; - // The end of a script task that drew content to the canvas is the point // at which the current frame may be considered complete. if (canvas())
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h index 7991a2b..d29d286 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h +++ b/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -122,7 +122,8 @@ SnapshotReason) const = 0; virtual ImageData* toImageData(SnapshotReason reason) { return nullptr; } virtual ContextType getContextType() const = 0; - virtual bool isAccelerated() const { return false; } + virtual bool isComposited() const = 0; + virtual bool isAccelerated() const = 0; virtual bool shouldAntialias() const { return false; } virtual void setIsHidden(bool) = 0; virtual bool isContextLost() const { return true; } @@ -132,6 +133,7 @@ } virtual bool isPaintable() const = 0; virtual void didDraw(const SkIRect& dirtyRect); + virtual void didDraw(); // Return true if the content is updated. virtual bool paintRenderingResultsToCanvas(SourceDrawingBuffer) {
diff --git a/third_party/WebKit/Source/core/layout/FragmentainerIterator.cpp b/third_party/WebKit/Source/core/layout/FragmentainerIterator.cpp index f7b8e61..c40046e 100644 --- a/third_party/WebKit/Source/core/layout/FragmentainerIterator.cpp +++ b/third_party/WebKit/Source/core/layout/FragmentainerIterator.cpp
@@ -149,7 +149,7 @@ if (m_endFragmentainerIndex > lastFragmentainerInClipRect) m_endFragmentainerIndex = lastFragmentainerInClipRect; } - DCHECK(m_endFragmentainerIndex >= m_currentFragmentainerIndex); + DCHECK_GE(m_endFragmentainerIndex, m_currentFragmentainerIndex); return true; }
diff --git a/third_party/WebKit/Source/core/layout/Grid.cpp b/third_party/WebKit/Source/core/layout/Grid.cpp index 1a06366..ae3704d4 100644 --- a/third_party/WebKit/Source/core/layout/Grid.cpp +++ b/third_party/WebKit/Source/core/layout/Grid.cpp
@@ -31,8 +31,8 @@ } void Grid::insert(LayoutBox& child, const GridArea& area) { - DCHECK(area.rows.isTranslatedDefinite() && - area.columns.isTranslatedDefinite()); + DCHECK(area.rows.isTranslatedDefinite()); + DCHECK(area.columns.isTranslatedDefinite()); ensureGridSize(area.rows.endLine(), area.columns.endLine()); for (const auto& row : area.rows) { @@ -164,8 +164,8 @@ m_childIndex(0) { DCHECK(!m_grid.isEmpty()); DCHECK(!m_grid[0].isEmpty()); - DCHECK(m_rowIndex < m_grid.size()); - DCHECK(m_columnIndex < m_grid[0].size()); + DCHECK_LT(m_rowIndex, m_grid.size()); + DCHECK_LT(m_columnIndex, m_grid[0].size()); } LayoutBox* GridIterator::nextGridItem() { @@ -212,7 +212,8 @@ size_t varyingTrackSpan) { DCHECK(!m_grid.isEmpty()); DCHECK(!m_grid[0].isEmpty()); - DCHECK(fixedTrackSpan >= 1 && varyingTrackSpan >= 1); + DCHECK_GE(fixedTrackSpan, 1u); + DCHECK_GE(varyingTrackSpan, 1u); size_t rowSpan = (m_direction == ForColumns) ? varyingTrackSpan : fixedTrackSpan;
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp index 909f9c5e1..b033024 100644 --- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -1663,7 +1663,8 @@ .resolvedAlignSelf(selfAlignmentNormalBehavior(), child.isAnonymous() ? style() : nullptr) .position(); - DCHECK(align != ItemPositionAuto && align != ItemPositionNormal); + DCHECK_NE(align, ItemPositionAuto); + DCHECK_NE(align, ItemPositionNormal); if (align == ItemPositionBaseline && hasOrthogonalFlow(child)) align = ItemPositionFlexStart;
diff --git a/third_party/WebKit/Source/core/layout/LayoutState.cpp b/third_party/WebKit/Source/core/layout/LayoutState.cpp index 0874035..c021054 100644 --- a/third_party/WebKit/Source/core/layout/LayoutState.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutState.cpp
@@ -113,7 +113,7 @@ LayoutState::~LayoutState() { if (m_layoutObject.view()->layoutState()) { - DCHECK(m_layoutObject.view()->layoutState() == this); + DCHECK_EQ(m_layoutObject.view()->layoutState(), this); m_layoutObject.view()->popLayoutState(); } }
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableBoxComponent.h b/third_party/WebKit/Source/core/layout/LayoutTableBoxComponent.h index 3f5c49d..71ed6fe 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableBoxComponent.h +++ b/third_party/WebKit/Source/core/layout/LayoutTableBoxComponent.h
@@ -43,11 +43,11 @@ LayoutObjectChildList* children() { return &m_children; } LayoutObject* firstChild() const { - DCHECK(children() == virtualChildren()); + DCHECK_EQ(children(), virtualChildren()); return children()->firstChild(); } LayoutObject* lastChild() const { - DCHECK(children() == virtualChildren()); + DCHECK_EQ(children(), virtualChildren()); return children()->lastChild(); }
diff --git a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp index b4c3bd8..34dfe47b 100644 --- a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp +++ b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
@@ -103,7 +103,7 @@ #endif { DCHECK(!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()); - DCHECK(&m_paintingLayer == currentObject.paintingLayer()); + DCHECK_EQ(&m_paintingLayer, currentObject.paintingLayer()); if (currentObject == parentState.m_currentObject) { // Sometimes we create a new PaintInvalidationState from parentState on the same @@ -243,9 +243,9 @@ return; if (m_currentObject.isLayoutView()) { - DCHECK(&parentState.m_currentObject == - LayoutAPIShim::layoutObjectFrom( - toLayoutView(m_currentObject).frame()->ownerLayoutItem())); + DCHECK_EQ(&parentState.m_currentObject, + LayoutAPIShim::layoutObjectFrom( + toLayoutView(m_currentObject).frame()->ownerLayoutItem())); m_paintOffset += toLayoutBox(parentState.m_currentObject).contentBoxOffset(); // a LayoutView paints with a defined size but a pixel-rounded offset. @@ -435,9 +435,9 @@ point = m_svgTransform.mapPoint(point); point += FloatPoint(m_paintOffset); #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY - DCHECK(point == - slowLocalOriginToAncestorPoint( - m_currentObject, m_paintInvalidationContainer, FloatPoint())); + DCHECK_EQ(point, slowLocalOriginToAncestorPoint( + m_currentObject, m_paintInvalidationContainer, + FloatPoint())); #endif } else { point = slowLocalToAncestorPoint( @@ -569,7 +569,7 @@ } PaintLayer& PaintInvalidationState::paintingLayer() const { - DCHECK(&m_paintingLayer == m_currentObject.paintingLayer()); + DCHECK_EQ(&m_paintingLayer, m_currentObject.paintingLayer()); return m_paintingLayer; } @@ -644,7 +644,7 @@ void PaintInvalidatorContextAdapter::mapLocalRectToVisualRectInBacking( const LayoutObject& object, LayoutRect& rect) const { - DCHECK(&object == &m_paintInvalidationState.currentObject()); + DCHECK_EQ(&object, &m_paintInvalidationState.currentObject()); m_paintInvalidationState.mapLocalRectToVisualRectInBacking(rect); }
diff --git a/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp b/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp index f0925ed..e196f22 100644 --- a/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp +++ b/third_party/WebKit/Source/core/layout/ScrollAnchor.cpp
@@ -30,7 +30,7 @@ ScrollAnchor::~ScrollAnchor() {} void ScrollAnchor::setScroller(ScrollableArea* scroller) { - DCHECK(m_scroller != scroller); + DCHECK_NE(m_scroller, scroller); DCHECK(scroller); DCHECK(scroller->isRootFrameViewport() || scroller->isFrameView() || scroller->isPaintLayerScrollableArea()); @@ -201,7 +201,7 @@ if (result.status == Constrain) return true; - DCHECK(result.status == Continue); + DCHECK_EQ(result.status, Continue); return false; }
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp index 96148621..5bf31587 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -109,11 +109,11 @@ return pixelSnappedIntRect(box.backgroundRect(BackgroundClipRect)); } -static inline bool isAcceleratedCanvas(const LayoutObject& layoutObject) { +static inline bool isCompositedCanvas(const LayoutObject& layoutObject) { if (layoutObject.isCanvas()) { HTMLCanvasElement* canvas = toHTMLCanvasElement(layoutObject.node()); if (CanvasRenderingContext* context = canvas->renderingContext()) - return context->isAccelerated(); + return context->isComposited(); } return false; } @@ -153,7 +153,7 @@ } static inline bool isAcceleratedContents(LayoutObject& layoutObject) { - return isAcceleratedCanvas(layoutObject) || + return isCompositedCanvas(layoutObject) || (layoutObject.isEmbeddedObject() && toLayoutEmbeddedObject(layoutObject) .requiresAcceleratedCompositing()) || @@ -439,7 +439,7 @@ } void CompositedLayerMapping::updateContentsOpaque() { - if (isAcceleratedCanvas(layoutObject())) { + if (isCompositedCanvas(layoutObject())) { CanvasRenderingContext* context = toHTMLCanvasElement(layoutObject().node())->renderingContext(); WebLayer* layer = context ? context->platformLayer() : nullptr; @@ -809,7 +809,7 @@ m_graphicsLayer->setContentsToPlatformLayer( canvas->surfaceLayerBridge()->getWebLayer()); layerConfigChanged = true; - } else if (isAcceleratedCanvas(layoutObject)) { + } else if (isCompositedCanvas(layoutObject)) { HTMLCanvasElement* canvas = toHTMLCanvasElement(layoutObject.node()); if (CanvasRenderingContext* context = canvas->renderingContext()) m_graphicsLayer->setContentsToPlatformLayer(context->platformLayer()); @@ -1753,7 +1753,7 @@ m_drawsBackgroundOntoContentLayer = false; - if (hasPaintedContent && isAcceleratedCanvas(layoutObject())) { + if (hasPaintedContent && isCompositedCanvas(layoutObject())) { CanvasRenderingContext* context = toHTMLCanvasElement(layoutObject().node())->renderingContext(); // Content layer may be null if context is lost. @@ -2674,7 +2674,7 @@ return; } - if (changeType == CanvasChanged && isAcceleratedCanvas(layoutObject())) { + if (changeType == CanvasChanged && isCompositedCanvas(layoutObject())) { m_graphicsLayer->setContentsNeedsDisplay(); return; }
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingLayerAssigner.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingLayerAssigner.cpp index c146c8b..4fbe496 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositingLayerAssigner.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/CompositingLayerAssigner.cpp
@@ -192,7 +192,7 @@ if (layer->nearestFixedPositionLayer() != squashingLayer.nearestFixedPositionLayer()) return SquashingDisallowedReasonNearestFixedPositionMismatch; - DCHECK(layer->layoutObject().style()->position() != EPosition::kFixed); + DCHECK_NE(layer->layoutObject().style()->position(), EPosition::kFixed); if ((squashingLayer.layoutObject().style()->subtreeWillChangeContents() && squashingLayer.layoutObject()
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.cpp index e8b7882..17a6302 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.cpp
@@ -234,7 +234,7 @@ EPosition position = layer->layoutObject().style()->position(); if (position == EPosition::kFixed) return layer->fixedToViewport() && m_layoutView.frameView()->isScrollable(); - DCHECK(position == EPosition::kSticky); + DCHECK_EQ(position, EPosition::kSticky); // Don't promote sticky position elements that cannot move with scrolls. if (!layer->sticksToScroller())
diff --git a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h index 7893a3b..d704b81 100644 --- a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h +++ b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
@@ -1119,9 +1119,10 @@ if (hyphenation && (m_nextObject || isLineEmpty || hasVisibleText(layoutText, m_current.offset()))) { m_width.addUncommittedWidth(-wordMeasurement.width); - DCHECK(lastSpace == static_cast<unsigned>(wordMeasurement.startOffset)); - DCHECK(m_current.offset() == - static_cast<unsigned>(wordMeasurement.endOffset)); + DCHECK_EQ(lastSpace, + static_cast<unsigned>(wordMeasurement.startOffset)); + DCHECK_EQ(m_current.offset(), + static_cast<unsigned>(wordMeasurement.endOffset)); if (hyphenate(layoutText, style, font, *hyphenation, lastSpaceWordSpacing, wordMeasurement)) { m_width.addUncommittedWidth(wordMeasurement.width);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc index 5347de18..245e470 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc
@@ -88,7 +88,7 @@ Optional<LayoutUnit> width = incoming_width; NGPhysicalSize container_size = space.AvailableSize().ConvertToPhysical(space.WritingMode()); - DCHECK(container_size.width != NGSizeIndefinite); + DCHECK_NE(container_size.width, NGSizeIndefinite); // Solving the equation: // left + marginLeft + width + marginRight + right = container width @@ -250,7 +250,7 @@ NGPhysicalSize container_size = space.AvailableSize().ConvertToPhysical(space.WritingMode()); - DCHECK(container_size.height != NGSizeIndefinite); + DCHECK_NE(container_size.height, NGSizeIndefinite); // Solving the equation: // top + marginTop + height + marginBottom + bottom
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc index b2885ea..cb8734d 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
@@ -89,7 +89,8 @@ case NGPhysicalBoxFragment::kFragmentLineBox: // NGInlineNode produces multiple line boxes in an anonymous box. Only // the last break token is needed to be reported to the parent. - DCHECK(child->BreakToken() && child->BreakToken()->InputNode() == node_); + DCHECK(child->BreakToken()); + DCHECK_EQ(child->BreakToken()->InputNode(), node_); last_inline_break_token_ = child->BreakToken()->IsFinished() ? nullptr : child->BreakToken(); break;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc index e44ea699..63cefdd 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc
@@ -227,7 +227,7 @@ if (*layout_result) return layout_result->get(); - DCHECK(item.Type() == NGLayoutInlineItem::kAtomicInline); + DCHECK_EQ(item.Type(), NGLayoutInlineItem::kAtomicInline); NGBlockNode* node = new NGBlockNode(item.GetLayoutObject()); // TODO(kojii): Keep node in NGLayoutInlineItem. const ComputedStyle& style = node->Style(); @@ -553,8 +553,8 @@ } MinMaxContentSize NGInlineLayoutAlgorithm::ComputeMinMaxContentSizeByLayout() { - DCHECK(ConstraintSpace().AvailableSize().inline_size == LayoutUnit() && - ConstraintSpace().AvailableSize().block_size == NGSizeIndefinite); + DCHECK_EQ(ConstraintSpace().AvailableSize().inline_size, LayoutUnit()); + DCHECK_EQ(ConstraintSpace().AvailableSize().block_size, NGSizeIndefinite); if (!Node()->Text().isEmpty()) NGLineBreaker().BreakLines(this, Node()->Text(), start_offset_); MinMaxContentSize sizes;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc index 4be176f..f99de8aa 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc
@@ -232,21 +232,23 @@ if (Type() == NGLayoutInlineItem::kText) return LayoutUnit(shape_result_->width()); - DCHECK(Type() != NGLayoutInlineItem::kAtomicInline) + DCHECK_NE(Type(), NGLayoutInlineItem::kAtomicInline) << "Use NGInlineLayoutAlgorithm::InlineSize"; // Bidi controls and out-of-flow objects do not have in-flow widths. return LayoutUnit(); } LayoutUnit NGLayoutInlineItem::InlineSize(unsigned start, unsigned end) const { - DCHECK(start >= StartOffset() && start <= end && end <= EndOffset()); + DCHECK_GE(start, StartOffset()); + DCHECK_LE(start, end); + DCHECK_LE(end, EndOffset()); if (start == end) return LayoutUnit(); if (start == start_offset_ && end == end_offset_) return InlineSize(); - DCHECK(Type() == NGLayoutInlineItem::kText); + DCHECK_EQ(Type(), NGLayoutInlineItem::kText); return LayoutUnit(ShapeResultBuffer::getCharacterRange( shape_result_, Direction(), shape_result_->width(), start - StartOffset(), end - StartOffset()) @@ -257,7 +259,9 @@ HashSet<const SimpleFontData*>* fallback_fonts, unsigned start, unsigned end) const { - DCHECK(start >= StartOffset() && start <= end && end <= EndOffset()); + DCHECK_GE(start, StartOffset()); + DCHECK_LE(start, end); + DCHECK_LE(end, EndOffset()); // TODO(kojii): Implement |start| and |end|. shape_result_->fallbackFonts(fallback_fonts);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h index b49afb9..9fca8cce 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h
@@ -131,7 +131,7 @@ style_(style), layout_object_(layout_object), type_(type) { - DCHECK(end >= start); + DCHECK_GE(end, start); } NGLayoutInlineItemType Type() const { @@ -192,7 +192,8 @@ } inline void NGLayoutInlineItem::AssertEndOffset(unsigned offset) const { - DCHECK(offset >= start_offset_ && offset <= end_offset_); + DCHECK_GE(offset, start_offset_); + DCHECK_LE(offset, end_offset_); } inline void NGInlineNode::AssertOffset(unsigned index, unsigned offset) const {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_inline_items_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_inline_items_builder.cc index cd83ca1..099daab 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_inline_items_builder.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_inline_items_builder.cc
@@ -55,7 +55,8 @@ const ComputedStyle* after_style) { // Remove if either before/after the newline is zeroWidthSpaceCharacter. UChar32 last = 0; - DCHECK(!before.isEmpty() && before[before.length() - 1] == ' '); + DCHECK(!before.isEmpty()); + DCHECK_EQ(before[before.length() - 1], ' '); if (before.length() >= 2) { last = before[before.length() - 2]; if (last == zeroWidthSpaceCharacter) @@ -188,8 +189,10 @@ UChar character, const ComputedStyle* style, LayoutObject* layout_object) { - DCHECK(character != spaceCharacter && character != tabulationCharacter && - character != newlineCharacter && character != zeroWidthSpaceCharacter); + DCHECK_NE(character, spaceCharacter); + DCHECK_NE(character, tabulationCharacter); + DCHECK_NE(character, newlineCharacter); + DCHECK_NE(character, zeroWidthSpaceCharacter); text_.append(character); unsigned end_offset = text_.length(); @@ -236,7 +239,8 @@ void NGLayoutInlineItemsBuilder::RemoveTrailingCollapsibleSpace( unsigned* next_start_offset) { DCHECK_NE(last_collapsible_space_, CollapsibleSpace::None); - DCHECK(!text_.isEmpty() && text_[text_.length() - 1] == spaceCharacter); + DCHECK(!text_.isEmpty()); + DCHECK_EQ(text_[text_.length() - 1], spaceCharacter); unsigned new_size = text_.length() - 1; text_.resize(new_size);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc index f18089c..18b05ce 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
@@ -121,7 +121,7 @@ LayoutUnit content_size, LengthResolveType type) { DCHECK(!length.isMaxSizeNone()); - DCHECK(type != LengthResolveType::kMarginBorderPaddingSize); + DCHECK_NE(type, LengthResolveType::kMarginBorderPaddingSize); if (type == LengthResolveType::kMinSize && length.isAuto()) return LayoutUnit(); @@ -290,7 +290,7 @@ DCHECK(computed_count); return computed_count; } - DCHECK(computed_size > LayoutUnit()); + DCHECK_GT(computed_size, LayoutUnit()); int count_from_width = ((available_size + used_gap) / (computed_size + used_gap)).toInt(); count_from_width = std::max(1, count_from_width);
diff --git a/third_party/WebKit/Source/core/layout/shapes/ShapeInterval.h b/third_party/WebKit/Source/core/layout/shapes/ShapeInterval.h index b55f2e67..e21ef89 100644 --- a/third_party/WebKit/Source/core/layout/shapes/ShapeInterval.h +++ b/third_party/WebKit/Source/core/layout/shapes/ShapeInterval.h
@@ -45,7 +45,7 @@ DCHECK(isUndefined()); } - ShapeInterval(T x1, T x2) : m_x1(x1), m_x2(x2) { DCHECK(x2 >= x1); } + ShapeInterval(T x1, T x2) : m_x1(x1), m_x2(x2) { DCHECK_GE(x2, x1); } bool isUndefined() const { return m_x2 < m_x1; } T x1() const { return isUndefined() ? 0 : m_x1; }
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp index 1811efa..25b768fa7 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp +++ b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
@@ -37,6 +37,7 @@ #include "core/layout/svg/LayoutSVGViewportContainer.h" #include "core/layout/svg/SVGResources.h" #include "core/layout/svg/SVGResourcesCache.h" +#include "core/page/Page.h" #include "core/paint/PaintLayer.h" #include "core/svg/SVGElement.h" #include "platform/geometry/TransformState.h" @@ -519,7 +520,7 @@ m_savedContentTransformation.copyTransformTo(s_currentContentTransformation); } -float SVGLayoutSupport::calculateScreenFontSizeScalingFactor( +AffineTransform SVGLayoutSupport::deprecatedCalculateTransformToLayer( const LayoutObject* layoutObject) { AffineTransform transform; while (layoutObject) { @@ -528,10 +529,43 @@ break; layoutObject = layoutObject->parent(); } - transform.multiply( - SubtreeContentTransformScope::currentContentTransformation()); - return clampTo<float>( - sqrt((transform.xScaleSquared() + transform.yScaleSquared()) / 2)); + + // Continue walking up the layer tree, accumulating CSS transforms. + // FIXME: this queries layer compositing state - which is not + // supported during layout. Hence, the result may not include all CSS + // transforms. + PaintLayer* layer = layoutObject ? layoutObject->enclosingLayer() : 0; + while (layer && layer->isAllowedToQueryCompositingState()) { + // We can stop at compositing layers, to match the backing resolution. + // FIXME: should we be computing the transform to the nearest composited + // layer, or the nearest composited layer that does not paint into its + // ancestor? I think this is the nearest composited ancestor since we will + // inherit its transforms in the composited layer tree. + if (layer->compositingState() != NotComposited) + break; + + if (TransformationMatrix* layerTransform = layer->transform()) + transform = layerTransform->toAffineTransform() * transform; + + layer = layer->parent(); + } + + return transform; +} + +float SVGLayoutSupport::calculateScreenFontSizeScalingFactor( + const LayoutObject* layoutObject) { + DCHECK(layoutObject); + + // FIXME: trying to compute a device space transform at record time is wrong. + // All clients should be updated to avoid relying on this information, and the + // method should be removed. + AffineTransform ctm = + deprecatedCalculateTransformToLayer(layoutObject) * + SubtreeContentTransformScope::currentContentTransformation(); + ctm.scale(layoutObject->document().page()->deviceScaleFactorDeprecated()); + + return clampTo<float>(sqrt((ctm.xScaleSquared() + ctm.yScaleSquared()) / 2)); } static inline bool compareCandidateDistance(const SearchCandidate& r1,
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.h b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.h index c73d826..1d2b671 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.h +++ b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.h
@@ -145,6 +145,8 @@ static bool computeHasNonIsolatedBlendingDescendants(const LayoutObjectType*); static bool isIsolationRequired(const LayoutObject*); + static AffineTransform deprecatedCalculateTransformToLayer( + const LayoutObject*); static float calculateScreenFontSizeScalingFactor(const LayoutObject*); static LayoutObject* findClosestLayoutSVGText(LayoutObject*,
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp index 1a562c6..c290855 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp +++ b/third_party/WebKit/Source/core/layout/svg/SVGTextLayoutEngine.cpp
@@ -314,7 +314,7 @@ m_descendantTextNodes[m_currentLogicalTextNodeIndex]; const Vector<SVGTextMetrics>* metricsList = &logicalTextNode->metricsList(); unsigned metricsListSize = metricsList->size(); - DCHECK(m_logicalMetricsListOffset <= metricsListSize); + DCHECK_LE(m_logicalMetricsListOffset, metricsListSize); // Find the next non-collapsed text metrics cell. while (true) {
diff --git a/third_party/WebKit/Source/core/paint/HTMLCanvasPainter.cpp b/third_party/WebKit/Source/core/paint/HTMLCanvasPainter.cpp index 9607dd66..d28b4cc 100644 --- a/third_party/WebKit/Source/core/paint/HTMLCanvasPainter.cpp +++ b/third_party/WebKit/Source/core/paint/HTMLCanvasPainter.cpp
@@ -27,7 +27,7 @@ if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && canvas->renderingContext() && - canvas->renderingContext()->isAccelerated()) { + canvas->renderingContext()->isComposited()) { if (WebLayer* layer = canvas->renderingContext()->platformLayer()) { IntRect pixelSnappedRect = pixelSnappedIntRect(contentRect); recordForeignLayer(context, m_layoutHTMLCanvas,
diff --git a/third_party/WebKit/Source/core/paint/HTMLCanvasPainterTest.cpp b/third_party/WebKit/Source/core/paint/HTMLCanvasPainterTest.cpp index a150334..fa3b275f 100644 --- a/third_party/WebKit/Source/core/paint/HTMLCanvasPainterTest.cpp +++ b/third_party/WebKit/Source/core/paint/HTMLCanvasPainterTest.cpp
@@ -84,7 +84,8 @@ element->createImageBufferUsingSurfaceForTesting(WTF::wrapUnique( new Canvas2DImageBufferSurface(bridge, IntSize(300, 200)))); ASSERT_EQ(context, element->renderingContext()); - ASSERT_TRUE(context->isAccelerated()); + ASSERT_TRUE(context->isComposited()); + ASSERT_TRUE(element->isAccelerated()); // Force the page to paint. document().view()->updateAllLifecyclePhases();
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/DatabaseQueryView.js b/third_party/WebKit/Source/devtools/front_end/resources/DatabaseQueryView.js index 66fef316..aaf6894 100644 --- a/third_party/WebKit/Source/devtools/front_end/resources/DatabaseQueryView.js +++ b/third_party/WebKit/Source/devtools/front_end/resources/DatabaseQueryView.js
@@ -35,13 +35,11 @@ this.element.classList.add('storage-view', 'query', 'monospace'); this.element.addEventListener('selectstart', this._selectStart.bind(this), false); - this._promptIcon = UI.Icon.create('smallicon-text-prompt', 'prompt-icon'); - this._promptElement = createElement('div'); - this._promptElement.appendChild(this._promptIcon); + this._promptContainer = this.element.createChild('div', 'database-query-prompt-container'); + this._promptContainer.appendChild(UI.Icon.create('smallicon-text-prompt', 'prompt-icon')); + this._promptElement = this._promptContainer.createChild('div'); this._promptElement.className = 'database-query-prompt'; - this._promptElement.appendChild(createElement('br')); this._promptElement.addEventListener('keydown', this._promptKeyDown.bind(this), true); - this.element.appendChild(this._promptElement); this._prompt = new UI.TextPrompt(); this._prompt.initialize(this.completions.bind(this), ' '); @@ -131,7 +129,6 @@ return; this._prompt.setText(''); - this._promptElement.insertBefore(this._promptIcon, this._promptElement.firstChild); this.database.executeSql(query, this._queryFinished.bind(this, query), this._queryError.bind(this, query)); } @@ -184,7 +181,7 @@ var element = createElement('div'); element.className = 'database-user-query'; element.appendChild(UI.Icon.create('smallicon-user-command', 'prompt-icon')); - this.element.insertBefore(element, this._proxyElement); + this.element.insertBefore(element, this._promptContainer); var commandTextElement = createElement('span'); commandTextElement.className = 'database-query-text';
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/resourcesPanel.css b/third_party/WebKit/Source/devtools/front_end/resources/resourcesPanel.css index 89b61c2..ca1ac712 100644 --- a/third_party/WebKit/Source/devtools/front_end/resources/resourcesPanel.css +++ b/third_party/WebKit/Source/devtools/front_end/resources/resourcesPanel.css
@@ -90,9 +90,12 @@ border-bottom: 1px solid #dadada; } -.database-query-prompt { +.database-query-prompt-container { position: relative; padding: 1px 22px 1px 24px; +} + +.database-query-prompt { min-height: 16px; white-space: pre-wrap; -webkit-user-modify: read-write-plaintext-only; @@ -103,11 +106,15 @@ position: absolute; display: block; left: 7px; - top: 0.8em; + top: 9px; margin-top: -7px; -webkit-user-select: none; } +.database-query-prompt-container .prompt-icon { + top: 10px; +} + .database-user-query { position: relative; border-bottom: 1px solid rgb(245, 245, 245);
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js index a7915cd..37e7ff121 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTreeView.js
@@ -632,11 +632,6 @@ this._groupBySetting = Common.settings.createSetting('timelineTreeGroupBy', Timeline.AggregatedTimelineTreeView.GroupBy.None); this.init(filters); - var nonessentialEvents = [ - TimelineModel.TimelineModel.RecordType.EventDispatch, TimelineModel.TimelineModel.RecordType.FunctionCall, - TimelineModel.TimelineModel.RecordType.TimerFire - ]; - this._filters.push(new TimelineModel.ExclusiveNameFilter(nonessentialEvents)); this._stackView = new Timeline.TimelineStackView(this); this._stackView.addEventListener( Timeline.TimelineStackView.Events.SelectionChanged, this._onStackViewSelectionChanged, this);
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js b/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js index 0672b10..3ef2086 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js
@@ -162,17 +162,11 @@ } /** - * @param {string} x + * @param {string} text */ - setText(x) { + setText(text) { this.clearAutocomplete(); - if (!x) { - // Append a break element instead of setting textContent to make sure the selection is inside the prompt. - this._element.removeChildren(); - this._element.createChild('br'); - } else { - this._element.textContent = x; - } + this._element.textContent = text; this._previousText = this.text(); this.moveCaretToEndOfPrompt();
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp index 50ae0fef..d512770 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
@@ -900,7 +900,7 @@ if (!imageBitmap) return String(); - StaticBitmapImage* bitmapImage = imageBitmap->bitmapImage(); + RefPtr<StaticBitmapImage> bitmapImage = imageBitmap->bitmapImage(); if (!bitmapImage) return String();
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp index 8f67677..b50753e2 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp
@@ -172,6 +172,10 @@ return canvas()->buffer()->isAccelerated(); } +bool CanvasRenderingContext2D::isComposited() const { + return isAccelerated(); +} + void CanvasRenderingContext2D::stop() { if (!isContextLost()) { // Never attempt to restore the context because the page is being torn down. @@ -825,7 +829,7 @@ // anti-aliasing, which is expected when !creationAttributes().alpha(), so we // need to fall out of display list mode when drawing text to an opaque // canvas. crbug.com/583809 - if (!creationAttributes().alpha() && !isAccelerated()) { + if (!creationAttributes().alpha() && !isComposited()) { canvas()->disableDeferral( DisableDeferralReasonSubPixelTextAntiAliasingSupport); }
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h index a26642f..948a9fee 100644 --- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h +++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.h
@@ -233,6 +233,7 @@ return CanvasRenderingContext::Context2d; } bool is2d() const override { return true; } + bool isComposited() const override; bool isAccelerated() const override; bool hasAlpha() const override { return creationAttributes().alpha(); } void setIsHidden(bool) override;
diff --git a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp index 06b4cb9..2754fbbf 100644 --- a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp +++ b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp
@@ -8,6 +8,7 @@ #include "core/frame/ImageBitmap.h" #include "platform/graphics/GraphicsContext.h" #include "platform/graphics/StaticBitmapImage.h" +#include "platform/graphics/gpu/ImageLayerBridge.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkSurface.h" @@ -17,7 +18,9 @@ HTMLCanvasElement* canvas, const CanvasContextCreationAttributes& attrs, Document& document) - : CanvasRenderingContext(canvas, nullptr, attrs) {} + : CanvasRenderingContext(canvas, nullptr, attrs), + m_imageLayerBridge( + new ImageLayerBridge(attrs.alpha() ? NonOpaque : Opaque)) {} ImageBitmapRenderingContext::~ImageBitmapRenderingContext() {} @@ -29,50 +32,19 @@ void ImageBitmapRenderingContext::transferFromImageBitmap( ImageBitmap* imageBitmap, ExceptionState& exceptionState) { - if (!imageBitmap) { - m_image.release(); - return; - } - - if (imageBitmap->isNeutered()) { + if (imageBitmap && imageBitmap->isNeutered()) { exceptionState.throwDOMException(InvalidStateError, "The input ImageBitmap has been detached"); return; } - m_image = imageBitmap->bitmapImage(); - if (!m_image) - return; + m_imageLayerBridge->setImage(imageBitmap ? imageBitmap->bitmapImage() + : nullptr); - sk_sp<SkImage> skImage = m_image->imageForCurrentFrame(); - if (skImage->isTextureBacked()) { - // TODO(junov): crbug.com/585607 Eliminate this readback and use an - // ExternalTextureLayer - sk_sp<SkSurface> surface = - SkSurface::MakeRasterN32Premul(skImage->width(), skImage->height()); - if (!surface) { - // silent failure - m_image.clear(); - return; - } - surface->getCanvas()->drawImage(skImage, 0, 0); - m_image = StaticBitmapImage::create(surface->makeImageSnapshot()); - } - didDraw(skImage->bounds()); - imageBitmap->close(); -} + didDraw(); -bool ImageBitmapRenderingContext::paint(GraphicsContext& gc, const IntRect& r) { - if (!m_image) - return true; - - // With impl-side painting, it is unsafe to use a gpu-backed SkImage - DCHECK(!m_image->imageForCurrentFrame()->isTextureBacked()); - gc.drawImage(m_image.get(), r, nullptr, creationAttributes().alpha() - ? SkBlendMode::kSrcOver - : SkBlendMode::kSrc); - - return true; + if (imageBitmap) + imageBitmap->close(); } CanvasRenderingContext* ImageBitmapRenderingContext::Factory::create( @@ -85,7 +57,29 @@ } void ImageBitmapRenderingContext::stop() { - m_image.clear(); + m_imageLayerBridge->dispose(); +} + +PassRefPtr<Image> ImageBitmapRenderingContext::getImage(AccelerationHint, + SnapshotReason) const { + return m_imageLayerBridge->image(); +} + +WebLayer* ImageBitmapRenderingContext::platformLayer() const { + return m_imageLayerBridge->platformLayer(); +} + +bool ImageBitmapRenderingContext::isPaintable() const { + return !!m_imageLayerBridge->image(); +} + +DEFINE_TRACE(ImageBitmapRenderingContext) { + visitor->trace(m_imageLayerBridge); + CanvasRenderingContext::trace(visitor); +} + +bool ImageBitmapRenderingContext::isAccelerated() const { + return m_imageLayerBridge->isAccelerated(); } } // blink
diff --git a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.h b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.h index e25afe7b..298b0421 100644 --- a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.h +++ b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.h
@@ -13,6 +13,7 @@ namespace blink { class ImageBitmap; +class ImageLayerBridge; class MODULES_EXPORT ImageBitmapRenderingContext final : public CanvasRenderingContext { @@ -34,6 +35,8 @@ } }; + DECLARE_TRACE(); + // Script API void transferFromImageBitmap(ImageBitmap*, ExceptionState&); @@ -43,20 +46,18 @@ } void setIsHidden(bool) override {} bool isContextLost() const override { return false; } - bool paint(GraphicsContext&, const IntRect&) override; void setCanvasGetContextResult(RenderingContext&) final; - PassRefPtr<Image> getImage(AccelerationHint, SnapshotReason) const final { - return m_image.get(); - } + PassRefPtr<Image> getImage(AccelerationHint, SnapshotReason) const final; + bool isComposited() const final { return true; } + bool isAccelerated() const final; - // TODO(junov): Implement GPU accelerated rendering using a layer bridge - WebLayer* platformLayer() const override { return nullptr; } + WebLayer* platformLayer() const final; // TODO(junov): handle lost contexts when content is GPU-backed void loseContext(LostContextMode) override {} void stop() override; - bool isPaintable() const final { return m_image.get(); } + bool isPaintable() const final; virtual ~ImageBitmapRenderingContext(); @@ -65,7 +66,7 @@ const CanvasContextCreationAttributes&, Document&); - RefPtr<Image> m_image; + Member<ImageLayerBridge> m_imageLayerBridge; }; DEFINE_TYPE_CASTS(ImageBitmapRenderingContext,
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp index a522c1d..1acaab85 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.cpp
@@ -251,4 +251,8 @@ bool OffscreenCanvasRenderingContext2D::isPaintable() const { return this->imageBuffer(); } + +bool OffscreenCanvasRenderingContext2D::isAccelerated() const { + return m_imageBuffer && m_imageBuffer->isAccelerated(); +} }
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h index cd30654..14c2a68 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.h
@@ -43,6 +43,8 @@ ~OffscreenCanvasRenderingContext2D() override; ContextType getContextType() const override { return Context2d; } bool is2d() const override { return true; } + bool isComposited() const override { return false; } + bool isAccelerated() const override; void setOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final; void setIsHidden(bool) final { NOTREACHED(); } void stop() final { NOTREACHED(); }
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp index 63e2214..506ec9d 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp +++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
@@ -685,8 +685,8 @@ DOMException::create(InvalidStateError, "Already called show() once")); } - if (!scriptState->contextIsValid() || !scriptState->domWindow() || - !scriptState->domWindow()->frame()) { + if (!scriptState->contextIsValid() || !LocalDOMWindow::from(scriptState) || + !LocalDOMWindow::from(scriptState)->frame()) { return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(InvalidStateError, "Cannot show the payment request"));
diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.cpp b/third_party/WebKit/Source/modules/sensor/Sensor.cpp index 530bb5b..30154f2 100644 --- a/third_party/WebKit/Source/modules/sensor/Sensor.cpp +++ b/third_party/WebKit/Source/modules/sensor/Sensor.cpp
@@ -90,7 +90,7 @@ return 0.0; } - LocalDOMWindow* window = scriptState->domWindow(); + LocalDOMWindow* window = LocalDOMWindow::from(scriptState); if (!window) { isNull = true; return 0.0;
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp index 2db5946..0376293 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioContext.cpp
@@ -184,7 +184,7 @@ void AudioContext::getOutputTimestamp(ScriptState* scriptState, AudioTimestamp& result) { DCHECK(isMainThread()); - LocalDOMWindow* window = scriptState->domWindow(); + LocalDOMWindow* window = LocalDOMWindow::from(scriptState); if (!window) return;
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index 3982dddc..96ca350 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -5162,8 +5162,7 @@ // float/integer/sRGB internal format. // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is // upgraded to handle more formats. - if (!canvas->renderingContext() || - !canvas->renderingContext()->isAccelerated() || + if (!canvas->isAccelerated() || !canUseTexImageByGPU(functionID, internalformat, type)) { // 2D canvas has only FrontBuffer. texImageImpl(functionID, target, level, internalformat, xoffset, yoffset,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h index fb2455a..7d58fcf 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -624,6 +624,7 @@ // CanvasRenderingContext implementation. bool is3d() const override { return true; } + bool isComposited() const override { return true; } bool isAccelerated() const override { return true; } void setIsHidden(bool) override; bool paintRenderingResultsToCanvas(SourceDrawingBuffer) override;
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index 0f042591..7f0e2a39 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -976,6 +976,8 @@ "graphics/gpu/DrawingBuffer.h", "graphics/gpu/Extensions3DUtil.cpp", "graphics/gpu/Extensions3DUtil.h", + "graphics/gpu/ImageLayerBridge.cpp", + "graphics/gpu/ImageLayerBridge.h", "graphics/gpu/SharedContextRateLimiter.cpp", "graphics/gpu/SharedContextRateLimiter.h", "graphics/gpu/SharedGpuContext.cpp",
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp index a923d79..baef5a9 100644 --- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp +++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -981,8 +981,9 @@ #if USE_IOSURFACE_FOR_2D_CANVAS DCHECK(!releasedMailboxInfo->m_imageInfo); #endif // USE_IOSURFACE_FOR_2D_CANVAS - if (syncToken.HasData()) { - contextGL()->WaitSyncTokenCHROMIUM(syncToken.GetConstData()); + gpu::gles2::GLES2Interface* gl = contextGL(); + if (syncToken.HasData() && gl) { + gl->WaitSyncTokenCHROMIUM(syncToken.GetConstData()); } GrTexture* texture = releasedMailboxInfo->m_image->getTexture(); if (texture) { @@ -992,7 +993,6 @@ texture->textureParamsModified(); // Break the mailbox association to avoid leaking mailboxes every time // skia recycles a texture. - gpu::gles2::GLES2Interface* gl = contextGL(); if (gl) gl->ProduceTextureDirectCHROMIUM( 0, GL_TEXTURE_2D, releasedMailboxInfo->m_mailbox.name);
diff --git a/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.h b/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.h index 2a203df..131754a4 100644 --- a/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.h +++ b/third_party/WebKit/Source/platform/graphics/StaticBitmapImage.h
@@ -37,7 +37,6 @@ // Methods that have a default implementation, and overrided by only one // sub-class virtual bool hasMailbox() { return false; } - virtual void transfer() {} // Methods overrided by AcceleratedStaticBitmapImage only
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp index 6fdb064..8b326cb 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
@@ -715,6 +715,15 @@ propertyTrees().scroll_tree.FindNodeIndexFromOwningLayerId(layer->id()); EXPECT_EQ(scrollNodeIndex, scrollNode.id); + // Only one content layer, and the first child layer is the dummy layer for + // the transform node. + const cc::Layer* transformNodeLayer = rootLayer()->children()[0].get(); + EXPECT_EQ(transformNodeLayer->id(), transformNode.owning_layer_id); + auto transformNodeIndex = + propertyTrees().transform_tree.FindNodeIndexFromOwningLayerId( + transformNodeLayer->id()); + EXPECT_EQ(transformNodeIndex, transformNode.id); + EXPECT_EQ(0u, scrollClient.didScrollCount); layer->SetScrollOffsetFromImplSide(gfx::ScrollOffset(1, 2)); EXPECT_EQ(1u, scrollClient.didScrollCount); @@ -1589,6 +1598,34 @@ EXPECT_EQ(2, elementIdToTransformNodeIndex(expectedCompositorElementId)); } +TEST_F(PaintArtifactCompositorTestWithPropertyTrees, + TransformNodeHasOwningLayerId) { + RefPtr<TransformPaintPropertyNode> transform = + TransformPaintPropertyNode::create( + TransformPaintPropertyNode::root(), TransformationMatrix().rotate(90), + FloatPoint3D(100, 100, 0), false, 0, CompositingReason3DTransform); + + TestPaintArtifact artifact; + artifact + .chunk(transform, ClipPaintPropertyNode::root(), + EffectPaintPropertyNode::root()) + .rectDrawing(FloatRect(100, 100, 200, 100), Color::black); + update(artifact.build()); + + // Only one content layer, and the first child layer is the dummy layer for + // the transform node. + ASSERT_EQ(1u, contentLayerCount()); + const cc::Layer* transformNodeLayer = rootLayer()->children()[0].get(); + const cc::TransformNode* ccTransformNode = + propertyTrees().transform_tree.Node( + transformNodeLayer->transform_tree_index()); + EXPECT_EQ(transformNodeLayer->id(), ccTransformNode->owning_layer_id); + auto transformNodeIndex = + propertyTrees().transform_tree.FindNodeIndexFromOwningLayerId( + transformNodeLayer->id()); + EXPECT_EQ(transformNodeIndex, ccTransformNode->id); +} + TEST_F(PaintArtifactCompositorTestWithPropertyTrees, EffectWithElementId) { CompositorElementId expectedCompositorElementId(2, 0); float opacity = 2.0 / 255.0;
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp index 370a6416..50c72f9 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp
@@ -74,6 +74,12 @@ transformTree.Insert(cc::TransformNode(), kRealRootNodeId)); DCHECK_EQ(transformNode.id, kSecondaryRootNodeId); transformNode.source_node_id = transformNode.parent_id; + // Setting owning layer id on cc property tree transform nodes is temporary + // until we can remove animation subsystem dependency on layer + // references. http://crbug.com/709137 + transformNode.owning_layer_id = m_rootLayer->id(); + transformTree.SetOwningLayerIdForNode(&transformNode, + transformNode.owning_layer_id); // TODO(jaydasika): We shouldn't set ToScreen and FromScreen of root // transform node here. They should be set while updating transform tree in @@ -163,6 +169,12 @@ cc::TransformNode& compositorNode = *transformTree().Node(id); compositorNode.source_node_id = parentId; + // Setting owning layer id on cc property tree transform nodes is temporary + // until we can remove animation subsystem dependency on layer + // references. http://crbug.com/709137 + compositorNode.owning_layer_id = dummyLayer->id(); + transformTree().SetOwningLayerIdForNode(&compositorNode, + compositorNode.owning_layer_id); FloatPoint3D origin = transformNode->origin(); compositorNode.pre_local.matrix().setTranslate(-origin.x(), -origin.y(),
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.cpp new file mode 100644 index 0000000..e31bc9b --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.cpp
@@ -0,0 +1,181 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/graphics/gpu/ImageLayerBridge.h" + +#include "cc/resources/shared_bitmap.h" +#include "cc/resources/texture_mailbox.h" +#include "gpu/command_buffer/client/gles2_interface.h" +#include "platform/graphics/ColorBehavior.h" +#include "platform/graphics/GraphicsLayer.h" +#include "platform/graphics/gpu/SharedGpuContext.h" +#include "public/platform/Platform.h" +#include "public/platform/WebCompositorSupport.h" +#include "public/platform/WebExternalTextureLayer.h" +#include "public/platform/WebGraphicsContext3DProvider.h" + +namespace blink { + +ImageLayerBridge::ImageLayerBridge(OpacityMode opacityMode) + : m_weakPtrFactory(this), m_opacityMode(opacityMode) { + m_layer = + Platform::current()->compositorSupport()->createExternalTextureLayer( + this); + GraphicsLayer::registerContentsLayer(m_layer->layer()); + m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); + if (m_opacityMode == Opaque) { + m_layer->setOpaque(true); + m_layer->setBlendBackgroundColor(false); + } +} + +ImageLayerBridge::~ImageLayerBridge() { + if (!m_disposed) + dispose(); +} + +void ImageLayerBridge::setImage(PassRefPtr<StaticBitmapImage> image) { + m_image = std::move(image); + if (m_image) { + if (m_opacityMode == NonOpaque) { + m_layer->setOpaque(m_image->currentFrameKnownToBeOpaque()); + m_layer->setBlendBackgroundColor(!m_image->currentFrameKnownToBeOpaque()); + } + } + if (!m_hasPresentedSinceLastSetImage && m_image && + m_image->isTextureBacked()) { + // If the layer bridge is not presenting, the GrContext may not be getting + // flushed regularly. The flush is normally triggered inside the + // m_image->ensureMailbox() call of + // ImageLayerBridge::PrepareTextureMailbox. To prevent a potential memory + // leak we must flush the GrContext here. + m_image->imageForCurrentFrame()->getTextureHandle( + true); // GrContext flush. + } + m_hasPresentedSinceLastSetImage = false; +} + +void ImageLayerBridge::dispose() { + if (m_layer) { + GraphicsLayer::unregisterContentsLayer(m_layer->layer()); + m_layer->clearTexture(); + m_layer.reset(); + } + m_image = nullptr; + m_disposed = true; +} + +bool ImageLayerBridge::PrepareTextureMailbox( + cc::TextureMailbox* outMailbox, + std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { + if (m_disposed) + return false; + + if (!m_image) + return false; + + if (m_hasPresentedSinceLastSetImage) + return false; + + m_hasPresentedSinceLastSetImage = true; + + if (m_image->isTextureBacked()) { + m_image->ensureMailbox(); + *outMailbox = cc::TextureMailbox(m_image->mailbox(), m_image->syncToken(), + GL_TEXTURE_2D); + auto func = WTF::bind(&ImageLayerBridge::mailboxReleasedGpu, + m_weakPtrFactory.createWeakPtr(), m_image); + *outReleaseCallback = cc::SingleReleaseCallback::Create( + convertToBaseCallback(std::move(func))); + } else { + std::unique_ptr<cc::SharedBitmap> bitmap = createOrRecycleBitmap(); + if (!bitmap) + return false; + + sk_sp<SkImage> skImage = m_image->imageForCurrentFrame(); + if (!skImage) + return false; + + SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(m_image->width(), 1); + size_t rowBytes = m_image->width() * 4; + + // loop to flip Y + for (int row = 0; row < m_image->height(); row++) { + if (!skImage->readPixels( + dstInfo, + bitmap->pixels() + rowBytes * (m_image->height() - 1 - row), + rowBytes, 0, row)) + return false; + } + + *outMailbox = cc::TextureMailbox( + bitmap.get(), gfx::Size(m_image->width(), m_image->height())); + auto func = WTF::bind(&ImageLayerBridge::mailboxReleasedSoftware, + m_weakPtrFactory.createWeakPtr(), + base::Passed(&bitmap), m_image->size()); + *outReleaseCallback = cc::SingleReleaseCallback::Create( + convertToBaseCallback(std::move(func))); + } + + outMailbox->set_nearest_neighbor(m_filterQuality == kNone_SkFilterQuality); + // TODO(junov): Figure out how to get the color space info. + // outMailbox->set_color_space(); + + return true; +} + +std::unique_ptr<cc::SharedBitmap> ImageLayerBridge::createOrRecycleBitmap() { + auto it = std::remove_if(m_recycledBitmaps.begin(), m_recycledBitmaps.end(), + [this](const RecycledBitmap& bitmap) { + return bitmap.size != m_image->size(); + }); + m_recycledBitmaps.shrink(it - m_recycledBitmaps.begin()); + + if (!m_recycledBitmaps.isEmpty()) { + RecycledBitmap recycled = std::move(m_recycledBitmaps.back()); + m_recycledBitmaps.pop_back(); + DCHECK(recycled.size == m_image->size()); + return std::move(recycled.bitmap); + } + return Platform::current()->allocateSharedBitmap(m_image->size()); +} + +void ImageLayerBridge::mailboxReleasedGpu(RefPtr<StaticBitmapImage> image, + const gpu::SyncToken& token, + bool lostResource) { + if (image) { + DCHECK(image->isTextureBacked()); + if (token.HasData()) { + if (image->hasMailbox()) { + image->updateSyncToken(token); + } else { + // Wait on sync token now because SkiaTextureHolder does not know + // about sync tokens. + gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl(); + if (sharedGL) + sharedGL->WaitSyncTokenCHROMIUM(token.GetConstData()); + } + } + } + // let 'image' go out of scope to finalize the release. The + // destructor will wait on sync token before deleting resource. +} + +void ImageLayerBridge::mailboxReleasedSoftware( + std::unique_ptr<cc::SharedBitmap> bitmap, + const IntSize& size, + const gpu::SyncToken& syncToken, + bool lostResource) { + DCHECK(!syncToken.HasData()); // No sync tokens for software resources. + if (!m_disposed && !lostResource) { + RecycledBitmap recycled = {std::move(bitmap), size}; + m_recycledBitmaps.push_back(std::move(recycled)); + } +} + +WebLayer* ImageLayerBridge::platformLayer() const { + return m_layer->layer(); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.h b/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.h new file mode 100644 index 0000000..b2811a8 --- /dev/null +++ b/third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.h
@@ -0,0 +1,84 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ImageLayerBridge_h +#define ImageLayerBridge_h + +#include "cc/layers/texture_layer_client.h" +#include "platform/PlatformExport.h" +#include "platform/graphics/StaticBitmapImage.h" +#include "platform/heap/Heap.h" +#include "wtf/WeakPtr.h" + +namespace cc { +class SharedBitmap; +} + +namespace blink { + +class WebLayer; +class WebExternalTextureLayer; + +class PLATFORM_EXPORT ImageLayerBridge + : public GarbageCollectedFinalized<ImageLayerBridge>, + NON_EXPORTED_BASE(public cc::TextureLayerClient) { + WTF_MAKE_NONCOPYABLE(ImageLayerBridge); + + public: + ImageLayerBridge(OpacityMode); + ~ImageLayerBridge(); + + void setImage(PassRefPtr<StaticBitmapImage>); + void dispose(); + + // cc::TextureLayerClient implementation. + bool PrepareTextureMailbox( + cc::TextureMailbox* outMailbox, + std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) override; + + void mailboxReleasedGpu(RefPtr<StaticBitmapImage>, + const gpu::SyncToken&, + bool lostResource); + + void mailboxReleasedSoftware(std::unique_ptr<cc::SharedBitmap>, + const IntSize&, + const gpu::SyncToken&, + bool lostResource); + + RefPtr<StaticBitmapImage> image() { return m_image; } + + WebLayer* platformLayer() const; + + void setFilterQuality(SkFilterQuality filterQuality) { + m_filterQuality = filterQuality; + } + + bool isAccelerated() { return m_image->isTextureBacked(); } + + DEFINE_INLINE_TRACE() {} + + private: + std::unique_ptr<cc::SharedBitmap> createOrRecycleBitmap(); + + WeakPtrFactory<ImageLayerBridge> m_weakPtrFactory; + RefPtr<StaticBitmapImage> m_image; + std::unique_ptr<WebExternalTextureLayer> m_layer; + SkFilterQuality m_filterQuality = kLow_SkFilterQuality; + + // Shared memory bitmaps that were released by the compositor and can be used + // again by this ImageLayerBridge. + struct RecycledBitmap { + std::unique_ptr<cc::SharedBitmap> bitmap; + IntSize size; + }; + Vector<RecycledBitmap> m_recycledBitmaps; + + bool m_disposed = false; + bool m_hasPresentedSinceLastSetImage = false; + OpacityMode m_opacityMode = NonOpaque; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/platform/wtf/CheckedNumeric.h b/third_party/WebKit/Source/platform/wtf/CheckedNumeric.h index f94ba48..d383e59 100644 --- a/third_party/WebKit/Source/platform/wtf/CheckedNumeric.h +++ b/third_party/WebKit/Source/platform/wtf/CheckedNumeric.h
@@ -32,6 +32,22 @@ namespace WTF { using base::CheckedNumeric; +using base::IsValidForType; +using base::ValueOrDieForType; +using base::ValueOrDefaultForType; +using base::MakeCheckedNum; +using base::CheckMax; +using base::CheckMin; +using base::CheckAdd; +using base::CheckSub; +using base::CheckMul; +using base::CheckDiv; +using base::CheckMod; +using base::CheckLsh; +using base::CheckRsh; +using base::CheckAnd; +using base::CheckOr; +using base::CheckXor; } // namespace WTF using WTF::CheckedNumeric;
diff --git a/third_party/WebKit/Source/platform/wtf/HashMap.h b/third_party/WebKit/Source/platform/wtf/HashMap.h index b46b7e7..7598cfb 100644 --- a/third_party/WebKit/Source/platform/wtf/HashMap.h +++ b/third_party/WebKit/Source/platform/wtf/HashMap.h
@@ -523,7 +523,7 @@ typename HashMap<T, U, V, W, X, Y>::AddResult HashMap<T, U, V, W, X, Y>::inlineAdd(IncomingKeyType&& key, IncomingMappedType&& mapped) { - return m_impl.template add<HashMapTranslator<ValueTraits, HashFunctions>>( + return m_impl.template insert<HashMapTranslator<ValueTraits, HashFunctions>>( std::forward<IncomingKeyType>(key), std::forward<IncomingMappedType>(mapped)); }
diff --git a/third_party/WebKit/Source/platform/wtf/HashSet.h b/third_party/WebKit/Source/platform/wtf/HashSet.h index 927c325..8b140eb0 100644 --- a/third_party/WebKit/Source/platform/wtf/HashSet.h +++ b/third_party/WebKit/Source/platform/wtf/HashSet.h
@@ -254,7 +254,7 @@ template <typename IncomingValueType> inline typename HashSet<T, U, V, W>::AddResult HashSet<T, U, V, W>::insert( IncomingValueType&& value) { - return m_impl.add(std::forward<IncomingValueType>(value)); + return m_impl.insert(std::forward<IncomingValueType>(value)); } template <typename Value, @@ -267,7 +267,7 @@ // Forward only the first argument, because the second argument isn't actually // used in HashSetTranslatorAdapter. return m_impl - .template addPassingHashCode<HashSetTranslatorAdapter<HashTranslator>>( + .template insertPassingHashCode<HashSetTranslatorAdapter<HashTranslator>>( std::forward<T>(value), value); }
diff --git a/third_party/WebKit/Source/platform/wtf/HashTable.h b/third_party/WebKit/Source/platform/wtf/HashTable.h index 1950b1f..8f44777 100644 --- a/third_party/WebKit/Source/platform/wtf/HashTable.h +++ b/third_party/WebKit/Source/platform/wtf/HashTable.h
@@ -729,18 +729,18 @@ void reserveCapacityForSize(unsigned size); template <typename IncomingValueType> - AddResult add(IncomingValueType&& value) { - return add<IdentityTranslatorType>(Extractor::extract(value), - std::forward<IncomingValueType>(value)); + AddResult insert(IncomingValueType&& value) { + return insert<IdentityTranslatorType>( + Extractor::extract(value), std::forward<IncomingValueType>(value)); } - // A special version of add() that finds the object by hashing and comparing - // with some other type, to avoid the cost of type conversion if the object - // is already in the table. + // A special version of insert() that finds the object by hashing and + // comparing with some other type, to avoid the cost of type conversion if the + // object is already in the table. template <typename HashTranslator, typename T, typename Extra> - AddResult add(T&& key, Extra&&); + AddResult insert(T&& key, Extra&&); template <typename HashTranslator, typename T, typename Extra> - AddResult addPassingHashCode(T&& key, Extra&&); + AddResult insertPassingHashCode(T&& key, Extra&&); iterator find(KeyPeekInType key) { return find<IdentityTranslatorType>(key); } const_iterator find(KeyPeekInType key) const { @@ -1229,7 +1229,7 @@ KeyTraits, Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>:: - add(T&& key, Extra&& extra) { + insert(T&& key, Extra&& extra) { DCHECK(!accessForbidden()); DCHECK(Allocator::isAllocationAllowed()); if (!m_table) @@ -1325,7 +1325,7 @@ KeyTraits, Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>:: - addPassingHashCode(T&& key, Extra&& extra) { + insertPassingHashCode(T&& key, Extra&& extra) { DCHECK(!accessForbidden()); DCHECK(Allocator::isAllocationAllowed()); if (!m_table) @@ -1833,7 +1833,7 @@ // table. It might be more efficient to copy the table slots, but it's not // clear that efficiency is needed. for (const auto& element : other) - add(element); + insert(element); } template <typename Key,
diff --git a/third_party/WebKit/Source/platform/wtf/LinkedHashSet.h b/third_party/WebKit/Source/platform/wtf/LinkedHashSet.h index 67ec1a1d..741b74a6 100644 --- a/third_party/WebKit/Source/platform/wtf/LinkedHashSet.h +++ b/third_party/WebKit/Source/platform/wtf/LinkedHashSet.h
@@ -284,7 +284,7 @@ IncomingValueType&& newValue); template <typename IncomingValueType> AddResult insertBefore(iterator it, IncomingValueType&& newValue) { - return m_impl.template add<NodeHashFunctions>( + return m_impl.template insert<NodeHashFunctions>( std::forward<IncomingValueType>(newValue), it.getNode()); } @@ -814,7 +814,7 @@ typename LinkedHashSet<Value, HashFunctions, Traits, Allocator>::AddResult LinkedHashSet<Value, HashFunctions, Traits, Allocator>::insert( IncomingValueType&& value) { - return m_impl.template add<NodeHashFunctions>( + return m_impl.template insert<NodeHashFunctions>( std::forward<IncomingValueType>(value), &m_anchor); } @@ -822,8 +822,9 @@ template <typename IncomingValueType> typename LinkedHashSet<T, U, V, W>::iterator LinkedHashSet<T, U, V, W>::addReturnIterator(IncomingValueType&& value) { - typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions>( - std::forward<IncomingValueType>(value), &m_anchor); + typename ImplType::AddResult result = + m_impl.template insert<NodeHashFunctions>( + std::forward<IncomingValueType>(value), &m_anchor); return makeIterator(result.storedValue); } @@ -831,8 +832,9 @@ template <typename IncomingValueType> typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::appendOrMoveToLast(IncomingValueType&& value) { - typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions>( - std::forward<IncomingValueType>(value), &m_anchor); + typename ImplType::AddResult result = + m_impl.template insert<NodeHashFunctions>( + std::forward<IncomingValueType>(value), &m_anchor); Node* node = result.storedValue; if (!result.isNewEntry) { node->unlink(); @@ -845,8 +847,9 @@ template <typename IncomingValueType> typename LinkedHashSet<T, U, V, W>::AddResult LinkedHashSet<T, U, V, W>::prependOrMoveToFirst(IncomingValueType&& value) { - typename ImplType::AddResult result = m_impl.template add<NodeHashFunctions>( - std::forward<IncomingValueType>(value), m_anchor.m_next); + typename ImplType::AddResult result = + m_impl.template insert<NodeHashFunctions>( + std::forward<IncomingValueType>(value), m_anchor.m_next); Node* node = result.storedValue; if (!result.isNewEntry) { node->unlink();
diff --git a/third_party/WebKit/Source/platform/wtf/ListHashSet.h b/third_party/WebKit/Source/platform/wtf/ListHashSet.h index 2cf4c18c..9c3a87f 100644 --- a/third_party/WebKit/Source/platform/wtf/ListHashSet.h +++ b/third_party/WebKit/Source/platform/wtf/ListHashSet.h
@@ -922,7 +922,7 @@ // because it lets it take lvalues by reference, but for our purposes it's // inconvenient, since it constrains us to be const, whereas the allocator // actually changes when it does allocations. - auto result = m_impl.template add<BaseTranslator>( + auto result = m_impl.template insert<BaseTranslator>( std::forward<IncomingValueType>(value), *this->getAllocator()); if (result.isNewEntry) appendNode(*result.storedValue); @@ -943,7 +943,7 @@ ListHashSet<T, inlineCapacity, U, V>::appendOrMoveToLast( IncomingValueType&& value) { createAllocatorIfNeeded(); - auto result = m_impl.template add<BaseTranslator>( + auto result = m_impl.template insert<BaseTranslator>( std::forward<IncomingValueType>(value), *this->getAllocator()); Node* node = *result.storedValue; if (!result.isNewEntry) @@ -958,7 +958,7 @@ ListHashSet<T, inlineCapacity, U, V>::prependOrMoveToFirst( IncomingValueType&& value) { createAllocatorIfNeeded(); - auto result = m_impl.template add<BaseTranslator>( + auto result = m_impl.template insert<BaseTranslator>( std::forward<IncomingValueType>(value), *this->getAllocator()); Node* node = *result.storedValue; if (!result.isNewEntry) @@ -974,7 +974,7 @@ iterator it, IncomingValueType&& newValue) { createAllocatorIfNeeded(); - auto result = m_impl.template add<BaseTranslator>( + auto result = m_impl.template insert<BaseTranslator>( std::forward<IncomingValueType>(newValue), *this->getAllocator()); if (result.isNewEntry) insertNodeBefore(it.getNode(), *result.storedValue);
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp index 3e218af..452dcaa 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.cpp +++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -710,7 +710,6 @@ .isScrollbarHandlingGestures()) break; endActiveFlingAnimation(); - m_client->cancelScheduledContentIntents(); m_positionOnFlingStart = WebPoint(event.x, event.y); m_globalPositionOnFlingStart = WebPoint(event.globalX, event.globalY); m_flingModifier = event.modifiers(); @@ -759,7 +758,6 @@ case WebInputEvent::GestureDoubleTap: if (m_webSettings->doubleTapToZoomEnabled() && minimumPageScaleFactor() != maximumPageScaleFactor()) { - m_client->cancelScheduledContentIntents(); animateDoubleTapZoom( flooredIntPoint(scaledEvent.positionInRootFrame())); } @@ -770,7 +768,6 @@ m_client->didHandleGestureEvent(event, eventCancelled); return eventResult; case WebInputEvent::GestureScrollBegin: - m_client->cancelScheduledContentIntents(); case WebInputEvent::GestureScrollEnd: case WebInputEvent::GestureScrollUpdate: case WebInputEvent::GestureFlingStart: @@ -817,12 +814,6 @@ switch (event.type()) { case WebInputEvent::GestureTap: { - m_client->cancelScheduledContentIntents(); - if (detectContentOnTouch(targetedEvent)) { - eventResult = WebInputEventResult::HandledSystem; - break; - } - // Don't trigger a disambiguation popup on sites designed for mobile // devices. Instead, assume that the page has been designed with big // enough buttons and links. Don't trigger a disambiguation popup when @@ -889,7 +880,6 @@ if (!mainFrameImpl() || !mainFrameImpl()->frameView()) break; - m_client->cancelScheduledContentIntents(); m_page->contextMenuController().clearContextMenu(); { ContextMenuAllowedScope scope; @@ -921,7 +911,6 @@ break; } case WebInputEvent::GestureShowPress: { - m_client->cancelScheduledContentIntents(); eventResult = mainFrameImpl()->frame()->eventHandler().handleGestureEvent( targetedEvent); break; @@ -4104,44 +4093,6 @@ m_layerTreeView->forceRecalculateRasterScales(); } -bool WebViewImpl::detectContentOnTouch( - const GestureEventWithHitTestResults& targetedEvent) { - if (!m_page->mainFrame()->isLocalFrame()) - return false; - - // Need a local copy of the hit test as - // setToShadowHostIfInUserAgentShadowRoot() will modify it. - HitTestResult touchHit = targetedEvent.hitTestResult(); - touchHit.setToShadowHostIfInRestrictedShadowRoot(); - - if (touchHit.isContentEditable()) - return false; - - Node* node = touchHit.innerNode(); - if (!node || !node->isTextNode()) - return false; - - // Ignore when tapping on links or nodes listening to click events, unless - // the click event is on the body element, in which case it's unlikely that - // the original node itself was intended to be clickable. - for (; node && !isHTMLBodyElement(*node); - node = LayoutTreeBuilderTraversal::parent(*node)) { - if (node->isLink() || node->willRespondToTouchEvents() || - node->willRespondToMouseClickEvents()) - return false; - } - - WebURL intent = m_client->detectContentIntentAt(touchHit); - if (!intent.isValid()) - return false; - - // This code is called directly after hit test code, with no user code - // running in between, thus it is assumed that the frame pointer is non-null. - bool isMainFrame = node ? node->document().frame()->isMainFrame() : true; - m_client->scheduleContentIntent(intent, isMainFrame); - return true; -} - WebViewScheduler* WebViewImpl::scheduler() const { return m_scheduler.get(); }
diff --git a/third_party/WebKit/Source/web/WebViewImpl.h b/third_party/WebKit/Source/web/WebViewImpl.h index 46f8d69..19df220 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.h +++ b/third_party/WebKit/Source/web/WebViewImpl.h
@@ -332,8 +332,6 @@ void mouseContextMenu(const WebMouseEvent&); void mouseDoubleClick(const WebMouseEvent&); - bool detectContentOnTouch( - const GestureEventWithHitTestResults& targetedEvent); bool startPageScaleAnimation(const IntPoint& targetPosition, bool useAnchor, float newScale,
diff --git a/third_party/WebKit/Source/web/tests/WebViewTest.cpp b/third_party/WebKit/Source/web/tests/WebViewTest.cpp index d7c8533b..7dfcc06 100644 --- a/third_party/WebKit/Source/web/tests/WebViewTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
@@ -1948,48 +1948,6 @@ EXPECT_EQ(fooUrl, webView->mainFrame()->document().url().string().utf8()); } -class ContentDetectorClient : public FrameTestHelpers::TestWebViewClient { - public: - ContentDetectorClient() { reset(); } - - WebURL detectContentIntentAt(const WebHitTestResult& hitTest) override { - m_contentDetectionRequested = true; - return m_contentDetectionResult; - } - - void scheduleContentIntent(const WebURL& url, bool isMainFrame) override { - m_scheduledIntentURL = url; - m_wasInMainFrame = isMainFrame; - } - - void cancelScheduledContentIntents() override { - m_pendingIntentsCancelled = true; - } - - void reset() { - m_contentDetectionRequested = false; - m_pendingIntentsCancelled = false; - m_scheduledIntentURL = WebURL(); - m_wasInMainFrame = false; - m_contentDetectionResult = WebURL(); - } - - bool contentDetectionRequested() const { return m_contentDetectionRequested; } - bool pendingIntentsCancelled() const { return m_pendingIntentsCancelled; } - const WebURL& scheduledIntentURL() const { return m_scheduledIntentURL; } - bool wasInMainFrame() const { return m_wasInMainFrame; } - void setContentDetectionResult(const WebURL& result) { - m_contentDetectionResult = result; - } - - private: - bool m_contentDetectionRequested; - bool m_pendingIntentsCancelled; - WebURL m_scheduledIntentURL; - bool m_wasInMainFrame; - WebURL m_contentDetectionResult; -}; - bool WebViewTest::tapElement(WebInputEvent::Type type, Element* element) { if (!element || !element->layoutObject()) return false; @@ -2040,86 +1998,6 @@ return IntSize(icbWidth, icbHeight); } -TEST_P(WebViewTest, DetectContentAroundPosition) { - registerMockedHttpURLLoad("content_listeners.html"); - - ContentDetectorClient client; - WebView* webView = m_webViewHelper.initializeAndLoad( - m_baseURL + "content_listeners.html", true, 0, &client); - webView->resize(WebSize(500, 300)); - webView->updateAllLifecyclePhases(); - runPendingTasks(); - - WebString clickListener = WebString::fromUTF8("clickListener"); - WebString touchstartListener = WebString::fromUTF8("touchstartListener"); - WebString mousedownListener = WebString::fromUTF8("mousedownListener"); - WebString noListener = WebString::fromUTF8("noListener"); - WebString link = WebString::fromUTF8("link"); - - // Ensure content detection is not requested for nodes listening to click, - // mouse or touch events when we do simple taps. - EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, clickListener)); - EXPECT_FALSE(client.contentDetectionRequested()); - client.reset(); - - EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, touchstartListener)); - EXPECT_FALSE(client.contentDetectionRequested()); - client.reset(); - - EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, mousedownListener)); - EXPECT_FALSE(client.contentDetectionRequested()); - client.reset(); - - // Content detection should work normally without these event listeners. - // The click listener in the body should be ignored as a special case. - EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, noListener)); - EXPECT_TRUE(client.contentDetectionRequested()); - EXPECT_FALSE(client.scheduledIntentURL().isValid()); - - WebURL intentURL = toKURL(m_baseURL); - client.setContentDetectionResult(intentURL); - EXPECT_TRUE(tapElementById(WebInputEvent::GestureTap, noListener)); - EXPECT_TRUE(client.scheduledIntentURL() == intentURL); - EXPECT_TRUE(client.wasInMainFrame()); - - // Tapping elsewhere should cancel the scheduled intent. - WebGestureEvent event(WebInputEvent::GestureTap, WebInputEvent::NoModifiers, - WebInputEvent::TimeStampForTesting); - event.sourceDevice = WebGestureDeviceTouchscreen; - webView->handleInputEvent(WebCoalescedInputEvent(event)); - runPendingTasks(); - EXPECT_TRUE(client.pendingIntentsCancelled()); - - // Explicitly reset to break dependency on locally scoped client. - m_webViewHelper.reset(); -} - -TEST_P(WebViewTest, ContentDetectionInIframe) { - registerMockedHttpURLLoad("content_listeners_iframe.html"); - - ContentDetectorClient client; - WebView* webView = m_webViewHelper.initializeAndLoad( - m_baseURL + "content_listeners_iframe.html", true, 0, &client); - webView->resize(WebSize(500, 300)); - webView->updateAllLifecyclePhases(); - runPendingTasks(); - - WebString noListener = WebString::fromUTF8("noListener"); - WebString frameName = WebString::fromUTF8("innerFrame"); - - WebURL intentURL = toKURL(m_baseURL); - client.setContentDetectionResult(intentURL); - Element* element = static_cast<Element*>( - webView->findFrameByName(frameName)->document().getElementById( - noListener)); - EXPECT_TRUE(tapElement(WebInputEvent::GestureTap, element)); - EXPECT_TRUE(client.scheduledIntentURL() == intentURL); - EXPECT_FALSE(client.wasInMainFrame()); - - // Explicitly reset to break dependency on locally scoped client. - m_webViewHelper.reset(); -} - TEST_P(WebViewTest, ClientTapHandling) { TapHandlingWebViewClient client; client.reset();
diff --git a/third_party/WebKit/Source/web/tests/data/content_listeners.html b/third_party/WebKit/Source/web/tests/data/content_listeners.html deleted file mode 100644 index ff924c8..0000000 --- a/third_party/WebKit/Source/web/tests/data/content_listeners.html +++ /dev/null
@@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<style> -span { - font-size: 300%; -} -</style> -<script> -function listener() { -} -</script> -</head> -<body onclick="listener()"> -<span id="clickListener" onclick="listener()"> -This has a click listener. -</span></br> -<span id="touchstartListener" ontouchstart="listener()"> -This has a touchstart listener. -</span></br> -<span id="mousedownListener" onmousedown="listener()"> -This has a mousedown listener. -</span></br> -<span id="noListener"> -This has no specific listener (the body listener should be ignored). -</span></br> -<a href="http://www.test.com/" id="link"> -This has no specific listener, but it's a link. -</a></br> -</body> -</html>
diff --git a/third_party/WebKit/Source/web/tests/data/content_listeners_iframe.html b/third_party/WebKit/Source/web/tests/data/content_listeners_iframe.html deleted file mode 100644 index 1dbda7b..0000000 --- a/third_party/WebKit/Source/web/tests/data/content_listeners_iframe.html +++ /dev/null
@@ -1,16 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<style> -body { - margin: 0; -} -iframe { - border: none; -} -</style> -</head> -<iframe srcdoc="<body style='margin:0;'><span style='font-size: 200%;' id='noListener'>This has no specific listener.</span></body>" - src="iframe.html" name="innerFrame"></iframe> -</body> -</html>
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py index 573e716..eafe8772 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py
@@ -28,6 +28,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import csv +import ctypes import errno import logging import multiprocessing @@ -38,8 +39,6 @@ import threading import time -from webkitpy.common.system.filesystem import FileSystem - _log = logging.getLogger(__name__) @@ -94,55 +93,37 @@ # multiple threads). See http://bugs.python.org/issue2320 . # Note that close_fds isn't supported on Windows, but this bug only # shows up on Mac and Linux. - return sys.platform not in ('win32', 'cygwin') + return sys.platform != 'win32' def cpu_count(self): return multiprocessing.cpu_count() def kill_process(self, pid): """Attempts to kill the given pid. + Will fail silently if pid does not exist or insufficient permissions. """ + # According to http://docs.python.org/library/os.html + # os.kill isn't available on Windows. if sys.platform == 'win32': - # We only use taskkill.exe on windows (not cygwin) because subprocess.pid - # is a CYGWIN pid and taskkill.exe expects a windows pid. - # Thankfully os.kill on CYGWIN handles either pid type. command = ['taskkill.exe', '/f', '/t', '/pid', pid] - # taskkill will exit 128 if the process is not found. We should log. + # taskkill will exit 128 if the process is not found. We should log. self.run_command(command, error_handler=self.ignore_error) return - # According to http://docs.python.org/library/os.html - # os.kill isn't available on Windows. python 2.5.5 os.kill appears - # to work in cygwin, however it occasionally raises EAGAIN. - retries_left = 10 if sys.platform == 'cygwin' else 1 - while retries_left > 0: - try: - retries_left -= 1 - os.kill(pid, signal.SIGKILL) - _ = os.waitpid(pid, os.WNOHANG) - except OSError as error: - if error.errno == errno.EAGAIN: - if retries_left <= 0: - _log.warning('Failed to kill pid %s. Too many EAGAIN errors.', pid) - continue - if error.errno == errno.ESRCH: # The process does not exist. - return - if error.errno == errno.EPIPE: # The process has exited already on cygwin - return - if error.errno == errno.ECHILD: - # Can't wait on a non-child process, but the kill worked. - return - if error.errno == errno.EACCES and sys.platform == 'cygwin': - # Cygwin python sometimes can't kill native processes. - return - raise + try: + os.kill(pid, signal.SIGKILL) + os.waitpid(pid, os.WNOHANG) + except OSError as error: + if error.errno == errno.ESRCH: + # The process does not exist. + return + if error.errno == errno.ECHILD: + # Can't wait on a non-child process, but the kill worked. + return + raise def _win32_check_running_pid(self, pid): - # importing ctypes at the top-level seems to cause weird crashes at - # exit under cygwin on apple's win port. Only win32 needs cygwin, so - # we import it here instead. See https://bugs.webkit.org/show_bug.cgi?id=91682 - import ctypes class PROCESSENTRY32(ctypes.Structure): _fields_ = [('dwSize', ctypes.c_ulong), @@ -192,7 +173,7 @@ def _running_processes(self): processes = [] - if sys.platform in ('win32', 'cygwin'): + if sys.platform == 'win32': tasklist_process = self.popen(['tasklist', '/fo', 'csv'], stdout=self.PIPE, stderr=self.PIPE) stdout, _ = tasklist_process.communicate() @@ -228,7 +209,7 @@ def process_dump(self): ps_process = None - if sys.platform in ('win32', 'cygwin'): + if sys.platform in 'win32': ps_process = self.popen( ['wmic', 'process', 'get', 'ProcessId,ParentProcessId,CommandLine'], @@ -383,11 +364,6 @@ return 'utf-8' def _should_encode_child_process_arguments(self): - # Cygwin's Python's os.execv doesn't support unicode command - # arguments, and neither does Cygwin's execv itself. - if sys.platform == 'cygwin': - return True - # Win32 Python 2.x uses CreateProcessA rather than CreateProcessW # to launch subprocesses, so we have to encode arguments using the # current code page. @@ -421,7 +397,7 @@ return self.map(_run_command_thunk, command_lines_and_cwds, processes) def map(self, thunk, arglist, processes=None): - if sys.platform in ('cygwin', 'win32') or len(arglist) == 1: + if sys.platform == 'win32' or len(arglist) == 1: return map(thunk, arglist) pool = multiprocessing.Pool(processes=(processes or multiprocessing.cpu_count())) try:
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_unittest.py index 68baecc..9318ca031 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_unittest.py
@@ -237,7 +237,7 @@ def test_maybe_make_directory__failure(self): # FIXME: os.chmod() doesn't work on Windows to set directories # as readonly, so we skip this test for now. - if sys.platform in ('win32', 'cygwin'): + if sys.platform == 'win32': return fs = FileSystem()
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/path.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/path.py index 01f5acb3..083773c 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/path.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/path.py
@@ -26,11 +26,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""generic routines to convert platform-specific paths to URIs.""" +"""Generic routines to convert platform-specific paths to URIs.""" -import atexit -import subprocess -import threading import urllib @@ -39,73 +36,6 @@ return 'file:' + _escape(_convert_path(platform, path)) -def cygpath(path): - """Converts an absolute cygwin path to an absolute Windows path.""" - return _CygPath.convert_using_singleton(path) - - -# Note that this object is not threadsafe and must only be called -# from multiple threads under protection of a lock (as is done in cygpath()) -class _CygPath(object): - """Manages a long-running 'cygpath' process for file conversion.""" - _lock = None - _singleton = None - - @staticmethod - def stop_cygpath_subprocess(): - if not _CygPath._lock: - return - - with _CygPath._lock: - if _CygPath._singleton: - _CygPath._singleton.stop() - - @staticmethod - def convert_using_singleton(path): - if not _CygPath._lock: - _CygPath._lock = threading.Lock() - - with _CygPath._lock: - if not _CygPath._singleton: - _CygPath._singleton = _CygPath() - # Make sure the cygpath subprocess always gets shutdown cleanly. - atexit.register(_CygPath.stop_cygpath_subprocess) - - return _CygPath._singleton.convert(path) - - def __init__(self): - self._child_process = None - - def start(self): - assert self._child_process is None - args = ['cygpath', '-f', '-', '-wa'] - self._child_process = subprocess.Popen(args, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE) - - def is_running(self): - if not self._child_process: - return False - return self._child_process.returncode is None - - def stop(self): - if self._child_process: - self._child_process.stdin.close() - self._child_process.wait() - self._child_process = None - - def convert(self, path): - if not self.is_running(): - self.start() - self._child_process.stdin.write('%s\r\n' % path) - self._child_process.stdin.flush() - windows_path = self._child_process.stdout.readline().rstrip() - # Some versions of cygpath use lowercase drive letters while others - # use uppercase. We always convert to uppercase for consistency. - windows_path = '%s%s' % (windows_path[0].upper(), windows_path[1:]) - return windows_path - - def _escape(path): """Handle any characters in the path that should be escaped.""" # FIXME: web browsers don't appear to blindly quote every character @@ -117,8 +47,6 @@ def _convert_path(platform, path): """Handles any os-specific path separators, mappings, etc.""" - if platform.is_cygwin(): - return _winpath_to_uri(cygpath(path)) if platform.is_win(): return _winpath_to_uri(path) return _unixypath_to_uri(path)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/path_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/path_unittest.py index 699a026a..b180ca9 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/path_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/path_unittest.py
@@ -39,12 +39,6 @@ def platform_info(self): return SystemHost().platform - def test_abspath_to_uri_cygwin(self): - if sys.platform != 'cygwin': - return - self.assertEqual(path.abspath_to_uri(self.platform_info(), '/cygdrive/c/foo/bar.html'), - 'file:///C:/foo/bar.html') - def test_abspath_to_uri_unixy(self): self.assertEqual(path.abspath_to_uri(MockPlatformInfo(), '/foo/bar.html'), 'file:///foo/bar.html') @@ -58,24 +52,3 @@ def test_abspath_to_uri_escaping_unixy(self): self.assertEqual(path.abspath_to_uri(MockPlatformInfo(), '/foo/bar + baz%?.html'), 'file:///foo/bar%20+%20baz%25%3F.html') - - # Note that you can't have '?' in a filename on windows. - def test_abspath_to_uri_escaping_cygwin(self): - if sys.platform != 'cygwin': - return - self.assertEqual(path.abspath_to_uri(self.platform_info(), '/cygdrive/c/foo/bar + baz%.html'), - 'file:///C:/foo/bar%20+%20baz%25.html') - - def test_stop_cygpath_subprocess(self): - if sys.platform != 'cygwin': - return - - # Call cygpath to ensure the subprocess is running. - path.cygpath('/cygdrive/c/foo.txt') - self.assertTrue(path._CygPath._singleton.is_running()) - - # Stop it. - path._CygPath.stop_cygpath_subprocess() - - # Ensure that it is stopped. - self.assertFalse(path._CygPath._singleton.is_running())
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info.py index 1b2c3739..7008067 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info.py
@@ -56,7 +56,7 @@ self.os_version = self._determine_mac_version(platform_module.mac_ver()[0]) if self.os_name.startswith('win'): self.os_version = self._determine_win_version(self._win_version_tuple(sys_module)) - self._is_cygwin = sys_module.platform == 'cygwin' + assert sys.platform != 'cygwin', 'Cygwin is not supported.' def is_mac(self): return self.os_name == 'mac' @@ -64,9 +64,6 @@ def is_win(self): return self.os_name == 'win' - def is_cygwin(self): - return self._is_cygwin - def is_linux(self): return self.os_name == 'linux' @@ -139,7 +136,7 @@ return 'mac' if sys_platform.startswith('linux'): return 'linux' - if sys_platform in ('win32', 'cygwin'): + if sys_platform == 'win32': return 'win' if sys_platform.startswith('freebsd'): return 'freebsd'
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info_mock.py index 5c1e0d0f..ee307cd 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info_mock.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info_mock.py
@@ -47,9 +47,6 @@ def is_highdpi(self): return self._is_highdpi - def is_cygwin(self): - return self.os_name == 'cygwin' - def is_freebsd(self): return self.os_name == 'freebsd'
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info_unittest.py index ff36290..a1e239a 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info_unittest.py
@@ -122,13 +122,6 @@ self.assertTrue(info.is_win()) self.assertFalse(info.is_freebsd()) - info = self.make_info(fake_sys('cygwin'), executive=fake_executive('6.1.7600')) - self.assertEqual(info.os_name, 'win') - self.assertFalse(info.is_linux()) - self.assertFalse(info.is_mac()) - self.assertTrue(info.is_win()) - self.assertFalse(info.is_freebsd()) - info = self.make_info(fake_sys('freebsd8')) self.assertEqual(info.os_name, 'freebsd') self.assertFalse(info.is_linux()) @@ -168,14 +161,6 @@ executive=fake_executive('5.0.1234')) self.assertRaises(AssertionError, self.make_info, fake_sys('win32'), executive=fake_executive('6.1.1234')) - self.assertEqual(self.make_info(fake_sys('cygwin'), executive=fake_executive('10.1.1234')).os_version, 'future') - self.assertEqual(self.make_info(fake_sys('cygwin'), executive=fake_executive('10.0.1234')).os_version, '10') - self.assertEqual(self.make_info(fake_sys('cygwin'), executive=fake_executive('6.3.1234')).os_version, '8.1') - self.assertEqual(self.make_info(fake_sys('cygwin'), executive=fake_executive('6.2.1234')).os_version, '8') - self.assertEqual(self.make_info(fake_sys('cygwin'), executive=fake_executive('6.1.7601')).os_version, '7sp1') - self.assertEqual(self.make_info(fake_sys('cygwin'), executive=fake_executive('6.1.7600')).os_version, '7sp0') - self.assertEqual(self.make_info(fake_sys('cygwin'), executive=fake_executive('6.0.1234')).os_version, 'vista') - self.assertEqual(self.make_info(fake_sys('cygwin'), executive=fake_executive('5.1.1234')).os_version, 'xp') def _assert_file_implies_linux_distribution(self, file_path, distribution): info = self.make_info(sys_module=fake_sys('linux2'), filesystem_module=MockFileSystem({file_path: ''})) @@ -187,9 +172,6 @@ self._assert_file_implies_linux_distribution('/etc/redhat-release', 'redhat') self._assert_file_implies_linux_distribution('/etc/mock-release', 'unknown') - info = self.make_info(fake_sys('cygwin'), executive=fake_executive('6.1.7600')) - self.assertIsNone(info.linux_distribution()) - def test_display_name(self): info = self.make_info(fake_sys('darwin')) self.assertNotEquals(info.display_name(), '') @@ -215,3 +197,7 @@ info = self.make_info(fake_sys('freebsd9')) self.assertIsNone(info.total_bytes_memory()) + + def test_unsupported_platform(self): + with self.assertRaises(AssertionError): + self.make_info(fake_sys('cygwin'))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py index 609f39c..c325f4d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py
@@ -45,7 +45,7 @@ from webkitpy.common import read_checksum_from_png from webkitpy.common.memoized import memoized from webkitpy.common.system.executive import ScriptError -from webkitpy.common.system.path import cygpath, abspath_to_uri +from webkitpy.common.system.path import abspath_to_uri from webkitpy.common.webkit_finder import WebKitFinder from webkitpy.layout_tests.layout_package.bot_test_expectations import BotTestExpectationsFactory from webkitpy.layout_tests.models import test_run_results @@ -439,14 +439,9 @@ diff_filename = self._filesystem.join(str(tempdir), 'diff.png') - # image_diff needs native win paths as arguments, so we need to convert them if running under cygwin. - native_expected_filename = self._convert_path(expected_filename) - native_actual_filename = self._convert_path(actual_filename) - native_diff_filename = self._convert_path(diff_filename) - executable = self._path_to_image_diff() # Although we are handed 'old', 'new', image_diff wants 'new', 'old'. - command = [executable, '--diff', native_actual_filename, native_expected_filename, native_diff_filename] + command = [executable, '--diff', actual_filename, expected_filename, diff_filename] result = None err_str = None @@ -456,7 +451,7 @@ # The images are the same. result = None elif exit_code == 1: - result = self._filesystem.read_binary_file(native_diff_filename) + result = self._filesystem.read_binary_file(diff_filename) else: err_str = 'Image diff returned an exit code of %s. See http://crbug.com/278596' % exit_code except OSError as error: @@ -1092,12 +1087,6 @@ 'PATH', 'GYP_DEFINES', # Required to locate win sdk. ] - if self.host.platform.is_cygwin(): - variables_to_copy += [ - 'HOMEDRIVE', - 'HOMEPATH', - '_NT_SYMBOL_PATH', - ] for variable in variables_to_copy: if variable in self.host.environ: @@ -1175,10 +1164,8 @@ self._wpt_server = None def http_server_supports_ipv6(self): - # Apache < 2.4 on win32 does not support IPv6, nor does cygwin apache. - if self.host.platform.is_cygwin() or self.host.platform.is_win(): - return False - return True + # Apache < 2.4 on win32 does not support IPv6. + return not self.host.platform.is_win() def stop_http_server(self): """Shuts down the http server if it is running.""" @@ -1390,8 +1377,6 @@ return re.sub(r'(?:.|\n)*Server version: Apache/(\d+\.\d+)(?:.|\n)*', r'\1', config) def _apache_config_file_name_for_platform(self): - if self.host.platform.is_cygwin(): - return 'cygwin-httpd.conf' # CYGWIN is the only platform to still use Apache 1.3. if self.host.platform.is_linux(): distribution = self.host.platform.linux_distribution() @@ -1573,13 +1558,6 @@ return any(test_input.test_name.startswith( directory) for directory in self._options.image_first_tests) - def _convert_path(self, path): - """Handles filename conversion for subprocess command line args.""" - # See note above in diff_image() for why we need this. - if sys.platform == 'cygwin': - return cygpath(path) - return path - def _build_path(self, *comps): return self._build_path_with_target(self._options.target, *comps)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py index 73616d9..f590167 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base_unittest.py
@@ -29,7 +29,6 @@ import functools import json import optparse -import tempfile import unittest from webkitpy.common.system.executive import ScriptError @@ -380,8 +379,6 @@ def test_http_server_supports_ipv6(self): port = self.make_port() self.assertTrue(port.http_server_supports_ipv6()) - port.host.platform.os_name = 'cygwin' - self.assertFalse(port.http_server_supports_ipv6()) port.host.platform.os_name = 'win' self.assertFalse(port.http_server_supports_ipv6()) @@ -516,9 +513,7 @@ def test_apache_config_file_name_for_platform(self): port = self.make_port() - # pylint: disable=protected-access - port._apache_version = lambda: '2.2' - self._assert_config_file_for_platform(port, 'cygwin', 'cygwin-httpd.conf') + port._apache_version = lambda: '2.2' # pylint: disable=protected-access self._assert_config_file_for_platform(port, 'linux', 'apache2-httpd-2.2.conf') self._assert_config_file_for_linux_distribution(port, 'arch', 'arch-httpd-2.2.conf') self._assert_config_file_for_linux_distribution(port, 'debian', 'debian-httpd-2.2.conf') @@ -526,7 +521,6 @@ self._assert_config_file_for_linux_distribution(port, 'redhat', 'redhat-httpd-2.2.conf') self._assert_config_file_for_platform(port, 'mac', 'apache2-httpd-2.2.conf') - # win32 isn't a supported sys.platform. AppleWin/WinCairo/WinCE ports all use cygwin. self._assert_config_file_for_platform(port, 'win32', 'apache2-httpd-2.2.conf') self._assert_config_file_for_platform(port, 'barf', 'apache2-httpd-2.2.conf')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/driver.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/driver.py index 4e381b6..ca3c7cf6 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/driver.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/driver.py
@@ -419,8 +419,6 @@ command = self.test_to_uri(driver_input.test_name) else: command = self._port.abspath_for_test(driver_input.test_name) - if sys.platform == 'cygwin': - command = path.cygpath(command) assert not driver_input.image_hash or driver_input.should_run_pixel_test
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/server_process.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/server_process.py index da9a1f2..125b785f 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/server_process.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/server_process.py
@@ -92,7 +92,6 @@ self._reset() # See comment in imports for why we need the win32 APIs and can't just use select. - # FIXME: there should be a way to get win32 vs. cygwin from platform_info. self._use_win32_apis = sys.platform == 'win32' def name(self): @@ -154,9 +153,9 @@ """ # FIXME: Linux and Mac set the returncode to -signal.SIGINT if a # subprocess is killed with a ctrl^C. Previous comments in this - # routine said that supposedly Windows returns 0xc000001d, but that's not what - # -1073741510 evaluates to. Figure out what the right value is - # for win32 and cygwin here ... + # routine said that supposedly Windows returns 0xc000001d, but that's + # not what -1073741510 evaluates to. Figure out what the right value + # is for win32 here ... if self._proc.returncode in (-1073741510, -signal.SIGINT): raise KeyboardInterrupt
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win.py index 883aaf7..3c7c8ea 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win.py
@@ -159,19 +159,12 @@ # FIXME: This is a temporary hack to get the cr-win bot online until # someone from the cr-win port can take a look. + # TODO(qyearsley): Remove this in a separate CL. apache_envvars = ['SYSTEMDRIVE', 'SYSTEMROOT', 'TEMP', 'TMP'] for key, value in self.host.environ.copy().items(): if key not in env and key in apache_envvars: env[key] = value - # Put the cygwin directory first in the path to find cygwin1.dll. - env['PATH'] = '%s;%s' % (self.path_from_chromium_base('third_party', 'cygwin', 'bin'), env['PATH']) - # Configure the cygwin directory so that pywebsocket finds proper - # python executable to run cgi program. - env['CYGWIN_PATH'] = self.path_from_chromium_base('third_party', 'cygwin', 'bin') - if self.get_option('register_cygwin'): - setup_mount = self.path_from_chromium_base('third_party', 'cygwin', 'setup_mount.bat') - self._executive.run_command([setup_mount]) # Paths are all absolute, so this does not require a cwd. return env def check_build(self, needs_http, printer):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win_unittest.py index dec8c057..1ee7183 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/win_unittest.py
@@ -48,19 +48,6 @@ orig_environ = port.host.environ.copy() env = output.assert_outputs(self, port.setup_environ_for_server) self.assertEqual(orig_environ['PATH'], port.host.environ.get('PATH')) - self.assertNotEqual(env['PATH'], port.host.environ.get('PATH')) - - def test_setup_environ_for_server_cygpath(self): - port = self.make_port() - env = port.setup_environ_for_server() - self.assertEqual(env['CYGWIN_PATH'], '/mock-checkout/third_party/cygwin/bin') - - def test_setup_environ_for_server_register_cygwin(self): - port = self.make_port(options=optparse.Values({'register_cygwin': True, 'results_directory': '/'})) - port._executive = MockExecutive(should_log=True) - expected_logs = "MOCK run_command: ['/mock-checkout/third_party/cygwin/setup_mount.bat'], cwd=None\n" - output = output_capture.OutputCapture() - output.assert_outputs(self, port.setup_environ_for_server, expected_logs=expected_logs) def assert_name(self, port_name, os_version_string, expected): port = self.make_port(port_name=port_name, os_version=os_version_string)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py index 0a09e50..02768f902 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_unittest.py
@@ -167,10 +167,6 @@ # Windows and Mac to skip some tests. self._platform = SystemHost().platform - # FIXME: Remove this when we fix test-webkitpy to work - # properly on cygwin (bug 63846). - self.should_test_processes = not self._platform.is_win() - def test_basic(self): options, args = parse_args( extra_args=['--json-test-results', '/tmp/json_test_results.json'], @@ -228,23 +224,19 @@ def test_max_locked_shards(self): # Tests for the default of using one locked shard even in the case of more than one child process. - if not self.should_test_processes: - return _, regular_output, _ = logging_run(['--debug-rwt-logging', '--child-processes', '2'], shared_port=False) self.assertTrue(any('1 locked' in line for line in regular_output.buflist)) def test_child_processes_2(self): - if self.should_test_processes: - _, regular_output, _ = logging_run( - ['--debug-rwt-logging', '--child-processes', '2'], shared_port=False) - self.assertTrue(any(['Running 2 ' in line for line in regular_output.buflist])) + _, regular_output, _ = logging_run( + ['--debug-rwt-logging', '--child-processes', '2'], shared_port=False) + self.assertTrue(any(['Running 2 ' in line for line in regular_output.buflist])) def test_child_processes_min(self): - if self.should_test_processes: - _, regular_output, _ = logging_run( - ['--debug-rwt-logging', '--child-processes', '2', '-i', 'passes/virtual_passes', 'passes'], - tests_included=True, shared_port=False) - self.assertTrue(any(['Running 1 ' in line for line in regular_output.buflist])) + _, regular_output, _ = logging_run( + ['--debug-rwt-logging', '--child-processes', '2', '-i', 'passes/virtual_passes', 'passes'], + tests_included=True, shared_port=False) + self.assertTrue(any(['Running 1 ' in line for line in regular_output.buflist])) def test_dryrun(self): tests_run = get_tests_run(['--dry-run']) @@ -269,13 +261,12 @@ self.assertRaises(BaseException, logging_run, ['failures/expected/exception.html', '--child-processes', '1'], tests_included=True) - if self.should_test_processes: - self.assertRaises( - BaseException, - logging_run, - ['--child-processes', '2', '--skipped=ignore', 'failures/expected/exception.html', 'passes/text.html'], - tests_included=True, - shared_port=False) + self.assertRaises( + BaseException, + logging_run, + ['--child-processes', '2', '--skipped=ignore', 'failures/expected/exception.html', 'passes/text.html'], + tests_included=True, + shared_port=False) def test_device_failure(self): # Test that we handle a device going offline during a test properly. @@ -295,11 +286,10 @@ details, _, _ = logging_run(['failures/expected/keyboard.html', '--child-processes', '1'], tests_included=True) self.assertEqual(details.exit_code, test_run_results.INTERRUPTED_EXIT_STATUS) - if self.should_test_processes: - _, regular_output, _ = logging_run( - ['failures/expected/keyboard.html', 'passes/text.html', '--child-processes', '2', '--skipped=ignore'], - tests_included=True, shared_port=False) - self.assertTrue(any(['Interrupted, exiting' in line for line in regular_output.buflist])) + _, regular_output, _ = logging_run( + ['failures/expected/keyboard.html', 'passes/text.html', '--child-processes', '2', '--skipped=ignore'], + tests_included=True, shared_port=False) + self.assertTrue(any(['Interrupted, exiting' in line for line in regular_output.buflist])) def test_no_tests_found(self): details, err, _ = logging_run(['resources'], tests_included=True) @@ -997,10 +987,6 @@ # see the verbose log output. However, we can't use logging_run() because using # output_capture to capture stdout and stderr latter results in a nonpicklable host. - # Test is flaky on Windows: https://bugs.webkit.org/show_bug.cgi?id=98559 - if not self.should_test_processes: - return - options, parsed_args = parse_args(['--verbose', '--fully-parallel', '--child-processes', '2', 'passes/text.html', 'passes/image.html'], tests_included=True) host = MockHost()
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_unittest.py index 8e1a9a5..f9bf3e6 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/apache_http_unittest.py
@@ -40,7 +40,7 @@ def test_start_cmd(self): # Fails on win - see https://bugs.webkit.org/show_bug.cgi?id=84726 - if sys.platform in ('cygwin', 'win32'): + if sys.platform == 'win32': return def fake_pid(_):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/crash_service_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/crash_service_unittest.py index acb9b021..6854863 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/crash_service_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/crash_service_unittest.py
@@ -39,7 +39,7 @@ def test_start_cmd(self): # Fails on win - see https://bugs.webkit.org/show_bug.cgi?id=84726 - if sys.platform in ('cygwin', 'win32'): + if sys.platform == 'win32': return host = MockHost() @@ -55,7 +55,6 @@ test_port._path_to_crash_service = lambda: "/mock/crash_service" host.platform.is_win = lambda: True - host.platform.is_cygwin = lambda: False server = CrashService(test_port, "/mock/crash_dumps_dir") server._check_that_all_ports_are_available = lambda: True
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/pretty_diff.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/pretty_diff.py index 9090224..5622813c 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/pretty_diff.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/pretty_diff.py
@@ -86,9 +86,5 @@ changed_files=changed_files) def _open_pretty_diff(self, file_path): - if self._tool.platform.is_cygwin(): - assert file_path.endswith('.html') - self._tool.executive.run_command(['cygstart', file_path]) - return url = 'file://%s' % urllib.quote(file_path) self._tool.user.open_url(url)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py index 59f14fc..6c482e0 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater.py
@@ -197,10 +197,11 @@ return merged_dict def get_expectations(self, results): - """Returns a set of test expectations for a given test dict. + """Returns a set of test expectations to use based on results. Returns a set of one or more test expectations based on the expected - and actual results of a given test name. + and actual results of a given test name. This function is to decide + expectations for tests that could not be rebaselined. Args: results: A dictionary that maps one test to its results. Example: @@ -217,16 +218,13 @@ capitalized. Example: set(['Failure', 'Timeout']). """ expectations = set() - failure_types = ['TEXT', 'FAIL', 'IMAGE+TEXT', 'IMAGE', 'AUDIO', 'MISSING', 'LEAK'] - test_expectation_types = ['SLOW', 'TIMEOUT', 'CRASH', 'PASS', 'REBASELINE', 'NEEDSREBASELINE', 'NEEDSMANUALREBASELINE'] - for expected in results['expected'].split(): - for actual in results['actual'].split(): - if expected in test_expectation_types and actual in failure_types: - expectations.add('Failure') - if expected in failure_types and actual in test_expectation_types: - expectations.add(actual.capitalize()) - if expected in test_expectation_types and actual in test_expectation_types: - expectations.add(actual.capitalize()) + failure_types = ('TEXT', 'IMAGE+TEXT', 'IMAGE', 'AUDIO') + other_types = ('TIMEOUT', 'CRASH', 'PASS') + for actual in results['actual'].split(): + if actual in failure_types: + expectations.add('Failure') + if actual in other_types: + expectations.add(actual.capitalize()) return expectations def create_line_list(self, merged_results):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py index 9e036d21..dc2a2f6 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_expectations_updater_unittest.py
@@ -153,11 +153,17 @@ updater.get_expectations({'expected': 'TIMEOUT', 'actual': 'PASS'}), {'Pass'}) self.assertEqual( - updater.get_expectations({'expected': 'PASS', 'actual': 'TIMEOUT CRASH FAIL'}), + updater.get_expectations({'expected': 'PASS', 'actual': 'TEXT PASS'}), + {'Pass', 'Failure'}) + self.assertEqual( + updater.get_expectations({'expected': 'PASS', 'actual': 'TIMEOUT CRASH TEXT'}), {'Crash', 'Failure', 'Timeout'}) self.assertEqual( updater.get_expectations({'expected': 'SLOW CRASH FAIL TIMEOUT', 'actual': 'PASS'}), {'Pass'}) + self.assertEqual( + updater.get_expectations({'expected': 'Pass', 'actual': 'IMAGE+TEXT IMAGE IMAGE'}), + {'Failure'}) def test_create_line_list_old_tests(self): # In this example, there are two failures that are not in w3c tests. @@ -176,7 +182,7 @@ updater = WPTExpectationsUpdater(self.mock_host()) results = { 'external/fake/test/zzzz.html': { - 'test-mac-mac10.10': {'expected': 'PASS', 'actual': 'FAIL', 'bug': 'crbug.com/test'}, + 'test-mac-mac10.10': {'expected': 'PASS', 'actual': 'TEXT', 'bug': 'crbug.com/test'}, }, 'external/fake/test/path.html': { 'test-linux-trusty': {'expected': 'FAIL', 'actual': 'PASS', 'bug': 'crbug.com/test'},
diff --git a/third_party/WebKit/public/web/WebViewClient.h b/third_party/WebKit/public/web/WebViewClient.h index 1e09aa4..758dd13 100644 --- a/third_party/WebKit/public/web/WebViewClient.h +++ b/third_party/WebKit/public/web/WebViewClient.h
@@ -43,7 +43,6 @@ class WebDateTimeChooserCompletion; class WebFileChooserCompletion; -class WebHitTestResult; class WebNode; class WebSpeechRecognizer; class WebStorageNamespace; @@ -239,24 +238,6 @@ // Informs the browser that the page scale has changed. virtual void pageScaleFactorChanged() {} - // Content detection ---------------------------------------------------- - - // Detects if the content at (or around) provided hit test result - // corresponds to an intent that could be handed by an embedder - // (e.g., email addresses, phone numbers). - virtual WebURL detectContentIntentAt(const WebHitTestResult&) { - return WebURL(); - } - - // Schedules a new content intent with the provided url. - // The boolean flag is set to true when the user gesture has been applied - // to the element from the main frame. - virtual void scheduleContentIntent(const WebURL&, bool isMainFrame) {} - - // Cancels any previously scheduled content intents that have not yet - // launched. - virtual void cancelScheduledContentIntents() {} - // Draggable regions ---------------------------------------------------- // Informs the browser that the draggable regions have been updated.
diff --git a/third_party/libaddressinput/chromium/chrome_address_validator.cc b/third_party/libaddressinput/chromium/chrome_address_validator.cc index b0bd189..320451b 100644 --- a/third_party/libaddressinput/chromium/chrome_address_validator.cc +++ b/third_party/libaddressinput/chromium/chrome_address_validator.cc
@@ -17,6 +17,7 @@ #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_normalizer.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h" +#include "third_party/libaddressinput/src/cpp/src/rule.h" namespace autofill { namespace { @@ -27,6 +28,7 @@ using ::i18n::addressinput::BuildCallback; using ::i18n::addressinput::FieldProblemMap; using ::i18n::addressinput::PreloadSupplier; +using ::i18n::addressinput::Rule; using ::i18n::addressinput::Source; using ::i18n::addressinput::Storage; @@ -58,6 +60,20 @@ supplier_->LoadRules(region_code, *rules_loaded_); } +std::vector<std::string> AddressValidator::GetRegionSubKeys( + const std::string& region_code) { + if (!AreRulesLoadedForRegion(region_code)) + return std::vector<std::string>(); + + auto rules = supplier_->GetRulesForRegion(region_code); + auto rule_iterator = rules.find("data/" + region_code); + + if (rule_iterator == rules.end() || !rule_iterator->second) + return std::vector<std::string>(); + + return rule_iterator->second->GetSubKeys(); +} + AddressValidator::Status AddressValidator::ValidateAddress( const AddressData& address, const FieldProblemMap* filter, @@ -141,7 +157,7 @@ const std::string& region_code, int) { if (load_rules_listener_) - load_rules_listener_->OnAddressValidationRulesLoaded(region_code, success); + load_rules_listener_->OnAddressRulesLoaded(region_code, success); // Count the first failed attempt to load rules as well. if (success || attempts_number_[region_code] + 1 >= kMaxAttemptsNumber)
diff --git a/third_party/libaddressinput/chromium/chrome_address_validator.h b/third_party/libaddressinput/chromium/chrome_address_validator.h index 43a4a40..f956bd0 100644 --- a/third_party/libaddressinput/chromium/chrome_address_validator.h +++ b/third_party/libaddressinput/chromium/chrome_address_validator.h
@@ -46,8 +46,8 @@ // then these are also loaded. // // The |success| parameter is true when the rules were loaded successfully. - virtual void OnAddressValidationRulesLoaded(const std::string& region_code, - bool success) = 0; + virtual void OnAddressRulesLoaded(const std::string& region_code, + bool success) = 0; }; // Interface to the libaddressinput AddressValidator for Chromium Autofill. The @@ -94,6 +94,13 @@ // Invokes |load_rules_listener| when the loading has finished. virtual void LoadRules(const std::string& region_code); + // Returns the list of sub-regions (recorded as sub-keys) of the region + // (recorded as rule) indicated by |region_code|. So, if the |region_code| is + // a country code, sub-region means the country's admin area. + // This function should be called when the rules are loaded. + virtual std::vector<std::string> GetRegionSubKeys( + const std::string& region_code); + // Validates the |address| and populates |problems| with the validation // problems, filtered according to the |filter| parameter. //
diff --git a/third_party/libaddressinput/chromium/chrome_address_validator_unittest.cc b/third_party/libaddressinput/chromium/chrome_address_validator_unittest.cc index 13b5a8b..17cae79 100644 --- a/third_party/libaddressinput/chromium/chrome_address_validator_unittest.cc +++ b/third_party/libaddressinput/chromium/chrome_address_validator_unittest.cc
@@ -5,6 +5,7 @@ #include "third_party/libaddressinput/chromium/chrome_address_validator.h" #include <stddef.h> +#include <set> #include <string> #include <utility> #include <vector> @@ -67,8 +68,8 @@ private: // LoadRulesListener implementation. - virtual void OnAddressValidationRulesLoaded(const std::string& country_code, - bool success) override { + void OnAddressRulesLoaded(const std::string& country_code, + bool success) override { AddressData address_data; address_data.region_code = country_code; FieldProblemMap dummy; @@ -110,6 +111,26 @@ AddressValidator* LargeAddressValidatorTest::validator_ = NULL; +TEST_F(AddressValidatorTest, SubKeysLoaded) { + const std::string country_code = "US"; + const std::string first_state = "AL"; + + validator_->LoadRules(country_code); + std::vector<std::string> sub_keys = + validator_->GetRegionSubKeys(country_code); + ASSERT_FALSE(sub_keys.empty()); + ASSERT_EQ(sub_keys[0], first_state); +} + +TEST_F(AddressValidatorTest, SubKeysNotLoaded) { + const std::string country_code = "ZZ"; + + validator_->LoadRules(country_code); + std::vector<std::string> sub_keys = + validator_->GetRegionSubKeys(country_code); + ASSERT_TRUE(sub_keys.empty()); +} + TEST_F(AddressValidatorTest, RegionHasRules) { const std::vector<std::string>& region_codes = GetRegionCodes(); AddressData address; @@ -758,7 +779,7 @@ virtual ~TestAddressValidator() {} protected: - virtual base::TimeDelta GetBaseRetryPeriod() const override { + base::TimeDelta GetBaseRetryPeriod() const override { return base::TimeDelta::FromSeconds(0); } @@ -770,7 +791,7 @@ // data. class FailingSource : public Source { public: - explicit FailingSource() + FailingSource() : failures_number_(0), attempts_number_(0), actual_source_(true) {} virtual ~FailingSource() {} @@ -781,8 +802,7 @@ // Source implementation. // Always fails for the first |failures_number| times. - virtual void Get(const std::string& url, - const Callback& callback) const override { + void Get(const std::string& url, const Callback& callback) const override { ++attempts_number_; // |callback| takes ownership of the |new std::string|. if (failures_number_-- > 0) @@ -823,8 +843,7 @@ private: // LoadRulesListener implementation. - virtual void OnAddressValidationRulesLoaded(const std::string&, - bool success) override { + void OnAddressRulesLoaded(const std::string&, bool success) override { load_rules_success_ = success; }
diff --git a/tools/check_grd_for_unused_strings.py b/tools/check_grd_for_unused_strings.py index 8124b576..21afc8a 100755 --- a/tools/check_grd_for_unused_strings.py +++ b/tools/check_grd_for_unused_strings.py
@@ -152,7 +152,7 @@ os.path.join(chrome_dir, 'renderer', 'resources', 'renderer_resources.grd'), os.path.join(device_base_dir, 'bluetooth', 'bluetooth_strings.grd'), - os.path.join(src_dir, 'extensions', 'extensions_strings.grd'), + os.path.join(src_dir, 'extensions', 'strings', 'extensions_strings.grd'), os.path.join(src_dir, 'ui', 'resources', 'ui_resources.grd'), os.path.join(src_dir, 'ui', 'webui', 'resources', 'webui_resources.grd'), os.path.join(ui_strings_dir, 'app_locale_settings.grd'),
diff --git a/tools/clang/pylib/clang/compile_db.py b/tools/clang/pylib/clang/compile_db.py index 8bae555..cb8a39fb1 100755 --- a/tools/clang/pylib/clang/compile_db.py +++ b/tools/clang/pylib/clang/compile_db.py
@@ -5,22 +5,93 @@ import json import os +import re +import shlex +import sys import subprocess +_RSP_RE = re.compile(r' (@(.+?\.rsp)) ') +_debugging = False + + +def _ProcessEntry(entry): + """Transforms one entry in the compile database to be clang-tool friendly.""" + # Escape backslashes to prevent shlex from interpreting them. + escaped_command = entry['command'].replace('\\', '\\\\') + split_command = shlex.split(escaped_command) + # Drop gomacc.exe from the front, if present. + if split_command[0].endswith('gomacc.exe'): + split_command = split_command[1:] + # Insert --driver-mode=cl as the first argument. + split_command = split_command[:1] + ['--driver-mode=cl'] + split_command[1:] + entry['command'] = ' '.join(split_command) + + # Expand the contents of the response file, if any. + # http://llvm.org/bugs/show_bug.cgi?id=21634 + try: + match = _RSP_RE.search(entry['command']) + if match: + rsp_path = os.path.join(entry['directory'], match.group(2)) + rsp_contents = file(rsp_path).read() + entry['command'] = ''.join([ + entry['command'][:match.start(1)], + rsp_contents, + entry['command'][match.end(1):]]) + except IOError: + if _debugging: + print 'Couldn\'t read response file for %s' % entry['file'] + + return entry + + +def _ProcessCompileDatabaseForWindows(compile_db): + """Make the compile db generated by ninja on Windows more clang-tool friendly. + + Args: + compile_db: The compile database parsed as a Python dictionary. + + Returns: + A postprocessed compile db that clang tooling can use. + """ + if _debugging > 0: + print 'Read in %d entries from the compile db' % len(compile_db) + compile_db = [_ProcessEntry(e) for e in compile_db] + original_length = len(compile_db) + + # Filter out NaCl stuff. The clang tooling chokes on them. + # TODO(dcheng): This doesn't appear to do anything anymore, remove? + compile_db = [e for e in compile_db if '_nacl.cc.pdb' not in e['command'] + and '_nacl_win64.cc.pdb' not in e['command']] + if _debugging > 0: + print 'Filtered out %d entries...' % (original_length - len(compile_db)) + + # TODO(dcheng): Also filter out multiple commands for the same file. Not sure + # how that happens, but apparently it's an issue on Windows. + return compile_db + + def GenerateWithNinja(path): """Generates a compile database using ninja. Args: path: The build directory to generate a compile database for. """ - # TODO(dcheng): Incorporate Windows-specific compile DB munging from - # https://codereview.chromium.org/718873004 - print 'Generating compile database in %s...' % path - args = ['ninja', '-C', path, '-t', 'compdb', 'cc', 'cxx', 'objc', 'objcxx'] - output = subprocess.check_output(args) - with file(os.path.join(path, 'compile_commands.json'), 'w') as f: - f.write(output) + # TODO(dcheng): Ensure that clang is enabled somehow. + + # First, generate the compile database. + json_compile_db = subprocess.check_output([ + 'ninja', '-C', path, '-t', 'compdb', 'cc', 'cxx', 'objc', 'objcxx']) + compile_db = json.loads(json_compile_db) + + # TODO(dcheng): Ideally this would check target_os... but not sure there's an + # easy way to do that, and (for now) cross-compiles don't work without custom + # patches anyway. + if sys.platform == 'win32': + compile_db = _ProcessCompileDatabaseForWindows(compile_db) + + with open(os.path.join(path, 'compile_commands.json'), 'w') as f: + f.write(json.dumps(compile_db, indent=2)) def Read(path):
diff --git a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp index 4180e15..832ee5a 100644 --- a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp +++ b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
@@ -425,7 +425,7 @@ // https://crbug.com/672902: Should not rewrite names that mimick methods // from std library. - "back", "empty", "erase", "front", "insert", "length", "size", + "at", "back", "empty", "erase", "front", "insert", "length", "size", }; for (const auto& b : kBlacklistedNames) { if (name == b) @@ -658,6 +658,7 @@ // Functions that are named similarily to a type - they should be prefixed // with a "Get" prefix. static const char* kConflictingMethods[] = { + "accumulatorMap", "animationWorklet", "audioWorklet", "binaryType", @@ -673,6 +674,7 @@ "emptySpellCheckerClient", "entryType", "error", + "eventTargetDataMap", "fileUtilities", "font", "frame", @@ -681,6 +683,7 @@ "gridCell", "hash", "heapObjectHeader", + "heapObjectSet", "iconURL", "image", "inputMethodController", @@ -708,6 +711,7 @@ "path", "position", "processingInstruction", + "qualifiedNameCache", "readyState", "relList", "referrer", @@ -721,6 +725,7 @@ "scrollAnimator", "selectionInDOMTree", "selectionInFlatTree", + "selectorTextCache", "settings", "signalingState", "snapshotById",
diff --git a/tools/clang/scripts/generate_compdb.py b/tools/clang/scripts/generate_compdb.py new file mode 100755 index 0000000..a33e4095 --- /dev/null +++ b/tools/clang/scripts/generate_compdb.py
@@ -0,0 +1,37 @@ +#!/usr/bin/env python +# Copyright 2014 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. + +""" +Helper for generating compile DBs for clang tooling. On non-Windows platforms, +this is pretty straightforward. On Windows, the tool does a bit of extra work to +integrate the content of response files, force clang tooling to run in clang-cl +mode, etc. +""" + +import argparse +import os +import sys + +script_dir = os.path.dirname(os.path.realpath(__file__)) +tool_dir = os.path.abspath(os.path.join(script_dir, '../pylib')) +sys.path.insert(0, tool_dir) + +from clang import compile_db + + +def main(argv): + parser = argparse.ArgumentParser() + parser.add_argument( + 'build_path', + nargs='?', + help='Path to build directory', + default='out/Debug') + args = parser.parse_args() + + compile_db.GenerateWithNinja(args.build_path) + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:]))
diff --git a/tools/clang/scripts/generate_win_compdb.py b/tools/clang/scripts/generate_win_compdb.py deleted file mode 100755 index 6edd593..0000000 --- a/tools/clang/scripts/generate_win_compdb.py +++ /dev/null
@@ -1,83 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 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. - -""" -Clang tools on Windows are still a bit busted. The tooling can't handle -backslashes in paths, doesn't understand how to read .rsp files, etc. In -addition, ninja generates compile commands prefixed with the ninja msvc helper, -which also confuses clang. This script generates a compile DB that should mostly -work until clang tooling can be improved upstream. -""" - -import argparse -import os -import re -import json -import shlex -import subprocess -import sys - - -_NINJA_MSVC_WRAPPER = re.compile('ninja -t msvc -e .+? -- ') -_RSP_RE = re.compile(r' (@(.+?\.rsp)) ') - - -def _ProcessEntry(e): - # Strip off the ninja -t msvc wrapper. - e['command'] = _NINJA_MSVC_WRAPPER.sub('', e['command']) - - # Prepend --driver-mode=cl to the command's arguments. - # Escape backslashes so shlex doesn't try to interpret them. - escaped_command = e['command'].replace('\\', '\\\\') - split_command = shlex.split(escaped_command) - e['command'] = ' '.join( - split_command[:1] + ['--driver-mode=cl'] + split_command[1:]) - - # Expand the contents of the response file, if any. - # http://llvm.org/bugs/show_bug.cgi?id=21634 - try: - match = _RSP_RE.search(e['command']) - rsp_path = os.path.join(e['directory'], match.group(2)) - rsp_contents = file(rsp_path).read() - e['command'] = ''.join([ - e['command'][:match.start(1)], - rsp_contents, - e['command'][match.end(1):]]) - except IOError: - pass - - return e - - -def main(argv): - # Parse argument - parser = argparse.ArgumentParser() - parser.add_argument( - 'build_path', - nargs='?', - help='Path to build directory', - default='out/Debug') - args = parser.parse_args() - # First, generate the compile database. - print 'Generating compile DB with ninja...' - compile_db_as_json = subprocess.check_output(shlex.split( - 'ninja -C %s -t compdb cc cxx objc objcxx' % args.build_path)) - - compile_db = json.loads(compile_db_as_json) - print 'Read in %d entries from the compile db' % len(compile_db) - compile_db = [_ProcessEntry(e) for e in compile_db] - original_length = len(compile_db) - - # Filter out NaCl stuff. The clang tooling chokes on them. - compile_db = [e for e in compile_db if '_nacl.cc.pdb' not in e['command'] - and '_nacl_win64.cc.pdb' not in e['command']] - print 'Filtered out %d entries...' % (original_length - len(compile_db)) - f = file('%s/compile_commands.json' % args.build_path, 'w') - f.write(json.dumps(compile_db, indent=2)) - print 'Done!' - - -if __name__ == '__main__': - sys.exit(main(sys.argv[1:]))
diff --git a/tools/gn/bootstrap/bootstrap.py b/tools/gn/bootstrap/bootstrap.py index 937427c6..8252799 100755 --- a/tools/gn/bootstrap/bootstrap.py +++ b/tools/gn/bootstrap/bootstrap.py
@@ -171,7 +171,8 @@ write_buildflag_header_manually(root_gen_dir, 'base/debug/debugging_flags.h', { 'ENABLE_PROFILING': 'false', - 'ENABLE_MEMORY_TASK_PROFILER': 'false' + 'ENABLE_MEMORY_TASK_PROFILER': 'false', + 'CAN_UNWIND_WITH_FRAME_POINTERS': 'false' }) write_build_date_header(root_gen_dir)
diff --git a/tools/gn/docs/standalone.md b/tools/gn/docs/standalone.md index faeb4260..81dd8969 100644 --- a/tools/gn/docs/standalone.md +++ b/tools/gn/docs/standalone.md
@@ -35,7 +35,10 @@ your subproject rather than for all of Chrome. This could be an advantage or a disadvantage. -If you would rather avoid using this file, you can use the command-line -flags `--root` and `--dotfile` to set these values. +If you are in a directory with such a file and you want to not use it +(e.g., to do the full Chrome build instead), you can use the command-line +flags `--root` and `--dotfile` to set the values you want. -# How the standalone and Chrome builds interact +If you want a completely standalone build that has nothing to do w/ Chrome +and doesn't use Chrome's //build files, you can look at an example in +[//tools/gn/example](../example).
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 790748cf..7ad3ec2 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -10959,6 +10959,29 @@ </summary> </histogram> +<histogram name="DelayNavigationThrottle.Delay.Actual" units="ms"> + <owner>bmcquade@chromium.org</owner> + <summary> + The actual delay added to main frame navigations by DelayNavigationThrottle. + </summary> +</histogram> + +<histogram name="DelayNavigationThrottle.Delay.Delta" units="ms"> + <owner>bmcquade@chromium.org</owner> + <summary> + The absolute delta between the specified and actual delays added to main + frame navigations by DelayNavigationThrottle. + </summary> +</histogram> + +<histogram name="DelayNavigationThrottle.Delay.Specified" units="ms"> + <owner>bmcquade@chromium.org</owner> + <summary> + The specified delay added to main frame navigations by + DelayNavigationThrottle. + </summary> +</histogram> + <histogram name="DesktopIOSPromotion.DismissalReason" enum="DesktopIOSPromotionDismissalReason"> <owner>mrefaat@chromium.org</owner>
diff --git a/tools/metrics/histograms/update_histogram_enum.py b/tools/metrics/histograms/update_histogram_enum.py index db9037f..5c42a12 100644 --- a/tools/metrics/histograms/update_histogram_enum.py +++ b/tools/metrics/histograms/update_histogram_enum.py
@@ -38,7 +38,8 @@ def ReadHistogramValues(filename, start_marker, end_marker): - """Returns a dictionary of enum values, read from a C++ file. + """Returns a dictionary of enum values and a pair of labels that have the same + enum values, read from a C++ file. Args: filename: The unix-style path (relative to src/) of the file to open. @@ -75,13 +76,16 @@ label = m.group(1) else: continue + # If two enum labels have the same value + if enum_value in result: + return result, (result[enum_value], label) result[enum_value] = label enum_value += 1 else: if START_REGEX.match(line): inside_enum = True enum_value = 0 - return result + return result, None def CreateEnumItemNode(document, value, label): @@ -180,12 +184,14 @@ end_marker: A regular expression that matches the end of the C++ enum. """ Log('Reading histogram enum definition from "{0}".'.format(source_enum_path)) - source_enum_values = ReadHistogramValues(source_enum_path, start_marker, - end_marker) + source_enum_values, duplicated_values = ReadHistogramValues( + source_enum_path, start_marker, end_marker) + if duplicated_values: + return False, duplicated_values (xml, new_xml) = _GetOldAndUpdatedXml(histogram_enum_name, source_enum_values, source_enum_path) - return xml != new_xml + return xml != new_xml, None def UpdateHistogramFromDict(histogram_enum_name, source_enum_values,
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc index 4bcaff5a..ccb4c68 100644 --- a/ui/android/delegated_frame_host_android.cc +++ b/ui/android/delegated_frame_host_android.cc
@@ -85,11 +85,13 @@ cc::SurfaceId(frame_sink_id_, local_surface_id), 1.f, frame_size); has_transparent_background_ = root_pass->has_transparent_background; + support_->SubmitCompositorFrame(local_surface_id, std::move(frame)); content_layer_ = CreateSurfaceLayer(surface_manager_, surface_info_, !has_transparent_background_); view_->GetLayer()->AddChild(content_layer_); + } else { + support_->SubmitCompositorFrame(local_surface_id, std::move(frame)); } - support_->SubmitCompositorFrame(local_surface_id, std::move(frame)); } cc::FrameSinkId DelegatedFrameHostAndroid::GetFrameSinkId() const {
diff --git a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java index 8e3dedac..e4eb367 100644 --- a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java +++ b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java
@@ -6,7 +6,6 @@ import android.annotation.TargetApi; import android.content.ClipData; -import android.content.Intent; import android.graphics.Bitmap; import android.os.Build; import android.view.View; @@ -15,22 +14,14 @@ import android.widget.ImageView; import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; -import java.net.URISyntaxException; - /** * Class to acquire, position, and remove anchor views from the implementing View. */ @JNINamespace("ui") public abstract class ViewAndroidDelegate { - private static final String TAG = "ViewAndroidDelegate"; - private static final String GEO_SCHEME = "geo"; - private static final String TEL_SCHEME = "tel"; - private static final String MAILTO_SCHEME = "mailto"; - /** * @return An anchor view that can be used to anchor decoration views like Autofill popup. */ @@ -132,34 +123,6 @@ public void onBottomControlsChanged(float bottomControlsOffsetY, float bottomContentOffsetY) {} /** - * Called when a new content intent is requested to be started. - * Invokes {@link #startContentIntent(Intent, String, boolean)} only if the parsed - * intent is valid and the scheme is acceptable. - */ - @CalledByNative - private void onStartContentIntent(String intentUrl, boolean isMainFrame) { - Intent intent; - try { - intent = Intent.parseUri(intentUrl, Intent.URI_INTENT_SCHEME); - } catch (URISyntaxException e) { - Log.d(TAG, "Bad URI %s", intentUrl, e); - return; - } - String scheme = intent.getScheme(); - if (!(GEO_SCHEME.equals(scheme) || TEL_SCHEME.equals(scheme) - || MAILTO_SCHEME.equals(scheme))) { - Log.d(TAG, "Invalid scheme for URI %s", intentUrl); - return; - } - startContentIntent(intent, intentUrl, isMainFrame); - } - - /** - * Start a new content intent. - */ - public void startContentIntent(Intent intent, String intentUrl, boolean isMainFrame) {} - - /** * @return container view that the anchor views are added to. May be null. */ @CalledByNative
diff --git a/ui/android/view_android.cc b/ui/android/view_android.cc index 672ae01..fddff015 100644 --- a/ui/android/view_android.cc +++ b/ui/android/view_android.cc
@@ -271,18 +271,6 @@ env, delegate, bottom_controls_offset, bottom_content_offset); } -void ViewAndroid::StartContentIntent(const GURL& content_url, - bool is_main_frame) { - ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); - if (delegate.is_null()) - return; - JNIEnv* env = base::android::AttachCurrentThread(); - ScopedJavaLocalRef<jstring> jcontent_url = - ConvertUTF8ToJavaString(env, content_url.spec()); - Java_ViewAndroidDelegate_onStartContentIntent(env, delegate, jcontent_url, - is_main_frame); -} - bool ViewAndroid::OnTouchEvent(const MotionEventAndroid& event, bool for_touch_handle) { return HitTest(
diff --git a/ui/android/view_android.h b/ui/android/view_android.h index a56603f07..a8d8f04 100644 --- a/ui/android/view_android.h +++ b/ui/android/view_android.h
@@ -13,8 +13,6 @@ #include "ui/android/ui_android_export.h" #include "ui/gfx/geometry/rect_f.h" -class GURL; - namespace cc { class Layer; } @@ -140,7 +138,6 @@ float top_content_offset); void OnBottomControlsChanged(float bottom_controls_offset, float bottom_content_offset); - void StartContentIntent(const GURL& content_url, bool is_main_frame); ScopedAnchorView AcquireAnchorView(); void SetAnchorRect(const base::android::JavaRef<jobject>& anchor,
diff --git a/ui/gl/gl_surface_osmesa_win.cc b/ui/gl/gl_surface_osmesa_win.cc index 4e13201e..1ee861d 100644 --- a/ui/gl/gl_surface_osmesa_win.cc +++ b/ui/gl/gl_surface_osmesa_win.cc
@@ -25,8 +25,11 @@ namespace gl { +// Use BGRA, because StretchDIBits from RGBA causes later PrintWindow or +// BitBlt from the HWND to return all 0s, which causes the snapshot mechanism +// not to work. GLSurfaceOSMesaWin::GLSurfaceOSMesaWin(gfx::AcceleratedWidget window) - : GLSurfaceOSMesa(GLSurfaceFormat(GLSurfaceFormat::PIXEL_LAYOUT_RGBA), + : GLSurfaceOSMesa(GLSurfaceFormat(GLSurfaceFormat::PIXEL_LAYOUT_BGRA), gfx::Size(1, 1)), window_(window), device_context_(NULL) { @@ -62,32 +65,7 @@ DCHECK(device_context_); gfx::Size size = GetSize(); - - // Note: negating the height below causes GDI to treat the bitmap data as row - // 0 being at the top. - BITMAPV4HEADER info = {sizeof(BITMAPV4HEADER)}; - info.bV4Width = size.width(); - info.bV4Height = -size.height(); - info.bV4Planes = 1; - info.bV4BitCount = 32; - info.bV4V4Compression = BI_BITFIELDS; - info.bV4RedMask = 0x000000FF; - info.bV4GreenMask = 0x0000FF00; - info.bV4BlueMask = 0x00FF0000; - info.bV4AlphaMask = 0xFF000000; - - // Copy the back buffer to the window's device context. Do not check whether - // StretchDIBits succeeds or not. It will fail if the window has been - // destroyed but it is preferable to allow rendering to silently fail if the - // window is destroyed. This is because the primary application of this - // class of GLContext is for testing and we do not want every GL related ui / - // browser test to become flaky if there is a race condition between GL - // context destruction and window destruction. - StretchDIBits(device_context_, 0, 0, size.width(), size.height(), 0, 0, - size.width(), size.height(), GetHandle(), - reinterpret_cast<BITMAPINFO*>(&info), DIB_RGB_COLORS, SRCCOPY); - - return gfx::SwapResult::SWAP_ACK; + return PostSubBuffer(0, 0, size.width(), size.height()); } bool GLSurfaceOSMesaWin::SupportsPostSubBuffer() { @@ -110,9 +88,9 @@ info.bV4Planes = 1; info.bV4BitCount = 32; info.bV4V4Compression = BI_BITFIELDS; - info.bV4RedMask = 0x000000FF; + info.bV4RedMask = 0x00FF0000; info.bV4GreenMask = 0x0000FF00; - info.bV4BlueMask = 0x00FF0000; + info.bV4BlueMask = 0x000000FF; info.bV4AlphaMask = 0xFF000000; // Copy the back buffer to the window's device context. Do not check whether
diff --git a/ui/snapshot/BUILD.gn b/ui/snapshot/BUILD.gn index 4685e1b..7e2c288 100644 --- a/ui/snapshot/BUILD.gn +++ b/ui/snapshot/BUILD.gn
@@ -16,14 +16,17 @@ "snapshot_async.cc", "snapshot_async.h", "snapshot_aura.cc", - "snapshot_export.h", + "snapshot_aura.h", "snapshot_ios.mm", "snapshot_mac.mm", + "snapshot_win.cc", ] defines = [ "SNAPSHOT_IMPLEMENTATION" ] deps = [ + ":snapshot_export", + ":snapshot_win", "//base", "//skia", "//ui/base", @@ -58,7 +61,10 @@ "//ui/compositor", ] } else { - sources -= [ "snapshot_aura.cc" ] + sources -= [ + "snapshot_aura.cc", + "snapshot_aura.h", + ] } if (is_mac) { @@ -69,6 +75,23 @@ } } +source_set("snapshot_win") { + sources = [ + "snapshot_win.h", + ] + deps = [ + ":snapshot_export", + ] + visibility = [ ":*" ] +} + +source_set("snapshot_export") { + sources = [ + "snapshot_export.h", + ] + visibility = [ ":*" ] +} + test("snapshot_unittests") { sources = [ "snapshot_aura_unittest.cc",
diff --git a/ui/snapshot/snapshot_aura.cc b/ui/snapshot/snapshot_aura.cc index 0ff547c1..44b136eb 100644 --- a/ui/snapshot/snapshot_aura.cc +++ b/ui/snapshot/snapshot_aura.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/snapshot/snapshot.h" +#include "ui/snapshot/snapshot_aura.h" #include <utility> @@ -21,21 +21,15 @@ namespace ui { -bool GrabViewSnapshot(gfx::NativeView view, - const gfx::Rect& snapshot_bounds, - gfx::Image* image) { - return GrabWindowSnapshot(view, snapshot_bounds, image); -} - -bool GrabWindowSnapshot(gfx::NativeWindow window, - const gfx::Rect& snapshot_bounds, - gfx::Image* image) { +bool GrabWindowSnapshotAura(aura::Window* window, + const gfx::Rect& snapshot_bounds, + gfx::Image* image) { // Not supported in Aura. Callers should fall back to the async version. return false; } static void MakeAsyncCopyRequest( - gfx::NativeWindow window, + aura::Window* window, const gfx::Rect& source_rect, const cc::CopyOutputRequest::CopyOutputRequestCallback& callback) { std::unique_ptr<cc::CopyOutputRequest> request = @@ -59,7 +53,7 @@ // order, the tracker might have been passed and set to NULL // before the window is looked up which results in a NULL pointer // dereference. - gfx::NativeWindow window = tracker->windows()[0]; + aura::Window* window = tracker->windows()[0]; MakeAsyncCopyRequest( window, source_rect, base::Bind(&FinishedAsyncCopyRequest, base::Passed(&tracker), @@ -71,7 +65,7 @@ } static void MakeInitialAsyncCopyRequest( - gfx::NativeWindow window, + aura::Window* window, const gfx::Rect& source_rect, const cc::CopyOutputRequest::CopyOutputRequestCallback& callback) { auto tracker = base::MakeUnique<aura::WindowTracker>(); @@ -82,8 +76,8 @@ callback, 0)); } -void GrabWindowSnapshotAndScaleAsync( - gfx::NativeWindow window, +void GrabWindowSnapshotAndScaleAsyncAura( + aura::Window* window, const gfx::Rect& source_rect, const gfx::Size& target_size, scoped_refptr<base::TaskRunner> background_task_runner, @@ -94,19 +88,51 @@ background_task_runner)); } -void GrabWindowSnapshotAsync(gfx::NativeWindow window, - const gfx::Rect& source_rect, - const GrabWindowSnapshotAsyncCallback& callback) { +void GrabWindowSnapshotAsyncAura( + aura::Window* window, + const gfx::Rect& source_rect, + const GrabWindowSnapshotAsyncCallback& callback) { MakeInitialAsyncCopyRequest( window, source_rect, base::Bind(&SnapshotAsync::RunCallbackWithCopyOutputResult, callback)); } +#if !defined(OS_WIN) +bool GrabWindowSnapshot(gfx::NativeWindow window, + const gfx::Rect& snapshot_bounds, + gfx::Image* image) { + // Not supported in Aura. Callers should fall back to the async version. + return false; +} + +bool GrabViewSnapshot(gfx::NativeView view, + const gfx::Rect& snapshot_bounds, + gfx::Image* image) { + return GrabWindowSnapshot(view, snapshot_bounds, image); +} + +void GrabWindowSnapshotAndScaleAsync( + gfx::NativeWindow window, + const gfx::Rect& source_rect, + const gfx::Size& target_size, + scoped_refptr<base::TaskRunner> background_task_runner, + const GrabWindowSnapshotAsyncCallback& callback) { + GrabWindowSnapshotAndScaleAsyncAura(window, source_rect, target_size, + background_task_runner, callback); +} + +void GrabWindowSnapshotAsync(gfx::NativeWindow window, + const gfx::Rect& source_rect, + const GrabWindowSnapshotAsyncCallback& callback) { + GrabWindowSnapshotAsyncAura(window, source_rect, callback); +} + void GrabViewSnapshotAsync(gfx::NativeView view, const gfx::Rect& source_rect, const GrabWindowSnapshotAsyncCallback& callback) { - GrabWindowSnapshotAsync(view, source_rect, callback); + GrabWindowSnapshotAsyncAura(view, source_rect, callback); } +#endif } // namespace ui
diff --git a/ui/snapshot/snapshot_aura.h b/ui/snapshot/snapshot_aura.h new file mode 100644 index 0000000..425dcf6 --- /dev/null +++ b/ui/snapshot/snapshot_aura.h
@@ -0,0 +1,30 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_SNAPSHOT_SNAPSHOT_AURA_H_ +#define UI_SNAPSHOT_SNAPSHOT_AURA_H_ + +#include "ui/snapshot/snapshot.h" + +namespace ui { + +// These functions are identical to those in snapshot.h, except they're +// guaranteed to read the frame using an Aura CopyOutputRequest and not the +// native windowing system. source_rect and target_size are in DIP. + +SNAPSHOT_EXPORT void GrabWindowSnapshotAndScaleAsyncAura( + aura::Window* window, + const gfx::Rect& source_rect, + const gfx::Size& target_size, + scoped_refptr<base::TaskRunner> background_task_runner, + const GrabWindowSnapshotAsyncCallback& callback); + +SNAPSHOT_EXPORT void GrabWindowSnapshotAsyncAura( + aura::Window* window, + const gfx::Rect& source_rect, + const GrabWindowSnapshotAsyncCallback& callback); + +} // namespace ui + +#endif // UI_SNAPSHOT_SNAPSHOT_AURA_H_
diff --git a/ui/snapshot/snapshot_win.cc b/ui/snapshot/snapshot_win.cc new file mode 100644 index 0000000..66049a70 --- /dev/null +++ b/ui/snapshot/snapshot_win.cc
@@ -0,0 +1,160 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/snapshot/snapshot_win.h" + +#include "base/callback.h" +#include "base/task_runner.h" +#include "base/win/windows_version.h" +#include "skia/ext/platform_canvas.h" +#include "skia/ext/skia_utils_win.h" +#include "ui/aura/window.h" +#include "ui/aura/window_tree_host.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/image/image.h" +#include "ui/snapshot/snapshot.h" +#include "ui/snapshot/snapshot_aura.h" + +namespace { + +// Windows 8.1 is the first version that supports PW_RENDERFULLCONTENT. +// Without that flag PrintWindow may not correctly capture what's actually +// onscreen. +bool UseAuraSnapshot() { + return (base::win::GetVersion() < base::win::VERSION_WIN8_1); +} + +} // namespace + +namespace ui { + +namespace internal { + +bool GrabHwndSnapshot(HWND window_handle, + const gfx::Rect& snapshot_bounds_in_pixels, + const gfx::Rect& clip_rect_in_pixels, + gfx::Image* image) { + gfx::Rect snapshot_bounds_in_window = + snapshot_bounds_in_pixels + clip_rect_in_pixels.OffsetFromOrigin(); + gfx::Size bitmap_size(snapshot_bounds_in_window.right(), + snapshot_bounds_in_window.bottom()); + + std::unique_ptr<SkCanvas> canvas = skia::CreatePlatformCanvas( + bitmap_size.width(), bitmap_size.height(), false); + HDC mem_hdc = skia::GetNativeDrawingContext(canvas.get()); + + // Grab a copy of the window. Use PrintWindow because it works even when the + // window's partially occluded. The PW_RENDERFULLCONTENT flag is undocumented, + // but works starting in Windows 8.1. It allows for capturing the contents of + // the window that are drawn using DirectComposition. + UINT flags = PW_CLIENTONLY | PW_RENDERFULLCONTENT; + + BOOL result = PrintWindow(window_handle, mem_hdc, flags); + if (!result) { + PLOG(ERROR) << "Failed to print window"; + return false; + } + + SkBitmap bitmap; + canvas->readPixels(gfx::RectToSkIRect(snapshot_bounds_in_window), &bitmap); + + // Clear the region of the bitmap outside the clip rect to white. + SkCanvas image_canvas(bitmap); + SkPaint paint; + paint.setColor(SK_ColorWHITE); + + SkRegion region; + gfx::Rect clip_in_bitmap(clip_rect_in_pixels.size()); + clip_in_bitmap.Offset(-snapshot_bounds_in_pixels.OffsetFromOrigin()); + region.setRect( + gfx::RectToSkIRect(gfx::Rect(snapshot_bounds_in_pixels.size()))); + region.op(gfx::RectToSkIRect(clip_in_bitmap), SkRegion::kDifference_Op); + image_canvas.drawRegion(region, paint); + + *image = gfx::Image::CreateFrom1xBitmap(bitmap); + + return true; +} + +} // namespace internal + +bool GrabViewSnapshot(gfx::NativeView view_handle, + const gfx::Rect& snapshot_bounds, + gfx::Image* image) { + return GrabWindowSnapshot(view_handle, snapshot_bounds, image); +} + +bool GrabWindowSnapshot(gfx::NativeWindow window_handle, + const gfx::Rect& snapshot_bounds, + gfx::Image* image) { + if (UseAuraSnapshot()) { + // Not supported in Aura. Callers should fall back to the async version. + return false; + } + + DCHECK(window_handle); + gfx::Rect window_bounds = window_handle->GetBoundsInRootWindow(); + aura::WindowTreeHost* host = window_handle->GetHost(); + DCHECK(host); + HWND hwnd = host->GetAcceleratedWidget(); + + gfx::RectF window_bounds_in_pixels(window_bounds); + host->GetRootTransform().TransformRect(&window_bounds_in_pixels); + gfx::RectF snapshot_bounds_in_pixels(snapshot_bounds); + host->GetRootTransform().TransformRect(&snapshot_bounds_in_pixels); + + gfx::Rect expanded_window_bounds_in_pixels = + gfx::ToEnclosingRect(window_bounds_in_pixels); + RECT client_area; + ::GetClientRect(hwnd, &client_area); + gfx::Rect client_area_rect(client_area); + client_area_rect.set_origin(gfx::Point()); + + expanded_window_bounds_in_pixels.Intersect(client_area_rect); + + return internal::GrabHwndSnapshot( + hwnd, gfx::ToEnclosingRect(snapshot_bounds_in_pixels), + expanded_window_bounds_in_pixels, image); +} + +void GrabWindowSnapshotAsync(gfx::NativeWindow window, + const gfx::Rect& source_rect, + const GrabWindowSnapshotAsyncCallback& callback) { + if (UseAuraSnapshot()) { + GrabWindowSnapshotAsyncAura(window, source_rect, callback); + return; + } + gfx::Image image; + GrabWindowSnapshot(window, source_rect, &image); + callback.Run(image); +} + +void GrabViewSnapshotAsync(gfx::NativeView view, + const gfx::Rect& source_rect, + const GrabWindowSnapshotAsyncCallback& callback) { + if (UseAuraSnapshot()) { + GrabWindowSnapshotAsyncAura(view, source_rect, callback); + return; + } + NOTIMPLEMENTED(); + callback.Run(gfx::Image()); +} + +void GrabWindowSnapshotAndScaleAsync( + gfx::NativeWindow window, + const gfx::Rect& source_rect, + const gfx::Size& target_size, + scoped_refptr<base::TaskRunner> background_task_runner, + const GrabWindowSnapshotAsyncCallback& callback) { + if (UseAuraSnapshot()) { + GrabWindowSnapshotAndScaleAsyncAura(window, source_rect, target_size, + background_task_runner, callback); + return; + } + NOTIMPLEMENTED(); + callback.Run(gfx::Image()); +} + +} // namespace ui
diff --git a/ui/snapshot/snapshot_win.h b/ui/snapshot/snapshot_win.h new file mode 100644 index 0000000..351d8d89 --- /dev/null +++ b/ui/snapshot/snapshot_win.h
@@ -0,0 +1,36 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_SNAPSHOT_SNAPSHOT_WIN_H_ +#define UI_SNAPSHOT_SNAPSHOT_WIN_H_ + +#include <windows.h> + +#include "ui/snapshot/snapshot_export.h" + +namespace gfx { +class Image; +class Rect; +} + +namespace ui { +namespace internal { + +// Grabs a snapshot of the desktop. No security checks are done. This is +// intended to be used for debugging purposes where no BrowserProcess instance +// is available (ie. tests). DO NOT use in a result of user action. +// +// snapshot_bounds_in_pixels is the area relative to clip_rect_in_pixels that +// should be captured. Areas outside clip_rect_in_pixels are filled white. +// clip_rect_in_pixels is relative to the client area of the window. +SNAPSHOT_EXPORT bool GrabHwndSnapshot( + HWND window_handle, + const gfx::Rect& snapshot_bounds_in_pixels, + const gfx::Rect& clip_rect_in_pixels, + gfx::Image* image); + +} // namespace internal +} // namespace ui + +#endif // UI_SNAPSHOT_SNAPSHOT_WIN_H_