diff --git a/DEPS b/DEPS index 60d168b..6f9c7c0 100644 --- a/DEPS +++ b/DEPS
@@ -87,8 +87,11 @@ # as an expression. 'cros_download_vm': '"{cros_board}" == "amd64-generic"', - # ANGLE's deps are relative to the angle_root variable. + # ANGLE's deps are relative to the angle_root variable, except for what's + # shared with chromium, such as build/, testing/, etc which are relative to + # src_root. 'angle_root': 'src/third_party/angle', + 'src_root': 'src', 'android_git': 'https://android.googlesource.com', 'aomedia_git': 'https://aomedia.googlesource.com', @@ -109,7 +112,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '4edb5e25157f5d256f626aa32a476ffdb01cf295', + 'v8_revision': 'b141a3197a5f400e9d9b68a35ab5f8d27cf4aa64', # 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. @@ -129,7 +132,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': 'bb3f58dbcb7195e9e641fcc64e2ab537cf3fbc61', + 'pdfium_revision': '2894645e6c187e75cfd016121e6f2857641575a1', # 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. @@ -165,7 +168,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '88afab4ff0f02bc2ad4d25642ecb5ce2d8cd8b76', + 'catapult_revision': 'b273e0cd217d87f33caacb8ed15d85801fcca9ea', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -181,7 +184,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'feed_revision': 'd97e635aa74d7d067a32cca5a8b65a39f4855e85', + 'feed_revision': '89e2c00bd3b9b2f0ce981f5c1d07a40c1e20eac1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling android_sdk_build-tools_version # and whatever else without interference from each other. @@ -213,7 +216,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': 'ab45d69154344cc5b6a80948e674aa001c126a97', + 'spv_tools_revision': 'b407163ef346bf852716970960a5f031c4aec9ce', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -605,7 +608,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'b708a096f473b55b8a72f4599067202d56b4f90b', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '0a3c5082ad50716d3e3df4934b5e32096d94ca3f', 'condition': 'checkout_linux', }, @@ -630,7 +633,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c68a1753c53a02b1bd292035e4a72a18e55814f3', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '1e488131ffcde9e4df573c9be3514c0cdc42d28b', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -959,7 +962,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f7eaeb14ee78953f87983e40c282df21fd04148c', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f0988af921fbbc8912dd6b2c2606e22ac301c889', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1111,7 +1114,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6d2f3f4cb8bac1f7c4a945c73d07a33df74f22f9', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '1927dfafabc06a7eced67d1d3fd60f2c0c88c152', + Var('webrtc_git') + '/src.git' + '@' + '9b1d67982f2631af48e3da503af10bd9ef989bd1', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1142,7 +1145,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@55fbadac66fec33a1181244ac29caca7c285ab35', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@baa4e9b9a71c839b6cec3e1ddfdbcfdcc74a7e87', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_url_checker_delegate_impl.cc b/android_webview/browser/aw_url_checker_delegate_impl.cc index a3b20fb5..b3a5031 100644 --- a/android_webview/browser/aw_url_checker_delegate_impl.cc +++ b/android_webview/browser/aw_url_checker_delegate_impl.cc
@@ -10,9 +10,11 @@ #include "android_webview/browser/aw_safe_browsing_whitelist_manager.h" #include "android_webview/browser/net/aw_web_resource_request.h" #include "base/bind.h" +#include "base/feature_list.h" #include "base/task/post_task.h" #include "components/safe_browsing/db/database_manager.h" #include "components/safe_browsing/db/v4_protocol_manager_util.h" +#include "components/safe_browsing/features.h" #include "components/security_interstitials/content/unsafe_resource.h" #include "components/security_interstitials/core/urls.h" #include "content/public/browser/browser_task_traits.h" @@ -32,7 +34,11 @@ {safe_browsing::SB_THREAT_TYPE_URL_MALWARE, safe_browsing::SB_THREAT_TYPE_URL_PHISHING, safe_browsing::SB_THREAT_TYPE_URL_UNWANTED})), - whitelist_manager_(whitelist_manager) {} + whitelist_manager_(whitelist_manager) { + if (base::FeatureList::IsEnabled(safe_browsing::kBillingInterstitial)) { + threat_types_.insert(safe_browsing::SB_THREAT_TYPE_BILLING); + } +} AwUrlCheckerDelegateImpl::~AwUrlCheckerDelegateImpl() = default;
diff --git a/android_webview/browser/deferred_gpu_command_service.cc b/android_webview/browser/deferred_gpu_command_service.cc index c645f864..ca7382dd 100644 --- a/android_webview/browser/deferred_gpu_command_service.cc +++ b/android_webview/browser/deferred_gpu_command_service.cc
@@ -72,6 +72,10 @@ bool ShouldYield() override { return false; } + // Should not be called because BlockThreadOnWaitSyncToken() returns true, + // and the client should not disable sequences to wait for sync tokens. + void SetEnabled(bool enabled) override { NOTREACHED(); } + void ScheduleTask(base::OnceClosure task, std::vector<gpu::SyncToken> sync_token_fences) override { uint32_t order_num = @@ -283,6 +287,10 @@ } } +bool DeferredGpuCommandService::BlockThreadOnWaitSyncToken() const { + return true; +} + bool DeferredGpuCommandService::CanSupportThreadedTextureMailbox() const { return gpu_info_.can_support_threaded_texture_mailbox; }
diff --git a/android_webview/browser/deferred_gpu_command_service.h b/android_webview/browser/deferred_gpu_command_service.h index 0a84ddf..27d9cae 100644 --- a/android_webview/browser/deferred_gpu_command_service.h +++ b/android_webview/browser/deferred_gpu_command_service.h
@@ -49,6 +49,7 @@ // gpu::CommandBufferTaskExecutor implementation. bool ForceVirtualizedGLContexts() const override; bool ShouldCreateMemoryTracker() const override; + bool BlockThreadOnWaitSyncToken() const override; std::unique_ptr<gpu::CommandBufferTaskExecutor::Sequence> CreateSequence() override; void ScheduleOutOfOrderTask(base::OnceClosure task) override;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConversionHelper.java b/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConversionHelper.java index 3d6494d..d0ba8fc 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConversionHelper.java +++ b/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConversionHelper.java
@@ -13,18 +13,23 @@ * constants in WebViewClient. */ public final class AwSafeBrowsingConversionHelper { - /** The resource was blocked for an unknown reason */ + /** The resource was blocked for an unknown reason. */ public static final int SAFE_BROWSING_THREAT_UNKNOWN = WebViewClient.SAFE_BROWSING_THREAT_UNKNOWN; - /** The resource was blocked because it contains malware */ + /** The resource was blocked because it contains malware. */ public static final int SAFE_BROWSING_THREAT_MALWARE = WebViewClient.SAFE_BROWSING_THREAT_MALWARE; - /** The resource was blocked because it contains deceptive content */ + /** The resource was blocked because it contains deceptive content. */ public static final int SAFE_BROWSING_THREAT_PHISHING = WebViewClient.SAFE_BROWSING_THREAT_PHISHING; - /** The resource was blocked because it contains unwanted software */ + /** The resource was blocked because it contains unwanted software. */ public static final int SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE = WebViewClient.SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE; + /** The resource was blocked because it may trick the user into a billing agreement. */ + // TODO(ntfschr): add a new int to the SDK. + public static final int SAFE_BROWSING_THREAT_BILLING = + WebViewClient.SAFE_BROWSING_THREAT_UNKNOWN; + /** * Converts the threat type value from SafeBrowsing code to the WebViewClient constant. */ @@ -36,6 +41,8 @@ return SAFE_BROWSING_THREAT_PHISHING; case SBThreatType.URL_UNWANTED: return SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE; + case SBThreatType.BILLING: + return SAFE_BROWSING_THREAT_BILLING; default: return SAFE_BROWSING_THREAT_UNKNOWN; }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java index ea2e4e7..eba1882 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingTest.java
@@ -101,6 +101,7 @@ private static final int PHISHING_PAGE_BACKGROUND_COLOR = Color.rgb(0, 0, 255); private static final int MALWARE_PAGE_BACKGROUND_COLOR = Color.rgb(0, 0, 255); private static final int UNWANTED_SOFTWARE_PAGE_BACKGROUND_COLOR = Color.rgb(0, 0, 255); + private static final int BILLING_PAGE_BACKGROUND_COLOR = Color.rgb(0, 0, 255); private static final int IFRAME_EMBEDDER_BACKGROUND_COLOR = Color.rgb(10, 10, 10); private static final String RESOURCE_PATH = "/android_webview/test/data"; @@ -114,6 +115,7 @@ private static final String MALWARE_HTML_PATH = RESOURCE_PATH + "/malware.html"; private static final String UNWANTED_SOFTWARE_HTML_PATH = RESOURCE_PATH + "/unwanted_software.html"; + private static final String BILLING_HTML_PATH = RESOURCE_PATH + "/billing.html"; // A gray page with an iframe to MALWARE_HTML_PATH private static final String IFRAME_HTML_PATH = RESOURCE_PATH + "/iframe.html"; @@ -130,9 +132,12 @@ public static class MockSafeBrowsingApiHandler implements SafeBrowsingApiHandler { private Observer mObserver; private static final String SAFE_METADATA = "{}"; + + // These codes are defined in "safebrowsing.proto". private static final int PHISHING_CODE = 5; private static final int MALWARE_CODE = 4; private static final int UNWANTED_SOFTWARE_CODE = 3; + private static final int BILLING_CODE = 15; // Mock time it takes for a lookup request to complete. private static final long CHECK_DELTA_US = 10; @@ -166,6 +171,9 @@ } else if (uri.endsWith(UNWANTED_SOFTWARE_HTML_PATH) && Arrays.binarySearch(threatsOfInterest, UNWANTED_SOFTWARE_CODE) >= 0) { metadata = buildMetadataFromCode(UNWANTED_SOFTWARE_CODE); + } else if (uri.endsWith(BILLING_HTML_PATH) + && Arrays.binarySearch(threatsOfInterest, BILLING_CODE) >= 0) { + metadata = buildMetadataFromCode(BILLING_CODE); } else { metadata = SAFE_METADATA; } @@ -486,6 +494,48 @@ @Test @SmallTest @Feature({"AndroidWebView"}) + @CommandLineFlags.Add("disable-features=BillingInterstitial") + public void testSafeBrowsingDoesNotBlockBillingPages() throws Throwable { + // TODO(ntfschr): this is a temporary check until we launch support for Billing warnings + // (http://crbug/887186). + loadGreenPage(); + final String responseUrl = mTestServer.getURL(BILLING_HTML_PATH); + mActivityTestRule.loadUrlSync( + mAwContents, mContentsClient.getOnPageFinishedHelper(), responseUrl); + assertTargetPageHasLoaded(BILLING_PAGE_BACKGROUND_COLOR); + } + + @Test + @SmallTest + @Feature({"AndroidWebView"}) + @CommandLineFlags.Add("enable-features=BillingInterstitial") + public void testSafeBrowsingBlocksBillingPages() throws Throwable { + loadGreenPage(); + loadPathAndWaitForInterstitial(BILLING_HTML_PATH); + assertGreenPageNotShowing(); + assertTargetPageNotShowing(BILLING_PAGE_BACKGROUND_COLOR); + // Assume that we are rendering the interstitial, since we see neither the previous page nor + // the target page + } + + @Test + @SmallTest + @Feature({"AndroidWebView"}) + @CommandLineFlags.Add("enable-features=BillingInterstitial") + public void testSafeBrowsingOnSafeBrowsingHitBillingCode() throws Throwable { + loadGreenPage(); + loadPathAndWaitForInterstitial(BILLING_HTML_PATH); + + // Check onSafeBrowsingHit arguments + final String responseUrl = mTestServer.getURL(BILLING_HTML_PATH); + Assert.assertEquals(responseUrl, mContentsClient.getLastRequest().url); + Assert.assertEquals(AwSafeBrowsingConversionHelper.SAFE_BROWSING_THREAT_BILLING, + mContentsClient.getLastThreatType()); + } + + @Test + @SmallTest + @Feature({"AndroidWebView"}) public void testSafeBrowsingBlocksPhishingPages() throws Throwable { loadGreenPage(); loadPathAndWaitForInterstitial(PHISHING_HTML_PATH); @@ -752,6 +802,18 @@ @Test @SmallTest @Feature({"AndroidWebView"}) + @CommandLineFlags.Add("enable-features=BillingInterstitial") + public void testSafeBrowsingCanShowQuietBillingInterstitial() throws Throwable { + mAwContents.setCanShowBigInterstitial(false); + loadGreenPage(); + loadPathAndWaitForInterstitial(BILLING_HTML_PATH); + assertGreenPageNotShowing(); + assertTargetPageNotShowing(BILLING_PAGE_BACKGROUND_COLOR); + } + + @Test + @SmallTest + @Feature({"AndroidWebView"}) public void testSafeBrowsingProceedQuietInterstitial() throws Throwable { mAwContents.setCanShowBigInterstitial(false); int pageFinishedCount = mContentsClient.getOnPageFinishedHelper().getCallCount();
diff --git a/android_webview/test/data/billing.html b/android_webview/test/data/billing.html new file mode 100644 index 0000000..ba2a808 --- /dev/null +++ b/android_webview/test/data/billing.html
@@ -0,0 +1,14 @@ +<html> + <head> + <style> + div { + background-color: rgb(0,0,255); + height: 100%; + width: 100%; + } + </style> + </head> + <body> + <div></div> + </body> +</html>
diff --git a/android_webview/ui/grit_strings_whitelist.txt b/android_webview/ui/grit_strings_whitelist.txt index efd4782..b1d47c34 100644 --- a/android_webview/ui/grit_strings_whitelist.txt +++ b/android_webview/ui/grit_strings_whitelist.txt
@@ -16,6 +16,10 @@ IDS_HARMFUL_V3_EXPLANATION_PARAGRAPH IDS_HARMFUL_V3_EXPLANATION_PARAGRAPH_SUBRESOURCE IDS_HARMFUL_V3_PROCEED_PARAGRAPH +IDS_BILLING_HEADING +IDS_BILLING_PRIMARY_PARAGRAPH +IDS_BILLING_PRIMARY_BUTTON +IDS_BILLING_PROCEED_BUTTON IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE IDS_SAFE_BROWSING_SCOUT_REPORTING_AGREE IDS_PHISHING_V4_HEADING @@ -28,6 +32,8 @@ IDS_PHISHING_WEBVIEW_EXPLANATION_PARAGRAPH IDS_HARMFUL_WEBVIEW_HEADING IDS_HARMFUL_WEBVIEW_EXPLANATION_PARAGRAPH +IDS_BILLING_WEBVIEW_HEADING +IDS_BILLING_WEBVIEW_EXPLANATION_PARAGRAPH IDS_SB_UNDER_CONSTRUCTION IDS_AUTOFILL_CC_AMEX IDS_AUTOFILL_CC_AMEX_SHORT
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index e14e8f0..477f37cf 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -240,6 +240,8 @@ "assistant/util/assistant_util.h", "assistant/util/deep_link_util.cc", "assistant/util/deep_link_util.h", + "assistant/util/histogram_util.cc", + "assistant/util/histogram_util.h", "assistant/util/views_util.cc", "assistant/util/views_util.h", "autoclick/autoclick_controller.cc", @@ -1141,8 +1143,6 @@ "wm/gestures/overview_gesture_handler.h", "wm/immersive_context_ash.cc", "wm/immersive_context_ash.h", - "wm/immersive_focus_watcher_classic.cc", - "wm/immersive_focus_watcher_classic.h", "wm/immersive_gesture_handler_classic.cc", "wm/immersive_gesture_handler_classic.h", "wm/immersive_handler_factory_ash.cc",
diff --git a/ash/app_list/app_list_presenter_delegate_impl.cc b/ash/app_list/app_list_presenter_delegate_impl.cc index e6ee690..a875edfb 100644 --- a/ash/app_list/app_list_presenter_delegate_impl.cc +++ b/ash/app_list/app_list_presenter_delegate_impl.cc
@@ -25,6 +25,7 @@ #include "base/command_line.h" #include "chromeos/chromeos_switches.h" #include "ui/aura/window.h" +#include "ui/display/manager/display_manager.h" #include "ui/events/event.h" #include "ui/keyboard/keyboard_controller.h" #include "ui/views/widget/widget.h" @@ -54,7 +55,9 @@ AppListPresenterDelegateImpl::AppListPresenterDelegateImpl( AppListControllerImpl* controller) - : controller_(controller) {} + : controller_(controller), display_observer_(this) { + display_observer_.Add(display::Screen::GetScreen()); +} AppListPresenterDelegateImpl::~AppListPresenterDelegateImpl() { Shell::Get()->RemovePreTargetHandler(this); @@ -77,11 +80,19 @@ aura::Window* root_window = Shell::GetRootWindowForDisplayId(display_id); app_list::AppListView::InitParams params; - params.parent = + aura::Window* parent_window = RootWindowController::ForWindow(root_window) ->GetContainer(IsHomeLauncherEnabledInTabletMode() ? kShellWindowId_AppListTabletModeContainer : kShellWindowId_AppListContainer); + + // Snap the window bounds to fit the screen size (See + // https://crbug.com/884889). + const gfx::Rect bounds = ash::screen_util::SnapBoundsToDisplayEdge( + parent_window->GetBoundsInScreen(), parent_window); + parent_window->SetBoundsInScreen( + bounds, Shell::Get()->display_manager()->GetDisplayForId(display_id)); + params.parent = parent_window; params.initial_apps_page = current_apps_page; params.is_tablet_mode = Shell::Get() ->tablet_mode_controller() @@ -171,6 +182,21 @@ controller_->OnTargetVisibilityChanged(visible); } +void AppListPresenterDelegateImpl::OnDisplayMetricsChanged( + const display::Display& display, + uint32_t changed_metrics) { + if (!presenter_->GetWindow()) + return; + + // Snap the window bounds to fit the screen size (See + // https://crbug.com/884889). + aura::Window* parent_window = presenter_->GetWindow()->parent(); + const gfx::Rect bounds = ash::screen_util::SnapBoundsToDisplayEdge( + parent_window->GetBoundsInScreen(), parent_window); + parent_window->SetBoundsInScreen(bounds, display); + view_->OnParentWindowBoundsChanged(); +} + //////////////////////////////////////////////////////////////////////////////// // AppListPresenterDelegateImpl, private:
diff --git a/ash/app_list/app_list_presenter_delegate_impl.h b/ash/app_list/app_list_presenter_delegate_impl.h index a82e5e4..8bf76ff 100644 --- a/ash/app_list/app_list_presenter_delegate_impl.h +++ b/ash/app_list/app_list_presenter_delegate_impl.h
@@ -10,6 +10,8 @@ #include "ash/app_list/presenter/app_list_presenter_delegate.h" #include "ash/ash_export.h" #include "base/macros.h" +#include "base/scoped_observer.h" +#include "ui/display/display_observer.h" #include "ui/events/event_handler.h" #include "ui/keyboard/keyboard_controller_observer.h" @@ -19,6 +21,10 @@ class AppListViewDelegate; } // namespace app_list +namespace display { +class Screen; +} // namespace display + namespace ui { class LocatedEvent; } // namespace ui @@ -33,7 +39,8 @@ // update its layout as necessary. class ASH_EXPORT AppListPresenterDelegateImpl : public app_list::AppListPresenterDelegate, - public ui::EventHandler { + public ui::EventHandler, + public display::DisplayObserver { public: explicit AppListPresenterDelegateImpl(AppListControllerImpl* controller); ~AppListPresenterDelegateImpl() override; @@ -56,6 +63,10 @@ void OnVisibilityChanged(bool visible, aura::Window* root_window) override; void OnTargetVisibilityChanged(bool visible) override; + // DisplayObserver overrides: + void OnDisplayMetricsChanged(const display::Display& display, + uint32_t changed_metrics) override; + private: void ProcessLocatedEvent(ui::LocatedEvent* event); @@ -75,6 +86,9 @@ // Not owned, owns this class. AppListControllerImpl* const controller_ = nullptr; + // An observer that notifies AppListView when the display has changed. + ScopedObserver<display::Screen, display::DisplayObserver> display_observer_; + DISALLOW_COPY_AND_ASSIGN(AppListPresenterDelegateImpl); };
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index fe8395f..cea51a7 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -306,7 +306,6 @@ model_(delegate->GetModel()), search_model_(delegate->GetSearchModel()), is_background_blur_enabled_(app_list_features::IsBackgroundBlurEnabled()), - display_observer_(this), hide_view_animation_observer_( std::make_unique<HideViewAnimationObserver>()), transition_animation_observer_( @@ -321,7 +320,6 @@ weak_ptr_factory_(this) { CHECK(delegate); - display_observer_.Add(display::Screen::GetScreen()); // Enable arrow key in FocusManager. Arrow left/right and up/down triggers // the same focus movement as tab/shift+tab. views::FocusManager::set_arrow_key_traversal_enabled(true); @@ -577,8 +575,8 @@ SetBackgroundShieldColor(); if (is_background_blur_enabled_ && !IsHomeLauncherEnabledInTabletMode()) { app_list_background_shield_mask_ = views::Painter::CreatePaintedLayer( - views::Painter::CreateSolidRoundRectPainter( - SK_ColorBLACK, AppListConfig::instance().blur_radius())); + views::Painter::CreateSolidRoundRectPainter(SK_ColorBLACK, + kAppListBackgroundRadius)); app_list_background_shield_mask_->layer()->SetFillsBoundsOpaquely(false); app_list_background_shield_->layer()->SetMaskLayer( app_list_background_shield_mask_->layer()); @@ -1607,8 +1605,7 @@ return false; } -void AppListView::OnDisplayMetricsChanged(const display::Display& display, - uint32_t changed_metrics) { +void AppListView::OnParentWindowBoundsChanged() { // Set the |fullscreen_widget_| size to fit the new display metrics. fullscreen_widget_->GetNativeView()->SetBounds( GetPreferredWidgetBoundsForState(app_list_state_));
diff --git a/ash/app_list/views/app_list_view.h b/ash/app_list/views/app_list_view.h index dc053031..84df413 100644 --- a/ash/app_list/views/app_list_view.h +++ b/ash/app_list/views/app_list_view.h
@@ -14,9 +14,7 @@ #include "ash/public/cpp/app_list/app_list_constants.h" #include "base/callback.h" #include "base/macros.h" -#include "base/scoped_observer.h" #include "build/build_config.h" -#include "ui/display/display_observer.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" @@ -25,7 +23,7 @@ } namespace display { -class Screen; +class Display; } namespace ui { @@ -49,8 +47,7 @@ // and hosts a AppsGridView and passes AppListModel to it for display. // TODO(newcomer|weidongg): Organize the cc file to match the order of // definitions in this header. -class APP_LIST_EXPORT AppListView : public views::WidgetDelegateView, - public display::DisplayObserver { +class APP_LIST_EXPORT AppListView : public views::WidgetDelegateView { public: class TestApi { public: @@ -187,6 +184,9 @@ // Called when on-screen keyboard's visibility is changed. void OnScreenKeyboardShown(bool shown); + // Called when parent window's bounds is changed. + void OnParentWindowBoundsChanged(); + // If the on-screen keyboard is shown, hide it. Return whether keyboard was // hidden bool CloseKeyboardIfVisible(); @@ -321,10 +321,6 @@ // Overridden from views::WidgetDelegateView: views::View* GetInitiallyFocusedView() override; - // Overridden from DisplayObserver: - void OnDisplayMetricsChanged(const display::Display& display, - uint32_t changed_metrics) override; - // Gets app list background opacity during dragging. float GetAppListBackgroundOpacityDuringDragging(); @@ -392,8 +388,6 @@ const bool is_background_blur_enabled_; // The state of the app list, controlled via SetState(). AppListViewState app_list_state_ = AppListViewState::PEEKING; - // An observer that notifies AppListView when the display has changed. - ScopedObserver<display::Screen, display::DisplayObserver> display_observer_; // A widget observer that sets the AppListView state when the widget is // closed.
diff --git a/ash/assistant/assistant_interaction_controller.cc b/ash/assistant/assistant_interaction_controller.cc index 01a8917d..7ecf779 100644 --- a/ash/assistant/assistant_interaction_controller.cc +++ b/ash/assistant/assistant_interaction_controller.cc
@@ -4,7 +4,6 @@ #include "ash/assistant/assistant_interaction_controller.h" -#include <map> #include <utility> #include "ash/assistant/assistant_controller.h" @@ -16,6 +15,7 @@ #include "ash/assistant/model/assistant_ui_element.h" #include "ash/assistant/ui/assistant_ui_constants.h" #include "ash/assistant/util/deep_link_util.h" +#include "ash/assistant/util/histogram_util.h" #include "ash/public/interfaces/voice_interaction_controller.mojom.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" @@ -90,8 +90,8 @@ void AssistantInteractionController::OnDeepLinkReceived( assistant::util::DeepLinkType type, const std::map<std::string, std::string>& params) { - using assistant::util::DeepLinkType; using assistant::util::DeepLinkParam; + using assistant::util::DeepLinkType; if (type == DeepLinkType::kWhatsOnMyScreen) { StartScreenContextInteraction(); @@ -226,6 +226,12 @@ StopActiveInteraction(false); } +void AssistantInteractionController::OnResponseChanged( + const std::shared_ptr<AssistantResponse>& response) { + assistant::util::IncrementAssistantQueryCountForEntryPoint( + assistant_controller_->ui_controller()->model()->entry_point()); +} + void AssistantInteractionController::OnResponseDestroying( AssistantResponse& response) { response.RemoveObserver(this); @@ -247,6 +253,13 @@ void AssistantInteractionController::OnInteractionStarted( bool is_voice_interaction) { + if (is_voice_interaction) { + // If the Assistant UI is not visible yet, and |is_voice_interaction| is + // true, then it will be sure that Assistant is fired via OKG. ShowUi will + // not update the Assistant entry point if the UI is already visible. + assistant_controller_->ui_controller()->ShowUi(AssistantSource::kHotword); + } + model_.SetInteractionState(InteractionState::kActive); // In the case of a voice interaction, we assume that the mic is open and @@ -339,7 +352,8 @@ } void AssistantInteractionController::OnHtmlResponse( - const std::string& response) { + const std::string& response, + const std::string& fallback) { if (model_.interaction_state() != InteractionState::kActive) { return; } @@ -352,7 +366,7 @@ } model_.pending_response()->AddUiElement( - std::make_unique<AssistantCardElement>(response)); + std::make_unique<AssistantCardElement>(response, fallback)); } void AssistantInteractionController::OnSuggestionChipPressed(
diff --git a/ash/assistant/assistant_interaction_controller.h b/ash/assistant/assistant_interaction_controller.h index 4fc28a3..f56686f1 100644 --- a/ash/assistant/assistant_interaction_controller.h +++ b/ash/assistant/assistant_interaction_controller.h
@@ -5,6 +5,7 @@ #ifndef ASH_ASSISTANT_ASSISTANT_INTERACTION_CONTROLLER_H_ #define ASH_ASSISTANT_ASSISTANT_INTERACTION_CONTROLLER_H_ +#include <map> #include <memory> #include <string> #include <vector> @@ -67,6 +68,8 @@ // AssistantInteractionModelObserver: void OnInteractionStateChanged(InteractionState interaction_state) override; void OnInputModalityChanged(InputModality input_modality) override; + void OnResponseChanged( + const std::shared_ptr<AssistantResponse>& response) override; // AssistantResponseObserver: void OnResponseDestroying(AssistantResponse& response) override; @@ -85,7 +88,8 @@ void OnInteractionStarted(bool is_voice_interaction) override; void OnInteractionFinished( AssistantInteractionResolution resolution) override; - void OnHtmlResponse(const std::string& response) override; + void OnHtmlResponse(const std::string& response, + const std::string& fallback) override; void OnSuggestionsResponse( std::vector<AssistantSuggestionPtr> response) override; void OnTextResponse(const std::string& response) override;
diff --git a/ash/assistant/assistant_notification_controller.cc b/ash/assistant/assistant_notification_controller.cc index 61d7ba6..0f3c727 100644 --- a/ash/assistant/assistant_notification_controller.cc +++ b/ash/assistant/assistant_notification_controller.cc
@@ -5,6 +5,7 @@ #include "ash/assistant/assistant_notification_controller.h" #include "ash/assistant/assistant_controller.h" +#include "ash/assistant/util/deep_link_util.h" #include "ash/new_window_controller.h" #include "ash/public/cpp/vector_icons/vector_icons.h" #include "ash/public/interfaces/voice_interaction_controller.mojom.h" @@ -54,16 +55,27 @@ void Click(const base::Optional<int>& button_index, const base::Optional<base::string16>& reply) override { + const auto& action_url = + button_index.has_value() + ? notification_->buttons[button_index.value()]->action_url + : notification_->action_url; // Open the action url if it is valid. - if (notification_->action_url.is_valid() && assistant_controller_) { - assistant_controller_->OpenUrl(notification_->action_url); + if (action_url.is_valid() && + (action_url.SchemeIsHTTPOrHTTPS() || + assistant::util::IsDeepLinkUrl(action_url)) && + assistant_controller_) { + assistant_controller_->OpenUrl(action_url); + Close(/*by_user=*/true); return; } if (notification_controller_) { - // TODO(wutao): support buttons with different |action_index|. + // Action index 0 is the top level action and the first button's action + // index is 1. + const int action_index = + button_index.has_value() ? button_index.value() + 1 : 0; notification_controller_->RetrieveNotification(notification_.Clone(), - /*action_index=*/0); + action_index); } } @@ -138,13 +150,17 @@ message_center::MessageCenter* message_center = message_center::MessageCenter::Get(); - message_center::RichNotificationData optional_field; + message_center::RichNotificationData data; + for (const auto& button : notification->buttons) { + data.buttons.push_back( + message_center::ButtonInfo(base::UTF8ToUTF16(button->label))); + } std::unique_ptr<message_center::Notification> system_notification = message_center::Notification::CreateSystemNotification( message_center::NOTIFICATION_TYPE_SIMPLE, GetNotificationId(notification->grouping_key), title, message, - display_source, GURL(), notifier_id_, optional_field, + display_source, GURL(), notifier_id_, data, new AssistantNotificationDelegate(weak_factory_.GetWeakPtr(), assistant_controller_->GetWeakPtr(), notification.Clone()),
diff --git a/ash/assistant/assistant_ui_controller.cc b/ash/assistant/assistant_ui_controller.cc index 2fd1a2b..eed37365 100644 --- a/ash/assistant/assistant_ui_controller.cc +++ b/ash/assistant/assistant_ui_controller.cc
@@ -104,7 +104,7 @@ // If there is an active interaction, we need to show Assistant UI if it is // not already showing. We don't have enough information here to know what - // the interaction source is, but at the moment we have no need to know. + // the interaction source is. ShowUi(AssistantSource::kUnspecified); }
diff --git a/ash/assistant/model/assistant_ui_element.cc b/ash/assistant/model/assistant_ui_element.cc index 422af0e..8c5d3fd 100644 --- a/ash/assistant/model/assistant_ui_element.cc +++ b/ash/assistant/model/assistant_ui_element.cc
@@ -8,9 +8,11 @@ // AssistantCardElement -------------------------------------------------------- -AssistantCardElement::AssistantCardElement(const std::string& html) +AssistantCardElement::AssistantCardElement(const std::string& html, + const std::string& fallback) : AssistantUiElement(AssistantUiElementType::kCard), html_(html), + fallback_(fallback), id_token_(base::UnguessableToken::Create()) {} AssistantCardElement::~AssistantCardElement() = default;
diff --git a/ash/assistant/model/assistant_ui_element.h b/ash/assistant/model/assistant_ui_element.h index 6e0ca60..67c9df2c 100644 --- a/ash/assistant/model/assistant_ui_element.h +++ b/ash/assistant/model/assistant_ui_element.h
@@ -44,11 +44,14 @@ // An Assistant UI element that will be rendered as an HTML card. class AssistantCardElement : public AssistantUiElement { public: - explicit AssistantCardElement(const std::string& html); + explicit AssistantCardElement(const std::string& html, + const std::string& fallback); ~AssistantCardElement() override; const std::string& html() const { return html_; } + const std::string& fallback() const { return fallback_; } + const base::UnguessableToken& id_token() const { return id_token_; } const base::Optional<base::UnguessableToken>& embed_token() const { @@ -62,6 +65,7 @@ private: const std::string html_; + const std::string fallback_; base::UnguessableToken id_token_; base::Optional<base::UnguessableToken> embed_token_ = base::nullopt;
diff --git a/ash/assistant/model/assistant_ui_model.cc b/ash/assistant/model/assistant_ui_model.cc index 6374ffe..c46d0d4a 100644 --- a/ash/assistant/model/assistant_ui_model.cc +++ b/ash/assistant/model/assistant_ui_model.cc
@@ -36,6 +36,10 @@ const AssistantVisibility old_visibility = visibility_; visibility_ = visibility; + // Cache the Assistant entry point used for query count UMA metric. + if (visibility == AssistantVisibility::kVisible) + entry_point_ = source; + NotifyUiVisibilityChanged(old_visibility, source); }
diff --git a/ash/assistant/model/assistant_ui_model.h b/ash/assistant/model/assistant_ui_model.h index efed31b..93ecfc7 100644 --- a/ash/assistant/model/assistant_ui_model.h +++ b/ash/assistant/model/assistant_ui_model.h
@@ -13,16 +13,21 @@ class AssistantUiModelObserver; -// Enumeration of Assistant entry/exit points. +// Enumeration of Assistant entry/exit points, also recorded in histograms. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. Only append to this enum is allowed +// if the possible source grows. enum class AssistantSource { - kUnspecified, - kDeepLink, - kHotkey, - kHotword, - kLauncherSearchBox, - kLongPressLauncher, - kSetup, - kStylus, + kUnspecified = 0, + kDeepLink = 1, + kHotkey = 2, + kHotword = 3, + kLauncherSearchBox = 4, + kLongPressLauncher = 5, + kSetup = 6, + kStylus = 7, + // Special enumerator value used by histogram macros. + kMaxValue = kStylus }; // Enumeration of Assistant UI modes. @@ -66,6 +71,9 @@ // Returns the current usable work area. const gfx::Rect& usable_work_area() const { return usable_work_area_; } + // Returns the UI entry point. Only valid while UI is visible. + AssistantSource entry_point() const { return entry_point_; } + private: void NotifyUiModeChanged(); void NotifyUiVisibilityChanged(AssistantVisibility old_visibility, @@ -76,6 +84,8 @@ AssistantVisibility visibility_ = AssistantVisibility::kClosed; + AssistantSource entry_point_ = AssistantSource::kUnspecified; + base::ObserverList<AssistantUiModelObserver>::Unchecked observers_; // Usable work area for Assistant. Value is only meaningful when Assistant
diff --git a/ash/assistant/ui/main_stage/assistant_main_stage.cc b/ash/assistant/ui/main_stage/assistant_main_stage.cc index f774e25..4d1bc53 100644 --- a/ash/assistant/ui/main_stage/assistant_main_stage.cc +++ b/ash/assistant/ui/main_stage/assistant_main_stage.cc
@@ -623,6 +623,10 @@ ui::LayerAnimationElement::AnimatableProperty::OPACITY, kFooterEntryAnimationFadeInDelay), CreateOpacityElement(1.f, kFooterEntryAnimationFadeInDuration))); + } else { + // A pending query is present so we simulate a change event to synchronize + // view state with interaction model state. + OnPendingQueryChanged(pending_query); } return;
diff --git a/ash/assistant/ui/main_stage/ui_element_container_view.cc b/ash/assistant/ui/main_stage/ui_element_container_view.cc index ab21c4d8..2683a664 100644 --- a/ash/assistant/ui/main_stage/ui_element_container_view.cc +++ b/ash/assistant/ui/main_stage/ui_element_container_view.cc
@@ -27,6 +27,7 @@ #include "ui/events/event.h" #include "ui/events/event_sink.h" #include "ui/events/event_utils.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/border.h" #include "ui/views/controls/native/native_view_host.h" #include "ui/views/layout/box_layout.h" @@ -90,8 +91,9 @@ class CardElementViewHolder : public views::NativeViewHost, public views::ViewObserver { public: - explicit CardElementViewHolder(views::View* card_element_view) - : card_element_view_(card_element_view) { + explicit CardElementViewHolder(const AssistantCardElement* card_element) + : card_element_view_(app_list::AnswerCardContentsRegistry::Get()->GetView( + card_element->embed_token().value())) { views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL); params.name = GetClassName(); @@ -107,6 +109,9 @@ contents_view_->AddChildView(card_element_view_); card_element_view_->AddObserver(this); + + // OverrideDescription() doesn't work. Only names are read automatically. + GetViewAccessibility().OverrideName(card_element->fallback()); } ~CardElementViewHolder() override { @@ -398,9 +403,7 @@ // When the card has been rendered in the same process, its view is // available in the AnswerCardContentsRegistry's token-to-view map. if (app_list::AnswerCardContentsRegistry::Get()) { - CardElementViewHolder* view_holder = new CardElementViewHolder( - app_list::AnswerCardContentsRegistry::Get()->GetView( - card_element->embed_token().value())); + auto* view_holder = new CardElementViewHolder(card_element); if (is_first_card_) { is_first_card_ = false; @@ -482,9 +485,9 @@ CreateOpacityElement(1.f, kUiElementAnimationFadeInDuration))); } - // TODO(luciferleo): Add ChromeVox description for WebView. - // Let screen reader read the query result. We don't read when there is TTS to - // avoid speaking over the server response. + // Let screen reader read the query result. This includes the text response + // and the card fallback text, but webview result is not included. + // We don't read when there is TTS to avoid speaking over the server response. const AssistantResponse* response = assistant_controller_->interaction_controller()->model()->response(); if (!response->has_tts())
diff --git a/ash/assistant/util/histogram_util.cc b/ash/assistant/util/histogram_util.cc new file mode 100644 index 0000000..6830c48e --- /dev/null +++ b/ash/assistant/util/histogram_util.cc
@@ -0,0 +1,20 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/assistant/util/histogram_util.h" + +#include "ash/assistant/model/assistant_ui_model.h" +#include "base/metrics/histogram_macros.h" + +namespace ash { +namespace assistant { +namespace util { + +void IncrementAssistantQueryCountForEntryPoint(AssistantSource entry_point) { + UMA_HISTOGRAM_ENUMERATION("Assistant.QueryCountPerEntryPoint", entry_point); +} + +} // namespace util +} // namespace assistant +} // namespace ash
diff --git a/ash/assistant/util/histogram_util.h b/ash/assistant/util/histogram_util.h new file mode 100644 index 0000000..8381284a --- /dev/null +++ b/ash/assistant/util/histogram_util.h
@@ -0,0 +1,22 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_ASSISTANT_UTIL_HISTOGRAM_UTIL_H_ +#define ASH_ASSISTANT_UTIL_HISTOGRAM_UTIL_H_ + +namespace ash { + +enum class AssistantSource; + +namespace assistant { +namespace util { + +// Increment number of queries fired for each entry point. +void IncrementAssistantQueryCountForEntryPoint(AssistantSource entry_point); + +} // namespace util +} // namespace assistant +} // namespace ash + +#endif // ASH_ASSISTANT_UTIL_HISTOGRAM_UTIL_H_
diff --git a/ash/login/resources/default_200_percent/common/fingerprint_unlock_spinner.png b/ash/login/resources/default_200_percent/common/fingerprint_unlock_spinner.png index 78ec9fed..b92eed1 100644 --- a/ash/login/resources/default_200_percent/common/fingerprint_unlock_spinner.png +++ b/ash/login/resources/default_200_percent/common/fingerprint_unlock_spinner.png Binary files differ
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn index b8753420..edf9730 100644 --- a/ash/public/cpp/BUILD.gn +++ b/ash/public/cpp/BUILD.gn
@@ -70,6 +70,7 @@ "frame_utils.h", "gesture_action_type.h", "immersive/immersive_context.h", + "immersive/immersive_focus_watcher.cc", "immersive/immersive_focus_watcher.h", "immersive/immersive_fullscreen_controller.cc", "immersive/immersive_fullscreen_controller.h", @@ -135,6 +136,7 @@ "//ui/views", "//ui/views/mus", "//ui/wm", + "//ui/wm/public", ] public_deps = [
diff --git a/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc b/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc index 755c065..9352491e 100644 --- a/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc +++ b/ash/public/cpp/caption_buttons/frame_caption_button_container_view.cc
@@ -158,12 +158,8 @@ : frame_(frame), delegate_(delegate), model_(std::make_unique<DefaultCaptionButtonModel>(frame)) { - constexpr int kTouchOptimizedCaptionButtonsSpacing = 8; - auto layout = std::make_unique<views::BoxLayout>( - views::BoxLayout::kHorizontal, gfx::Insets(), - ui::MaterialDesignController::IsTouchOptimizedUiEnabled() - ? kTouchOptimizedCaptionButtonsSpacing - : 0); + auto layout = + std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal); layout->set_cross_axis_alignment( views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_END);
diff --git a/chrome/browser/ui/views/frame/immersive_focus_watcher_mus.cc b/ash/public/cpp/immersive/immersive_focus_watcher.cc similarity index 76% rename from chrome/browser/ui/views/frame/immersive_focus_watcher_mus.cc rename to ash/public/cpp/immersive/immersive_focus_watcher.cc index 59820189..d2fa620 100644 --- a/chrome/browser/ui/views/frame/immersive_focus_watcher_mus.cc +++ b/ash/public/cpp/immersive/immersive_focus_watcher.cc
@@ -2,19 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/frame/immersive_focus_watcher_mus.h" +#include "ash/public/cpp/immersive/immersive_focus_watcher.h" #include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" #include "ui/aura/client/transient_window_client.h" -#include "ui/aura/mus/focus_synchronizer.h" -#include "ui/aura/mus/window_tree_client.h" #include "ui/aura/window.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" -#include "ui/views/mus/mus_client.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" #include "ui/wm/public/activation_client.h" +namespace ash { + namespace { // Returns the BubbleDialogDelegateView corresponding to |maybe_bubble| if @@ -63,9 +62,9 @@ // so that bubbles which are not activatable and bubbles which do not close // upon deactivation also keep the top-of-window views revealed for the // duration of their visibility. -class ImmersiveFocusWatcherMus::BubbleObserver : public aura::WindowObserver { +class ImmersiveFocusWatcher::BubbleObserver : public aura::WindowObserver { public: - explicit BubbleObserver(ash::ImmersiveFullscreenController* controller); + explicit BubbleObserver(ImmersiveFullscreenController* controller); ~BubbleObserver() override; // Start / stop observing changes to |bubble|'s visibility. @@ -80,27 +79,27 @@ void OnWindowVisibilityChanged(aura::Window* window, bool visible) override; void OnWindowDestroying(aura::Window* window) override; - ash::ImmersiveFullscreenController* controller_; + ImmersiveFullscreenController* controller_; std::set<aura::Window*> bubbles_; // Lock which keeps the top-of-window views revealed based on whether any of // |bubbles_| is visible. - std::unique_ptr<ash::ImmersiveRevealedLock> revealed_lock_; + std::unique_ptr<ImmersiveRevealedLock> revealed_lock_; DISALLOW_COPY_AND_ASSIGN(BubbleObserver); }; -ImmersiveFocusWatcherMus::BubbleObserver::BubbleObserver( - ash::ImmersiveFullscreenController* controller) +ImmersiveFocusWatcher::BubbleObserver::BubbleObserver( + ImmersiveFullscreenController* controller) : controller_(controller) {} -ImmersiveFocusWatcherMus::BubbleObserver::~BubbleObserver() { +ImmersiveFocusWatcher::BubbleObserver::~BubbleObserver() { for (aura::Window* bubble : bubbles_) bubble->RemoveObserver(this); } -void ImmersiveFocusWatcherMus::BubbleObserver::StartObserving( +void ImmersiveFocusWatcher::BubbleObserver::StartObserving( aura::Window* bubble) { if (bubbles_.insert(bubble).second) { bubble->AddObserver(this); @@ -108,7 +107,7 @@ } } -void ImmersiveFocusWatcherMus::BubbleObserver::StopObserving( +void ImmersiveFocusWatcher::BubbleObserver::StopObserving( aura::Window* bubble) { if (bubbles_.erase(bubble)) { bubble->RemoveObserver(this); @@ -116,7 +115,7 @@ } } -void ImmersiveFocusWatcherMus::BubbleObserver::UpdateRevealedLock() { +void ImmersiveFocusWatcher::BubbleObserver::UpdateRevealedLock() { bool has_visible_bubble = false; for (aura::Window* bubble : bubbles_) { if (bubble->IsVisible()) { @@ -132,7 +131,7 @@ // weird for the top-of-window views to animate and the bubble not to // animate along with the top-of-window views. revealed_lock_.reset(controller_->GetRevealedLock( - ash::ImmersiveFullscreenController::ANIMATE_REVEAL_NO)); + ImmersiveFullscreenController::ANIMATE_REVEAL_NO)); } } else { revealed_lock_.reset(); @@ -149,35 +148,37 @@ } } -void ImmersiveFocusWatcherMus::BubbleObserver::OnWindowVisibilityChanged( +void ImmersiveFocusWatcher::BubbleObserver::OnWindowVisibilityChanged( aura::Window*, bool visible) { UpdateRevealedLock(); } -void ImmersiveFocusWatcherMus::BubbleObserver::OnWindowDestroying( +void ImmersiveFocusWatcher::BubbleObserver::OnWindowDestroying( aura::Window* window) { StopObserving(window); } -ImmersiveFocusWatcherMus::ImmersiveFocusWatcherMus( - ash::ImmersiveFullscreenController* controller) +ImmersiveFocusWatcher::ImmersiveFocusWatcher( + ImmersiveFullscreenController* controller) : immersive_fullscreen_controller_(controller) { GetWidget()->GetFocusManager()->AddFocusChangeListener(this); aura::client::GetTransientWindowClient()->AddObserver(this); - ::wm::GetActivationClient(GetWidgetWindow())->AddObserver(this); + ::wm::GetActivationClient(GetWidgetWindow()->GetRootWindow()) + ->AddObserver(this); RecreateBubbleObserver(); } -ImmersiveFocusWatcherMus::~ImmersiveFocusWatcherMus() { +ImmersiveFocusWatcher::~ImmersiveFocusWatcher() { aura::client::GetTransientWindowClient()->RemoveObserver(this); GetWidget()->GetFocusManager()->RemoveFocusChangeListener(this); - auto* activation_client = ::wm::GetActivationClient(GetWidgetWindow()); + auto* activation_client = + ::wm::GetActivationClient(GetWidgetWindow()->GetRootWindow()); if (activation_client) activation_client->RemoveObserver(this); } -void ImmersiveFocusWatcherMus::UpdateFocusRevealedLock() { +void ImmersiveFocusWatcher::UpdateFocusRevealedLock() { views::Widget* widget = GetWidget(); views::View* top_container = immersive_fullscreen_controller_->top_container(); @@ -188,10 +189,9 @@ hold_lock = true; } else { aura::Window* native_window = GetWidgetWindow(); - aura::Window* active_window = views::MusClient::Get() - ->window_tree_client() - ->focus_synchronizer() - ->active_focus_client_root(); + aura::Window* active_window = + ::wm::GetActivationClient(native_window->GetRootWindow()) + ->GetActiveWindow(); if (GetAnchorView(active_window)) { // BubbleObserver will already have locked the top-of-window views if the // bubble is anchored to a child of |top_container|. Don't acquire @@ -219,26 +219,26 @@ if (hold_lock) { if (!lock_.get()) { lock_.reset(immersive_fullscreen_controller_->GetRevealedLock( - ash::ImmersiveFullscreenController::ANIMATE_REVEAL_YES)); + ImmersiveFullscreenController::ANIMATE_REVEAL_YES)); } } else { lock_.reset(); } } -void ImmersiveFocusWatcherMus::ReleaseLock() { +void ImmersiveFocusWatcher::ReleaseLock() { lock_.reset(); } -views::Widget* ImmersiveFocusWatcherMus::GetWidget() { +views::Widget* ImmersiveFocusWatcher::GetWidget() { return immersive_fullscreen_controller_->widget(); } -aura::Window* ImmersiveFocusWatcherMus::GetWidgetWindow() { - return GetWidget()->GetNativeWindow()->GetRootWindow(); +aura::Window* ImmersiveFocusWatcher::GetWidgetWindow() { + return GetWidget()->GetNativeWindow(); } -void ImmersiveFocusWatcherMus::RecreateBubbleObserver() { +void ImmersiveFocusWatcher::RecreateBubbleObserver() { bubble_observer_.reset(new BubbleObserver(immersive_fullscreen_controller_)); const std::vector<aura::Window*> transient_children = aura::client::GetTransientWindowClient()->GetTransientChildren( @@ -253,22 +253,22 @@ } } -void ImmersiveFocusWatcherMus::OnWillChangeFocus(views::View* focused_before, - views::View* focused_now) {} +void ImmersiveFocusWatcher::OnWillChangeFocus(views::View* focused_before, + views::View* focused_now) {} -void ImmersiveFocusWatcherMus::OnDidChangeFocus(views::View* focused_before, - views::View* focused_now) { +void ImmersiveFocusWatcher::OnDidChangeFocus(views::View* focused_before, + views::View* focused_now) { UpdateFocusRevealedLock(); } -void ImmersiveFocusWatcherMus::OnWindowActivated( +void ImmersiveFocusWatcher::OnWindowActivated( ::wm::ActivationChangeObserver::ActivationReason reason, aura::Window* gaining_active, aura::Window* losing_active) { UpdateFocusRevealedLock(); } -void ImmersiveFocusWatcherMus::OnTransientChildWindowAdded( +void ImmersiveFocusWatcher::OnTransientChildWindowAdded( aura::Window* window, aura::Window* transient) { views::View* anchor = GetAnchorView(transient); @@ -281,8 +281,10 @@ } } -void ImmersiveFocusWatcherMus::OnTransientChildWindowRemoved( +void ImmersiveFocusWatcher::OnTransientChildWindowRemoved( aura::Window* window, aura::Window* transient) { bubble_observer_->StopObserving(transient); } + +} // namespace ash
diff --git a/ash/public/cpp/immersive/immersive_focus_watcher.h b/ash/public/cpp/immersive/immersive_focus_watcher.h index 873b171..7799b06f 100644 --- a/ash/public/cpp/immersive/immersive_focus_watcher.h +++ b/ash/public/cpp/immersive/immersive_focus_watcher.h
@@ -1,27 +1,79 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FOCUS_WATCHER_H_ #define ASH_PUBLIC_CPP_IMMERSIVE_IMMERSIVE_FOCUS_WATCHER_H_ -#include "ash/public/cpp/ash_public_export.h" +#include "ui/aura/client/focus_change_observer.h" +#include "ui/aura/client/transient_window_client_observer.h" +#include "ui/views/focus/focus_manager.h" +#include "ui/wm/public/activation_change_observer.h" namespace ash { +class ImmersiveFullscreenController; +class ImmersiveRevealedLock; // ImmersiveFocusWatcher is responsible for grabbing a reveal lock based on -// activation and/or focus. -class ASH_PUBLIC_EXPORT ImmersiveFocusWatcher { +// activation and/or focus. This implementation grabs a lock if views focus is +// in the top view, a bubble is showing that is anchored to the top view, or +// the focused window is a transient child of the top view's widget. +class ImmersiveFocusWatcher + : public views::FocusChangeListener, + public aura::client::TransientWindowClientObserver, + public ::wm::ActivationChangeObserver { public: - virtual ~ImmersiveFocusWatcher() {} + explicit ImmersiveFocusWatcher(ImmersiveFullscreenController* controller); + ~ImmersiveFocusWatcher() override; // Forces updating the status of the lock. That is, this determines whether // a lock should be held and updates accordingly. The lock is automatically // maintained, but this function may be called to force an update. - virtual void UpdateFocusRevealedLock() = 0; + void UpdateFocusRevealedLock(); // Explicitly releases the lock, does nothing if a lock is not held. - virtual void ReleaseLock() = 0; + void ReleaseLock(); + + private: + class BubbleObserver; + + views::Widget* GetWidget(); + aura::Window* GetWidgetWindow(); + + // Recreate |bubble_observer_| and start observing any bubbles anchored to a + // child of |top_container_|. + void RecreateBubbleObserver(); + + // views::FocusChangeListener overrides: + void OnWillChangeFocus(views::View* focused_before, + views::View* focused_now) override; + void OnDidChangeFocus(views::View* focused_before, + views::View* focused_now) override; + + // aura::client::TransientWindowClientObserver overrides: + void OnTransientChildWindowAdded(aura::Window* window, + aura::Window* transient) override; + void OnTransientChildWindowRemoved(aura::Window* window, + aura::Window* transient) override; + + // ::wm::ActivationChangeObserver: + void OnWindowActivated( + ::wm::ActivationChangeObserver::ActivationReason reason, + aura::Window* gaining_active, + aura::Window* losing_active) override; + + ImmersiveFullscreenController* immersive_fullscreen_controller_; + + // Lock which keeps the top-of-window views revealed based on the focused view + // and the active widget. Acquiring the lock never triggers a reveal because + // a view is not focusable till a reveal has made it visible. + std::unique_ptr<ImmersiveRevealedLock> lock_; + + // Manages bubbles which are anchored to a child of + // |ImmersiveFullscreenController::top_container_|. + std::unique_ptr<BubbleObserver> bubble_observer_; + + DISALLOW_COPY_AND_ASSIGN(ImmersiveFocusWatcher); }; } // namespace ash
diff --git a/ash/public/cpp/immersive/immersive_fullscreen_controller.cc b/ash/public/cpp/immersive/immersive_fullscreen_controller.cc index b3783b12..0c934ae 100644 --- a/ash/public/cpp/immersive/immersive_fullscreen_controller.cc +++ b/ash/public/cpp/immersive/immersive_fullscreen_controller.cc
@@ -327,8 +327,7 @@ aura::Env* env = widget_->GetNativeWindow()->env(); if (enable) { - immersive_focus_watcher_ = - ImmersiveHandlerFactory::Get()->CreateFocusWatcher(this); + immersive_focus_watcher_ = std::make_unique<ImmersiveFocusWatcher>(this); immersive_gesture_handler_ = ImmersiveHandlerFactory::Get()->CreateGestureHandler(this); std::set<ui::EventType> types = {
diff --git a/ash/public/cpp/immersive/immersive_handler_factory.h b/ash/public/cpp/immersive/immersive_handler_factory.h index 5274167..418153e 100644 --- a/ash/public/cpp/immersive/immersive_handler_factory.h +++ b/ash/public/cpp/immersive/immersive_handler_factory.h
@@ -11,7 +11,6 @@ namespace ash { -class ImmersiveFocusWatcher; class ImmersiveFullscreenController; class ImmersiveGestureHandler; @@ -20,9 +19,6 @@ public: static ImmersiveHandlerFactory* Get() { return instance_; } - virtual std::unique_ptr<ImmersiveFocusWatcher> CreateFocusWatcher( - ImmersiveFullscreenController* controller) = 0; - virtual std::unique_ptr<ImmersiveGestureHandler> CreateGestureHandler( ImmersiveFullscreenController* controller) = 0;
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index e906d68..56beca4e 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -97,10 +97,8 @@ // TODO(sammiequon): This should be the same as IsTabletModeEnabled once home // launcher flag is removed. -bool IsHomeLauncherEnabled() { - return Shell::Get() - ->app_list_controller() - ->IsHomeLauncherEnabledInTabletMode(); +bool IsHomeLauncherEnabledInTabletMode() { + return app_list_features::IsHomeLauncherEnabled() && IsTabletModeEnabled(); } } // namespace @@ -549,7 +547,7 @@ // If the app list is active and the home launcher is not shown, hide the // shelf background to prevent overlap. - if (is_app_list_visible_ && !IsHomeLauncherEnabled()) + if (is_app_list_visible_ && !IsHomeLauncherEnabledInTabletMode()) return SHELF_BACKGROUND_APP_LIST; if (state_.visibility_state != SHELF_AUTO_HIDE && @@ -1001,7 +999,7 @@ if (visibility_state != SHELF_AUTO_HIDE) return SHELF_AUTO_HIDE_HIDDEN; - if (shelf_widget_->IsShowingAppList() && !IsHomeLauncherEnabled()) + if (shelf_widget_->IsShowingAppList() && !IsHomeLauncherEnabledInTabletMode()) return SHELF_AUTO_HIDE_SHOWN; if (shelf_widget_->status_area_widget() && @@ -1221,7 +1219,7 @@ } // Disable the shelf dragging if the fullscreen app list is opened. - if (is_app_list_visible_ && !IsHomeLauncherEnabled()) + if (is_app_list_visible_ && !IsHomeLauncherEnabledInTabletMode()) return; gesture_drag_status_ = GESTURE_DRAG_IN_PROGRESS; @@ -1391,7 +1389,7 @@ // In overview mode, app list for tablet mode is hidden temporarily and will // be shown automatically after overview mode ends. So prevent opening it // here. - if (IsHomeLauncherEnabled()) + if (IsHomeLauncherEnabledInTabletMode()) return false; return true;
diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc index cd55ca0f..6a5997ae 100644 --- a/ash/shelf/shelf_widget.cc +++ b/ash/shelf/shelf_widget.cc
@@ -189,7 +189,9 @@ } void ShelfWidget::DelegateView::UpdateBackgroundBlur() { + // Blur only if the background is visible. const bool should_blur_background = + opaque_background_.visible() && shelf_widget_->shelf_layout_manager()->ShouldBlurShelfBackground(); if (should_blur_background == background_is_currently_blurred_) return; @@ -208,6 +210,19 @@ const ShelfBackgroundType background_type = shelf_widget_->GetBackgroundType(); + // If the app list is showing in clamshell mode, we should hide the shelf. + // otherwise, we should show it again. This creates a 'blending' effect + // between the two + if (background_type == SHELF_BACKGROUND_APP_LIST) { + opaque_background_.SetVisible(false); + UpdateBackgroundBlur(); + return; + } + + if (!opaque_background_.visible()) { + opaque_background_.SetVisible(true); + } + // Show rounded corners except in maximized and split modes. if (background_type == SHELF_BACKGROUND_MAXIMIZED || background_type == SHELF_BACKGROUND_SPLIT_VIEW) {
diff --git a/ash/wm/immersive_focus_watcher_classic.cc b/ash/wm/immersive_focus_watcher_classic.cc deleted file mode 100644 index 91ade230..0000000 --- a/ash/wm/immersive_focus_watcher_classic.cc +++ /dev/null
@@ -1,286 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ash/wm/immersive_focus_watcher_classic.h" - -#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h" -#include "ui/aura/window.h" -#include "ui/views/bubble/bubble_dialog_delegate_view.h" -#include "ui/views/view.h" -#include "ui/views/widget/widget.h" -#include "ui/wm/core/transient_window_manager.h" -#include "ui/wm/core/window_util.h" -#include "ui/wm/public/activation_client.h" - -namespace ash { -namespace { - -// Returns the BubbleDialogDelegateView corresponding to |maybe_bubble| if -// |maybe_bubble| is a bubble. -views::BubbleDialogDelegateView* AsBubbleDialogDelegate( - aura::Window* maybe_bubble) { - if (!maybe_bubble) - return nullptr; - views::Widget* widget = views::Widget::GetWidgetForNativeView(maybe_bubble); - if (!widget) - return nullptr; - return widget->widget_delegate()->AsBubbleDialogDelegate(); -} - -views::View* GetAnchorView(aura::Window* maybe_bubble) { - views::BubbleDialogDelegateView* bubble_dialog = - AsBubbleDialogDelegate(maybe_bubble); - return bubble_dialog ? bubble_dialog->GetAnchorView() : nullptr; -} - -// Returns true if |maybe_transient| is a transient child of |toplevel|. -bool IsWindowTransientChildOf(aura::Window* maybe_transient, - aura::Window* toplevel) { - if (!maybe_transient || !toplevel) - return false; - - for (aura::Window* window = maybe_transient; window; - window = ::wm::GetTransientParent(window)) { - if (window == toplevel) - return true; - } - return false; -} - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// - -// Class which keeps the top-of-window views revealed as long as one of the -// bubbles it is observing is visible. The logic to keep the top-of-window -// views revealed based on the visibility of bubbles anchored to -// children of |ImmersiveFullscreenController::top_container_| is separate from -// the logic related to |ImmersiveFullscreenController::focus_revealed_lock_| -// so that bubbles which are not activatable and bubbles which do not close -// upon deactivation also keep the top-of-window views revealed for the -// duration of their visibility. -class ImmersiveFocusWatcherClassic::BubbleObserver - : public aura::WindowObserver { - public: - explicit BubbleObserver(ImmersiveFullscreenController* controller); - ~BubbleObserver() override; - - // Start / stop observing changes to |bubble|'s visibility. - void StartObserving(aura::Window* bubble); - void StopObserving(aura::Window* bubble); - - private: - // Updates |revealed_lock_| based on whether any of |bubbles_| is visible. - void UpdateRevealedLock(); - - // aura::WindowObserver overrides: - void OnWindowVisibilityChanged(aura::Window* window, bool visible) override; - void OnWindowDestroying(aura::Window* window) override; - - ImmersiveFullscreenController* controller_; - - std::set<aura::Window*> bubbles_; - - // Lock which keeps the top-of-window views revealed based on whether any of - // |bubbles_| is visible. - std::unique_ptr<ImmersiveRevealedLock> revealed_lock_; - - DISALLOW_COPY_AND_ASSIGN(BubbleObserver); -}; - -ImmersiveFocusWatcherClassic::BubbleObserver::BubbleObserver( - ImmersiveFullscreenController* controller) - : controller_(controller) {} - -ImmersiveFocusWatcherClassic::BubbleObserver::~BubbleObserver() { - for (aura::Window* bubble : bubbles_) - bubble->RemoveObserver(this); -} - -void ImmersiveFocusWatcherClassic::BubbleObserver::StartObserving( - aura::Window* bubble) { - if (bubbles_.insert(bubble).second) { - bubble->AddObserver(this); - UpdateRevealedLock(); - } -} - -void ImmersiveFocusWatcherClassic::BubbleObserver::StopObserving( - aura::Window* bubble) { - if (bubbles_.erase(bubble)) { - bubble->RemoveObserver(this); - UpdateRevealedLock(); - } -} - -void ImmersiveFocusWatcherClassic::BubbleObserver::UpdateRevealedLock() { - bool has_visible_bubble = false; - for (aura::Window* bubble : bubbles_) { - if (bubble->IsVisible()) { - has_visible_bubble = true; - break; - } - } - - bool was_revealed = controller_->IsRevealed(); - if (has_visible_bubble) { - if (!revealed_lock_.get()) { - // Reveal the top-of-window views without animating because it looks - // weird for the top-of-window views to animate and the bubble not to - // animate along with the top-of-window views. - revealed_lock_.reset(controller_->GetRevealedLock( - ImmersiveFullscreenController::ANIMATE_REVEAL_NO)); - } - } else { - revealed_lock_.reset(); - } - - if (!was_revealed && revealed_lock_.get()) { - // Currently, there is no nice way for bubbles to reposition themselves - // whenever the anchor view moves. Tell the bubbles to reposition themselves - // explicitly instead. The hidden bubbles are also repositioned because - // BubbleDialogDelegateView does not reposition its widget as a result of a - // visibility change. - for (aura::Window* bubble : bubbles_) - AsBubbleDialogDelegate(bubble)->OnAnchorBoundsChanged(); - } -} - -void ImmersiveFocusWatcherClassic::BubbleObserver::OnWindowVisibilityChanged( - aura::Window*, - bool visible) { - UpdateRevealedLock(); -} - -void ImmersiveFocusWatcherClassic::BubbleObserver::OnWindowDestroying( - aura::Window* window) { - StopObserving(window); -} - -ImmersiveFocusWatcherClassic::ImmersiveFocusWatcherClassic( - ImmersiveFullscreenController* controller) - : immersive_fullscreen_controller_(controller) { - GetWidget()->GetFocusManager()->AddFocusChangeListener(this); - GetWidget()->AddObserver(this); - ::wm::TransientWindowManager::GetOrCreate(GetWidgetWindow()) - ->AddObserver(this); - RecreateBubbleObserver(); -} - -ImmersiveFocusWatcherClassic::~ImmersiveFocusWatcherClassic() { - ::wm::TransientWindowManager::GetOrCreate(GetWidgetWindow()) - ->RemoveObserver(this); - GetWidget()->GetFocusManager()->RemoveFocusChangeListener(this); - GetWidget()->RemoveObserver(this); -} - -void ImmersiveFocusWatcherClassic::UpdateFocusRevealedLock() { - views::Widget* widget = GetWidget(); - views::View* top_container = - immersive_fullscreen_controller_->top_container(); - bool hold_lock = false; - if (widget->IsActive()) { - views::View* focused_view = widget->GetFocusManager()->GetFocusedView(); - if (top_container->Contains(focused_view)) - hold_lock = true; - } else { - aura::Window* native_window = widget->GetNativeWindow(); - aura::Window* active_window = - ::wm::GetActivationClient(native_window->GetRootWindow()) - ->GetActiveWindow(); - if (GetAnchorView(active_window)) { - // BubbleObserver will already have locked the top-of-window views if the - // bubble is anchored to a child of |top_container|. Don't acquire - // |lock_| here for the sake of simplicity. - // Note: Instead of checking for the existence of the |anchor_view|, - // the existence of the |anchor_widget| is performed to avoid the case - // where the view is already gone (and the widget is still running). - } else { - // The currently active window is not |native_window| and it is not a - // bubble with an anchor view. The top-of-window views should be revealed - // if: - // 1) The active window is a transient child of |native_window|. - // 2) The top-of-window views are already revealed. This restriction - // prevents a transient window opened by the web contents while the - // top-of-window views are hidden from from initiating a reveal. - // The top-of-window views will stay revealed till |native_window| is - // reactivated. - if (immersive_fullscreen_controller_->IsRevealed() && - IsWindowTransientChildOf(active_window, native_window)) { - hold_lock = true; - } - } - } - - if (hold_lock) { - if (!lock_.get()) { - lock_.reset(immersive_fullscreen_controller_->GetRevealedLock( - ImmersiveFullscreenController::ANIMATE_REVEAL_YES)); - } - } else { - lock_.reset(); - } -} - -void ImmersiveFocusWatcherClassic::ReleaseLock() { - lock_.reset(); -} - -views::Widget* ImmersiveFocusWatcherClassic::GetWidget() { - return immersive_fullscreen_controller_->widget(); -} - -aura::Window* ImmersiveFocusWatcherClassic::GetWidgetWindow() { - return GetWidget()->GetNativeWindow(); -} - -void ImmersiveFocusWatcherClassic::RecreateBubbleObserver() { - bubble_observer_.reset(new BubbleObserver(immersive_fullscreen_controller_)); - const std::vector<aura::Window*> transient_children = - ::wm::GetTransientChildren(GetWidgetWindow()); - for (size_t i = 0; i < transient_children.size(); ++i) { - aura::Window* transient_child = transient_children[i]; - views::View* anchor_view = GetAnchorView(transient_child); - if (anchor_view && - immersive_fullscreen_controller_->top_container()->Contains( - anchor_view)) - bubble_observer_->StartObserving(transient_child); - } -} - -void ImmersiveFocusWatcherClassic::OnWillChangeFocus( - views::View* focused_before, - views::View* focused_now) {} - -void ImmersiveFocusWatcherClassic::OnDidChangeFocus(views::View* focused_before, - views::View* focused_now) { - UpdateFocusRevealedLock(); -} - -void ImmersiveFocusWatcherClassic::OnWidgetActivationChanged( - views::Widget* widget, - bool active) { - UpdateFocusRevealedLock(); -} - -void ImmersiveFocusWatcherClassic::OnTransientChildAdded( - aura::Window* window, - aura::Window* transient) { - views::View* anchor = GetAnchorView(transient); - if (anchor && - immersive_fullscreen_controller_->top_container()->Contains(anchor)) { - // Observe the aura::Window because the BubbleDelegateView may not be - // parented to the widget's root view yet so |bubble_delegate->GetWidget()| - // may still return NULL. - bubble_observer_->StartObserving(transient); - } -} - -void ImmersiveFocusWatcherClassic::OnTransientChildRemoved( - aura::Window* window, - aura::Window* transient) { - bubble_observer_->StopObserving(transient); -} - -} // namespace ash
diff --git a/ash/wm/immersive_focus_watcher_classic.h b/ash/wm/immersive_focus_watcher_classic.h deleted file mode 100644 index 95f7422e..0000000 --- a/ash/wm/immersive_focus_watcher_classic.h +++ /dev/null
@@ -1,77 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ASH_WM_IMMERSIVE_FOCUS_WATCHER_CLASSIC_H_ -#define ASH_WM_IMMERSIVE_FOCUS_WATCHER_CLASSIC_H_ - -#include "ash/ash_export.h" -#include "ash/public/cpp/immersive/immersive_focus_watcher.h" -#include "ui/views/focus/focus_manager.h" -#include "ui/views/widget/widget_observer.h" -#include "ui/wm/core/transient_window_observer.h" - -namespace ash { - -class ImmersiveFullscreenController; -class ImmersiveRevealedLock; - -// ImmersiveFocusWatcher is responsible for grabbing a reveal lock based on -// activation and/or focus. This implementation grabs a lock if views focus is -// in the top view, or a bubble is showing that is anchored to the top view. -class ASH_EXPORT ImmersiveFocusWatcherClassic - : public ImmersiveFocusWatcher, - public views::FocusChangeListener, - public views::WidgetObserver, - public ::wm::TransientWindowObserver { - public: - explicit ImmersiveFocusWatcherClassic( - ImmersiveFullscreenController* controller); - ~ImmersiveFocusWatcherClassic() override; - - // ImmersiveFocusWatcher: - void UpdateFocusRevealedLock() override; - void ReleaseLock() override; - - private: - class BubbleObserver; - - views::Widget* GetWidget(); - aura::Window* GetWidgetWindow(); - - // Recreate |bubble_observer_| and start observing any bubbles anchored to a - // child of |top_container_|. - void RecreateBubbleObserver(); - - // views::FocusChangeObserver overrides: - void OnWillChangeFocus(views::View* focused_before, - views::View* focused_now) override; - void OnDidChangeFocus(views::View* focused_before, - views::View* focused_now) override; - - // views::WidgetObserver overrides: - void OnWidgetActivationChanged(views::Widget* widget, bool active) override; - - // ::wm::TransientWindowObserver overrides: - void OnTransientChildAdded(aura::Window* window, - aura::Window* transient) override; - void OnTransientChildRemoved(aura::Window* window, - aura::Window* transient) override; - - ImmersiveFullscreenController* immersive_fullscreen_controller_; - - // Lock which keeps the top-of-window views revealed based on the focused view - // and the active widget. Acquiring the lock never triggers a reveal because - // a view is not focusable till a reveal has made it visible. - std::unique_ptr<ImmersiveRevealedLock> lock_; - - // Manages bubbles which are anchored to a child of - // |ImmersiveFullscreenController::top_container_|. - std::unique_ptr<BubbleObserver> bubble_observer_; - - DISALLOW_COPY_AND_ASSIGN(ImmersiveFocusWatcherClassic); -}; - -} // namespace ash - -#endif // ASH_WM_IMMERSIVE_FOCUS_WATCHER_CLASSIC_H_
diff --git a/ash/wm/immersive_handler_factory_ash.cc b/ash/wm/immersive_handler_factory_ash.cc index 9c883ac..d88adb8 100644 --- a/ash/wm/immersive_handler_factory_ash.cc +++ b/ash/wm/immersive_handler_factory_ash.cc
@@ -6,7 +6,6 @@ #include <memory> -#include "ash/wm/immersive_focus_watcher_classic.h" #include "ash/wm/immersive_gesture_handler_classic.h" namespace ash { @@ -15,12 +14,6 @@ ImmersiveHandlerFactoryAsh::~ImmersiveHandlerFactoryAsh() = default; -std::unique_ptr<ImmersiveFocusWatcher> -ImmersiveHandlerFactoryAsh::CreateFocusWatcher( - ImmersiveFullscreenController* controller) { - return std::make_unique<ImmersiveFocusWatcherClassic>(controller); -} - std::unique_ptr<ImmersiveGestureHandler> ImmersiveHandlerFactoryAsh::CreateGestureHandler( ImmersiveFullscreenController* controller) {
diff --git a/ash/wm/immersive_handler_factory_ash.h b/ash/wm/immersive_handler_factory_ash.h index 0363a1b..a6eeecc1 100644 --- a/ash/wm/immersive_handler_factory_ash.h +++ b/ash/wm/immersive_handler_factory_ash.h
@@ -17,8 +17,6 @@ ~ImmersiveHandlerFactoryAsh() override; // ImmersiveHandlerFactory: - std::unique_ptr<ImmersiveFocusWatcher> CreateFocusWatcher( - ImmersiveFullscreenController* controller) override; std::unique_ptr<ImmersiveGestureHandler> CreateGestureHandler( ImmersiveFullscreenController* controller) override;
diff --git a/ash/wm/overview/window_selector.cc b/ash/wm/overview/window_selector.cc index 88ceede..2ce2a57 100644 --- a/ash/wm/overview/window_selector.cc +++ b/ash/wm/overview/window_selector.cc
@@ -348,11 +348,11 @@ for (std::unique_ptr<WindowGrid>& window_grid : grid_list_) { window_grid->PrepareForOverview(); - // Check if there is any window that's being dragged in the grid. If so, - // do not do the animation when entering overview. - aura::Window* dragged_window = - GetDraggedWindow(window_grid->root_window(), mru_window_list); - if (dragged_window) { + // Do not animate if there is any window that is being dragged in the + // grid. + if (enter_exit_overview_type_ == EnterExitOverviewType::kWindowDragged) { + if (!mru_window_list.empty()) + DCHECK(GetDraggedWindow(window_grid->root_window(), mru_window_list)); window_grid->PositionWindows(/*animate=*/false); } else if (enter_exit_overview_type_ == EnterExitOverviewType::kWindowsMinimized) { @@ -361,7 +361,8 @@ } else { // EnterExitOverviewType::kSwipeFromShelf is an exit only type, so it // should not appear here. - DCHECK_EQ(enter_exit_overview_type_, EnterExitOverviewType::kNormal); + DCHECK_NE(enter_exit_overview_type_, + EnterExitOverviewType::kSwipeFromShelf); window_grid->CalculateWindowListAnimationStates( /*selected_item=*/nullptr, OverviewTransition::kEnter); window_grid->PositionWindows(/*animate=*/true, /*ignore_item=*/nullptr,
diff --git a/ash/wm/overview/window_selector.h b/ash/wm/overview/window_selector.h index 3b8faac..4156fdc0 100644 --- a/ash/wm/overview/window_selector.h +++ b/ash/wm/overview/window_selector.h
@@ -63,8 +63,6 @@ }; // Enum describing the different ways overview can be entered or exited. - // TODO(minch|xdai): Investigate if we should add kWindowDragged and/or - // kWindowSnapped to this. enum class EnterExitOverviewType { // The default way, window(s) animate from their initial bounds to the grid // bounds. Window(s) that are not visible to the user do not get animated. @@ -80,9 +78,11 @@ // code does not need to handle any animations. This is an exit only type. kSwipeFromShelf, // Overview can be opened by start dragging a window from top or be closed - // if the dragged window restores back to maximized/full-screened. Used as - // an exit type only currently to avoid the update bounds animation of the - // windows in overview grid on overview mode ended. + // if the dragged window restores back to maximized/full-screened. On enter + // this mode is same as kNormal, except when all windows are minimized, the + // launcher does not animate in. On exit this mode is used to avoid the + // update bounds animation of the windows in overview grid on overview mode + // ended. kWindowDragged };
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc index 57d40578..eb1d82b 100644 --- a/ash/wm/overview/window_selector_unittest.cc +++ b/ash/wm/overview/window_selector_unittest.cc
@@ -38,6 +38,7 @@ #include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/splitview/split_view_divider.h" #include "ash/wm/splitview/split_view_drag_indicators.h" +#include "ash/wm/tablet_mode/tablet_mode_app_window_drag_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" @@ -3187,6 +3188,31 @@ EXPECT_TRUE(observer.last_animation_was_slide()); } +// Tests that overview mode is entered with kWindowDragged mode when an app is +// dragged from the top of the screen. +TEST_F(WindowSelectorTest, DraggingFromTopAnimation) { + // Ensure calls to EnableTabletModeWindowManager complete. + base::RunLoop().RunUntilIdle(); + Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true); + base::RunLoop().RunUntilIdle(); + + const gfx::Rect bounds(200, 200); + std::unique_ptr<aura::Window> window(CreateWindow(bounds)); + std::unique_ptr<views::Widget> widget(CreateWindowWidget(bounds)); + + // Drag from the the top of the app to enter overview. + auto drag_controller = std::make_unique<TabletModeAppWindowDragController>(); + ui::GestureEvent event(0, 0, 0, base::TimeTicks(), + ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN)); + ui::Event::DispatcherApi dispatch_helper(&event); + dispatch_helper.set_target(widget->GetNativeWindow()); + drag_controller->DragWindowFromTop(&event); + + ASSERT_TRUE(IsSelecting()); + EXPECT_EQ(WindowSelector::EnterExitOverviewType::kWindowDragged, + window_selector()->enter_exit_overview_type()); +} + class SplitViewWindowSelectorTest : public WindowSelectorTest { public: SplitViewWindowSelectorTest() = default;
diff --git a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc index 8e82f3f..8e2f68e 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc
@@ -102,8 +102,10 @@ // might open overview in the dragged window side of the screen. split_view_controller_->OnWindowDragStarted(dragged_window_); - if (ShouldOpenOverviewWhenDragStarts() && !controller->IsSelecting()) - controller->ToggleOverview(); + if (ShouldOpenOverviewWhenDragStarts() && !controller->IsSelecting()) { + controller->ToggleOverview( + WindowSelector::EnterExitOverviewType::kWindowDragged); + } if (controller->IsSelecting()) { // Only do animation if overview was open before the drag started. If the
diff --git a/ash/wm/workspace/multi_window_resize_controller.cc b/ash/wm/workspace/multi_window_resize_controller.cc index b4db01e..9212e6e 100644 --- a/ash/wm/workspace/multi_window_resize_controller.cc +++ b/ash/wm/workspace/multi_window_resize_controller.cc
@@ -201,8 +201,7 @@ MultiWindowResizeController::MultiWindowResizeController() = default; MultiWindowResizeController::~MultiWindowResizeController() { - window_resizer_.reset(); - Hide(); + ResetResizer(); } void MultiWindowResizeController::Show(aura::Window* window, @@ -235,39 +234,19 @@ &MultiWindowResizeController::ShowIfValidMouseLocation); } -void MultiWindowResizeController::Hide() { - if (window_resizer_) - return; // Ignore hides while actively resizing. - - if (windows_.window1) { - StopObserving(windows_.window1); - windows_.window1 = nullptr; - } - if (windows_.window2) { - StopObserving(windows_.window2); - windows_.window2 = nullptr; - } - - show_timer_.Stop(); - - if (!resize_widget_) - return; - - for (size_t i = 0; i < windows_.other_windows.size(); ++i) - StopObserving(windows_.other_windows[i]); - mouse_watcher_.reset(); - resize_widget_.reset(); - windows_ = ResizeWindows(); -} - void MultiWindowResizeController::MouseMovedOutOfHost() { Hide(); } +void MultiWindowResizeController::OnWindowVisibilityChanged( + aura::Window* window, + bool visible) { + if (!visible) + ResetResizer(); +} + void MultiWindowResizeController::OnWindowDestroying(aura::Window* window) { - // Have to explicitly reset the WindowResizer, otherwise Hide() does nothing. - window_resizer_.reset(); - Hide(); + ResetResizer(); } void MultiWindowResizeController::OnPostWindowStateTypeChange( @@ -275,8 +254,7 @@ mojom::WindowStateType old_type) { if (window_state->IsMaximized() || window_state->IsFullscreen() || window_state->IsMinimized()) { - window_resizer_.reset(); - Hide(); + ResetResizer(); } } @@ -476,6 +454,37 @@ return resize_widget_.get() || show_timer_.IsRunning(); } +void MultiWindowResizeController::Hide() { + if (window_resizer_) + return; // Ignore hides while actively resizing. + + if (windows_.window1) { + StopObserving(windows_.window1); + windows_.window1 = nullptr; + } + if (windows_.window2) { + StopObserving(windows_.window2); + windows_.window2 = nullptr; + } + + show_timer_.Stop(); + + if (!resize_widget_) + return; + + for (auto* window : windows_.other_windows) + StopObserving(window); + mouse_watcher_.reset(); + resize_widget_.reset(); + windows_ = ResizeWindows(); +} + +void MultiWindowResizeController::ResetResizer() { + // Have to explicitly reset the WindowResizer, otherwise Hide() does nothing. + window_resizer_.reset(); + Hide(); +} + void MultiWindowResizeController::StartResize( const gfx::Point& location_in_screen) { DCHECK(!window_resizer_.get()); @@ -543,8 +552,7 @@ return; // Happens if window was destroyed and we nuked the WindowResizer. window_resizer_->RevertDrag(); wm::GetWindowState(window_resizer_->GetTarget())->DeleteDragDetails(); - window_resizer_.reset(); - Hide(); + ResetResizer(); } gfx::Rect MultiWindowResizeController::CalculateResizeWidgetBounds(
diff --git a/ash/wm/workspace/multi_window_resize_controller.h b/ash/wm/workspace/multi_window_resize_controller.h index 43c47ea..5f46ddf 100644 --- a/ash/wm/workspace/multi_window_resize_controller.h +++ b/ash/wm/workspace/multi_window_resize_controller.h
@@ -45,13 +45,11 @@ // is over, |component| the edge and |point| the location of the mouse. void Show(aura::Window* window, int component, const gfx::Point& point); - // Hides the resize widget. - void Hide(); - // MouseWatcherListener: void MouseMovedOutOfHost() override; // WindowObserver: + void OnWindowVisibilityChanged(aura::Window* window, bool visible) override; void OnWindowDestroying(aura::Window* window) override; // wm::WindowStateObserver: @@ -132,6 +130,12 @@ // Returns true if the widget is showing. bool IsShowing() const; + // Hides the resize widget. + void Hide(); + + // Resets the window resizer and hides the resize widget. + void ResetResizer(); + // Initiates a resize. void StartResize(const gfx::Point& location_in_screen);
diff --git a/ash/wm/workspace/multi_window_resize_controller_unittest.cc b/ash/wm/workspace/multi_window_resize_controller_unittest.cc index df238d1..5d14ea5 100644 --- a/ash/wm/workspace/multi_window_resize_controller_unittest.cc +++ b/ash/wm/workspace/multi_window_resize_controller_unittest.cc
@@ -406,6 +406,29 @@ EXPECT_FALSE(IsShowing()); } +// Tests that if one of the resized windows visibility changes to hidden, the +// resize widget should be dismissed. +TEST_F(MultiWindowResizeControllerTest, HideWindowTest) { + aura::test::TestWindowDelegate delegate1; + std::unique_ptr<aura::Window> w1(CreateTestWindowInShellWithDelegate( + &delegate1, -1, gfx::Rect(0, 0, 100, 100))); + delegate1.set_window_component(HTRIGHT); + aura::test::TestWindowDelegate delegate2; + std::unique_ptr<aura::Window> w2(CreateTestWindowInShellWithDelegate( + &delegate2, -2, gfx::Rect(100, 0, 100, 100))); + delegate2.set_window_component(HTLEFT); + + ui::test::EventGenerator* generator = GetEventGenerator(); + gfx::Point w1_center_in_screen = w1->GetBoundsInScreen().CenterPoint(); + generator->MoveMouseTo(w1_center_in_screen); + ShowNow(); + EXPECT_TRUE(IsShowing()); + + // Hide one window should dimiss the resizer. + w1->Hide(); + EXPECT_FALSE(IsShowing()); +} + namespace { class TestWindowStateDelegate : public wm::WindowStateDelegate {
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc index a9bf314..cbb00b6a 100644 --- a/ash/wm/workspace/workspace_window_resizer.cc +++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -559,11 +559,7 @@ if (event->type() == ui::ET_SCROLL_FLING_START) { CompleteDrag(); - // TODO(pkotwicz): Fix tests which inadvertently start flings and check - // window_resizer_->IsMove() instead of the hittest component at |event|'s - // location. - if (wm::GetNonClientComponent(GetTarget(), event->location()) != - HTCAPTION || + if (details().bounds_change != WindowResizer::kBoundsChange_Repositions || !wm::GetWindowState(GetTarget())->IsNormalOrSnapped()) { return; }
diff --git a/base/allocator/partition_allocator/address_space_randomization.cc b/base/allocator/partition_allocator/address_space_randomization.cc index 3e3bf13..6a47e6c 100644 --- a/base/allocator/partition_allocator/address_space_randomization.cc +++ b/base/allocator/partition_allocator/address_space_randomization.cc
@@ -6,8 +6,8 @@ #include "base/allocator/partition_allocator/page_allocator.h" #include "base/allocator/partition_allocator/spin_lock.h" -#include "base/lazy_instance.h" #include "base/logging.h" +#include "base/no_destructor.h" #include "base/rand_util.h" #include "build/build_config.h" @@ -32,8 +32,10 @@ uint32_t d; }; -static LazyInstance<RandomContext>::Leaky s_RandomContext = - LAZY_INSTANCE_INITIALIZER; +RandomContext* GetRandomContext() { + static NoDestructor<RandomContext> s_RandomContext; + return s_RandomContext.get(); +} #define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) @@ -68,7 +70,7 @@ } // namespace void SetRandomPageBaseSeed(int64_t seed) { - RandomContext* x = s_RandomContext.Pointer(); + RandomContext* x = GetRandomContext(); subtle::SpinLock::Guard guard(x->lock); // Set RNG to initial state. x->initialized = true; @@ -77,12 +79,11 @@ } void* GetRandomPageBase() { - uintptr_t random = - static_cast<uintptr_t>(RandomValue(s_RandomContext.Pointer())); + uintptr_t random = static_cast<uintptr_t>(RandomValue(GetRandomContext())); #if defined(ARCH_CPU_64_BITS) random <<= 32ULL; - random |= static_cast<uintptr_t>(RandomValue(s_RandomContext.Pointer())); + random |= static_cast<uintptr_t>(RandomValue(GetRandomContext())); // The kASLRMask and kASLROffset constants will be suitable for the // OS and build configuration.
diff --git a/base/allocator/partition_allocator/oom_callback.cc b/base/allocator/partition_allocator/oom_callback.cc index 980c45f..2e22e109 100644 --- a/base/allocator/partition_allocator/oom_callback.cc +++ b/base/allocator/partition_allocator/oom_callback.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/allocator/partition_allocator/oom_callback.h" + #include "base/logging.h" namespace base {
diff --git a/base/allocator/partition_allocator/page_allocator.cc b/base/allocator/partition_allocator/page_allocator.cc index 4a28550a..f3fd1e6 100644 --- a/base/allocator/partition_allocator/page_allocator.cc +++ b/base/allocator/partition_allocator/page_allocator.cc
@@ -11,8 +11,8 @@ #include "base/allocator/partition_allocator/address_space_randomization.h" #include "base/allocator/partition_allocator/page_allocator_internal.h" #include "base/allocator/partition_allocator/spin_lock.h" -#include "base/lazy_instance.h" #include "base/logging.h" +#include "base/no_destructor.h" #include "base/numerics/checked_math.h" #include "build/build_config.h" @@ -33,7 +33,10 @@ namespace { // We may reserve/release address space on different threads. -LazyInstance<subtle::SpinLock>::Leaky s_reserveLock = LAZY_INSTANCE_INITIALIZER; +subtle::SpinLock& GetReserveLock() { + static NoDestructor<subtle::SpinLock> s_reserveLock; + return *s_reserveLock; +} // We only support a single block of reserved address space. void* s_reservation_address = nullptr; @@ -223,7 +226,7 @@ bool ReserveAddressSpace(size_t size) { // To avoid deadlock, call only SystemAllocPages. - subtle::SpinLock::Guard guard(s_reserveLock.Get()); + subtle::SpinLock::Guard guard(GetReserveLock()); if (s_reservation_address == nullptr) { void* mem = SystemAllocPages(nullptr, size, PageInaccessible, PageTag::kChromium, false); @@ -241,7 +244,7 @@ void ReleaseReservation() { // To avoid deadlock, call only FreePages. - subtle::SpinLock::Guard guard(s_reserveLock.Get()); + subtle::SpinLock::Guard guard(GetReserveLock()); if (s_reservation_address != nullptr) { FreePages(s_reservation_address, s_reservation_size); s_reservation_address = nullptr;
diff --git a/base/allocator/partition_allocator/page_allocator_internals_win.h b/base/allocator/partition_allocator/page_allocator_internals_win.h index d5dcf375..22940d6 100644 --- a/base/allocator/partition_allocator/page_allocator_internals_win.h +++ b/base/allocator/partition_allocator/page_allocator_internals_win.h
@@ -69,12 +69,10 @@ void* address, size_t length, PageAccessibilityConfiguration accessibility) { - if (accessibility == PageInaccessible) { + if (accessibility == PageInaccessible) return VirtualFree(address, length, MEM_DECOMMIT) != 0; - } else { - return nullptr != VirtualAlloc(address, length, MEM_COMMIT, - GetAccessFlags(accessibility)); - } + return nullptr != VirtualAlloc(address, length, MEM_COMMIT, + GetAccessFlags(accessibility)); } void FreePagesInternal(void* address, size_t length) {
diff --git a/base/allocator/partition_allocator/partition_alloc.cc b/base/allocator/partition_allocator/partition_alloc.cc index 0326d0b..6ef8bfe 100644 --- a/base/allocator/partition_allocator/partition_alloc.cc +++ b/base/allocator/partition_allocator/partition_alloc.cc
@@ -13,8 +13,8 @@ #include "base/allocator/partition_allocator/partition_oom.h" #include "base/allocator/partition_allocator/partition_page.h" #include "base/allocator/partition_allocator/spin_lock.h" -#include "base/lazy_instance.h" #include "base/logging.h" +#include "base/no_destructor.h" namespace base { @@ -57,8 +57,10 @@ PartitionAllocatorGeneric::PartitionAllocatorGeneric() = default; PartitionAllocatorGeneric::~PartitionAllocatorGeneric() = default; -static LazyInstance<subtle::SpinLock>::Leaky g_initialized_lock = - LAZY_INSTANCE_INITIALIZER; +subtle::SpinLock& GetLock() { + static NoDestructor<subtle::SpinLock> s_initialized_lock; + return *s_initialized_lock; +} static bool g_initialized = false; void (*internal::PartitionRootBase::gOomHandlingFunction)() = nullptr; @@ -69,7 +71,7 @@ static void PartitionAllocBaseInit(internal::PartitionRootBase* root) { DCHECK(!root->initialized); { - subtle::SpinLock::Guard guard(g_initialized_lock.Get()); + subtle::SpinLock::Guard guard(GetLock()); if (!g_initialized) { g_initialized = true; // We mark the sentinel bucket/page as free to make sure it is skipped by
diff --git a/base/allocator/partition_allocator/spin_lock.cc b/base/allocator/partition_allocator/spin_lock.cc index 752889bd..5cc04168 100644 --- a/base/allocator/partition_allocator/spin_lock.cc +++ b/base/allocator/partition_allocator/spin_lock.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/allocator/partition_allocator/spin_lock.h" + #include "base/threading/platform_thread.h" #include "build/build_config.h"
diff --git a/base/logging.cc b/base/logging.cc index 9e69d5e..826a4bd 100644 --- a/base/logging.cc +++ b/base/logging.cc
@@ -95,6 +95,7 @@ #include "base/lazy_instance.h" #include "base/posix/eintr_wrapper.h" #include "base/strings/string_piece.h" +#include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" @@ -770,8 +771,17 @@ priority = ANDROID_LOG_FATAL; break; } +#if DCHECK_IS_ON() + // Split the output by new lines to prevent the Android system from + // truncating the log. + for (const auto& line : base::SplitString( + str_newline, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL)) + __android_log_write(priority, "chromium", line.c_str()); +#else + // The Android system may truncate the string if it's too long. __android_log_write(priority, "chromium", str_newline.c_str()); #endif +#endif // OS_ANDROID ignore_result(fwrite(str_newline.data(), str_newline.size(), 1, stderr)); fflush(stderr); } else if (severity_ >= kAlwaysPrintErrorLevel) {
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc index 0db05e921..a35895c 100644 --- a/base/profiler/stack_sampling_profiler.cc +++ b/base/profiler/stack_sampling_profiler.cc
@@ -19,6 +19,7 @@ #include "base/memory/singleton.h" #include "base/profiler/native_stack_sampler.h" #include "base/synchronization/lock.h" +#include "base/thread_annotations.h" #include "base/threading/thread.h" #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" @@ -201,15 +202,19 @@ // Thread API (Start, Stop, StopSoon, & DetachFromSequence) so that // multiple threads may make those calls. Lock thread_execution_state_lock_; // Protects all thread_execution_state_* - ThreadExecutionState thread_execution_state_ = NOT_STARTED; - scoped_refptr<SingleThreadTaskRunner> thread_execution_state_task_runner_; - bool thread_execution_state_disable_idle_shutdown_for_testing_ = false; + ThreadExecutionState thread_execution_state_ + GUARDED_BY(thread_execution_state_lock_) = NOT_STARTED; + scoped_refptr<SingleThreadTaskRunner> thread_execution_state_task_runner_ + GUARDED_BY(thread_execution_state_lock_); + bool thread_execution_state_disable_idle_shutdown_for_testing_ + GUARDED_BY(thread_execution_state_lock_) = false; // A counter that notes adds of new collection requests. It is incremented // when changes occur so that delayed shutdown tasks are able to detect if // something new has happened while it was waiting. Like all "execution_state" // vars, this must be accessed while holding |thread_execution_state_lock_|. - int thread_execution_state_add_events_ = 0; + int thread_execution_state_add_events_ + GUARDED_BY(thread_execution_state_lock_) = 0; DISALLOW_COPY_AND_ASSIGN(SamplingThread); };
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index c2a62de3..051a355 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -252,6 +252,7 @@ // Handled by the launcher process. switches.erase(kGTestRepeatFlag); + switches.erase(kIsolatedScriptTestRepeatFlag); switches.erase(kGTestShuffleFlag); switches.erase(kGTestRandomSeedFlag); @@ -568,6 +569,20 @@ output_file_contents)); } +std::vector<std::string> ExtractTestsFromFilter(const std::string& filter, + bool double_colon_supported) { + std::vector<std::string> tests; + if (double_colon_supported) { + tests = + SplitString(filter, "::", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + } + if (tests.size() <= 1) { + tests = + SplitString(filter, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + } + return tests; +} + } // namespace const char kGTestBreakOnFailure[] = "gtest_break_on_failure"; @@ -580,6 +595,10 @@ const char kGTestOutputFlag[] = "gtest_output"; const char kGTestShuffleFlag[] = "gtest_shuffle"; const char kGTestRandomSeedFlag[] = "gtest_random_seed"; +const char kIsolatedScriptRunDisabledTestsFlag[] = + "isolated-script-test-also-run-disabled-tests"; +const char kIsolatedScriptTestFilterFlag[] = "isolated-script-test-filter"; +const char kIsolatedScriptTestRepeatFlag[] = "isolated-script-test-repeat"; TestLauncherDelegate::~TestLauncherDelegate() = default; @@ -946,6 +965,13 @@ LOG(ERROR) << "Invalid value for " << kGTestRepeatFlag; return false; } + if (command_line->HasSwitch(kIsolatedScriptTestRepeatFlag) && + !StringToInt( + command_line->GetSwitchValueASCII(kIsolatedScriptTestRepeatFlag), + &cycles_)) { + LOG(ERROR) << "Invalid value for " << kIsolatedScriptTestRepeatFlag; + return false; + } if (command_line->HasSwitch(switches::kTestLauncherRetryLimit)) { int retry_limit = -1; @@ -957,7 +983,22 @@ } retry_limit_ = retry_limit; - } else if (!command_line->HasSwitch(kGTestFilterFlag) || BotModeEnabled()) { + } else if (command_line->HasSwitch( + switches::kIsolatedScriptTestLauncherRetryLimit)) { + int retry_limit = -1; + if (!StringToInt(command_line->GetSwitchValueASCII( + switches::kIsolatedScriptTestLauncherRetryLimit), + &retry_limit) || + retry_limit < 0) { + LOG(ERROR) << "Invalid value for " + << switches::kIsolatedScriptTestLauncherRetryLimit; + return false; + } + + retry_limit_ = retry_limit; + } else if (BotModeEnabled() || + !(command_line->HasSwitch(kGTestFilterFlag) || + command_line->HasSwitch(kIsolatedScriptTestFilterFlag))) { // Retry failures 3 times by default if we are running all of the tests or // in bot mode. retry_limit_ = 3; @@ -1022,21 +1063,22 @@ // Split --gtest_filter at '-', if there is one, to separate into // positive filter and negative filter portions. - std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag); + bool double_colon_supported = !command_line->HasSwitch(kGTestFilterFlag); + std::string filter = command_line->GetSwitchValueASCII( + double_colon_supported ? kIsolatedScriptTestFilterFlag + : kGTestFilterFlag); size_t dash_pos = filter.find('-'); if (dash_pos == std::string::npos) { positive_gtest_filter = - SplitString(filter, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + ExtractTestsFromFilter(filter, double_colon_supported); } else { // Everything up to the dash. - positive_gtest_filter = - SplitString(filter.substr(0, dash_pos), ":", base::TRIM_WHITESPACE, - base::SPLIT_WANT_ALL); + positive_gtest_filter = ExtractTestsFromFilter(filter.substr(0, dash_pos), + double_colon_supported); // Everything after the dash. - for (std::string pattern : - SplitString(filter.substr(dash_pos + 1), ":", base::TRIM_WHITESPACE, - base::SPLIT_WANT_ALL)) { + for (std::string pattern : ExtractTestsFromFilter( + filter.substr(dash_pos + 1), double_colon_supported)) { negative_test_filter_.push_back(pattern); } } @@ -1168,7 +1210,8 @@ results_tracker_.AddDisabledTest(test_name); // Skip disabled tests unless explicitly requested. - if (!command_line->HasSwitch(kGTestRunDisabledTestsFlag)) + if (!command_line->HasSwitch(kGTestRunDisabledTestsFlag) && + !command_line->HasSwitch(kIsolatedScriptRunDisabledTestsFlag)) continue; } @@ -1366,7 +1409,9 @@ } return jobs; } - if (command_line->HasSwitch(kGTestFilterFlag) && !BotModeEnabled()) { + if (!BotModeEnabled() && + (command_line->HasSwitch(kGTestFilterFlag) || + command_line->HasSwitch(kIsolatedScriptTestFilterFlag))) { // Do not run jobs in parallel by default if we are running a subset of // the tests and if bot mode is off. return 1U;
diff --git a/base/test/launcher/test_launcher.h b/base/test/launcher/test_launcher.h index 9ac45ba..ef8cbeb 100644 --- a/base/test/launcher/test_launcher.h +++ b/base/test/launcher/test_launcher.h
@@ -40,6 +40,9 @@ extern const char kGTestOutputFlag[]; extern const char kGTestShuffleFlag[]; extern const char kGTestRandomSeedFlag[]; +extern const char kIsolatedScriptRunDisabledTestsFlag[]; +extern const char kIsolatedScriptTestFilterFlag[]; +extern const char kIsolatedScriptTestRepeatFlag[]; // Interface for use with LaunchTests that abstracts away exact details // which tests and how are run.
diff --git a/base/test/scoped_task_environment.cc b/base/test/scoped_task_environment.cc index 50a46325..32265ee 100644 --- a/base/test/scoped_task_environment.cc +++ b/base/test/scoped_task_environment.cc
@@ -5,6 +5,7 @@ #include "base/test/scoped_task_environment.h" #include "base/bind_helpers.h" +#include "base/lazy_instance.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" @@ -16,6 +17,7 @@ #include "base/task/task_scheduler/task_scheduler_impl.h" #include "base/test/test_mock_time_task_runner.h" #include "base/threading/sequence_local_storage_map.h" +#include "base/threading/thread_local.h" #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" @@ -29,6 +31,9 @@ namespace { +LazyInstance<ThreadLocalPointer<ScopedTaskEnvironment::LifetimeObserver>>::Leaky + environment_lifetime_observer; + std::unique_ptr<MessageLoop> CreateMessageLoopForMainThreadType( ScopedTaskEnvironment::MainThreadType main_thread_type) { switch (main_thread_type) { @@ -146,6 +151,12 @@ if (execution_control_mode_ == ExecutionMode::QUEUED) CHECK(task_tracker_->DisallowRunTasks()); + + LifetimeObserver* observer = environment_lifetime_observer.Get().Get(); + if (observer) { + observer->OnScopedTaskEnvironmentCreated(main_thread_type, + GetMainThreadTaskRunner()); + } } ScopedTaskEnvironment::~ScopedTaskEnvironment() { @@ -165,6 +176,16 @@ // on their main thread. ScopedAllowBaseSyncPrimitivesForTesting allow_waits_to_destroy_task_tracker; TaskScheduler::SetInstance(nullptr); + + LifetimeObserver* observer = environment_lifetime_observer.Get().Get(); + if (observer) + observer->OnScopedTaskEnvironmentDestroyed(); +} + +void ScopedTaskEnvironment::SetLifetimeObserver( + ScopedTaskEnvironment::LifetimeObserver* lifetime_observer) { + DCHECK_NE(!!environment_lifetime_observer.Get().Get(), !!lifetime_observer); + environment_lifetime_observer.Get().Set(lifetime_observer); } scoped_refptr<base::SingleThreadTaskRunner>
diff --git a/base/test/scoped_task_environment.h b/base/test/scoped_task_environment.h index 2e46073..9c4ce59 100644 --- a/base/test/scoped_task_environment.h +++ b/base/test/scoped_task_environment.h
@@ -98,6 +98,22 @@ // TaskScheduler and the (Thread|Sequenced)TaskRunnerHandle. ~ScopedTaskEnvironment(); + class LifetimeObserver { + public: + virtual ~LifetimeObserver() = default; + + virtual void OnScopedTaskEnvironmentCreated( + MainThreadType main_thread_type, + scoped_refptr<SingleThreadTaskRunner> task_runner) = 0; + virtual void OnScopedTaskEnvironmentDestroyed() = 0; + }; + + // Set a thread-local observer which will get notifications when + // a new ScopedTaskEnvironment is created or destroyed. + // This is needed due to peculiarities of Blink initialisation + // (Blink is per-test suite and ScopedTaskEnvironment is per-test). + static void SetLifetimeObserver(LifetimeObserver* lifetime_observer); + // Returns a TaskRunner that schedules tasks on the main thread. scoped_refptr<base::SingleThreadTaskRunner> GetMainThreadTaskRunner();
diff --git a/base/test/scoped_task_environment_unittest.cc b/base/test/scoped_task_environment_unittest.cc index f32e93b..d8e76c5 100644 --- a/base/test/scoped_task_environment_unittest.cc +++ b/base/test/scoped_task_environment_unittest.cc
@@ -18,6 +18,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/tick_clock.h" #include "build/build_config.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #if defined(OS_POSIX) @@ -303,6 +304,36 @@ EXPECT_EQ(kLongTaskDelay * 2, tick_clock->NowTicks() - tick_clock_ref); } +namespace { + +class MockLifetimeObserver : public ScopedTaskEnvironment::LifetimeObserver { + public: + MockLifetimeObserver() = default; + ~MockLifetimeObserver() override = default; + + MOCK_METHOD2(OnScopedTaskEnvironmentCreated, + void(ScopedTaskEnvironment::MainThreadType, + scoped_refptr<SingleThreadTaskRunner>)); + MOCK_METHOD0(OnScopedTaskEnvironmentDestroyed, void()); +}; + +} // namespace + +TEST_F(ScopedTaskEnvironmentTest, LifetimeObserver) { + testing::StrictMock<MockLifetimeObserver> lifetime_observer; + ScopedTaskEnvironment::SetLifetimeObserver(&lifetime_observer); + + EXPECT_CALL(lifetime_observer, + OnScopedTaskEnvironmentCreated(testing::_, testing::_)); + std::unique_ptr<ScopedTaskEnvironment> task_environment( + std::make_unique<ScopedTaskEnvironment>()); + testing::Mock::VerifyAndClearExpectations(&lifetime_observer); + + EXPECT_CALL(lifetime_observer, OnScopedTaskEnvironmentDestroyed()); + task_environment.reset(); + testing::Mock::VerifyAndClearExpectations(&lifetime_observer); +} + INSTANTIATE_TEST_CASE_P( MainThreadDefault, ScopedTaskEnvironmentTest,
diff --git a/base/test/test_switches.cc b/base/test/test_switches.cc index 5e4f9cf..ecdf493 100644 --- a/base/test/test_switches.cc +++ b/base/test/test_switches.cc
@@ -40,8 +40,12 @@ // Path to test results file in our custom test launcher format. const char switches::kTestLauncherOutput[] = "test-launcher-output"; +// These two flags has the same effect, but don't use them at the same time. +// And isolated-script-test-launcher-retry-limit is preferred in the future. // Maximum number of times to retry a test after failure. const char switches::kTestLauncherRetryLimit[] = "test-launcher-retry-limit"; +const char switches::kIsolatedScriptTestLauncherRetryLimit[] = + "isolated-script-test-launcher-retry-limit"; // Path to test results file with all the info from the test launcher. const char switches::kTestLauncherSummaryOutput[] =
diff --git a/base/test/test_switches.h b/base/test/test_switches.h index 6baba308..d3857ba 100644 --- a/base/test/test_switches.h +++ b/base/test/test_switches.h
@@ -19,6 +19,7 @@ extern const char kTestLauncherListTests[]; extern const char kTestLauncherOutput[]; extern const char kTestLauncherRetryLimit[]; +extern const char kIsolatedScriptTestLauncherRetryLimit[]; extern const char kTestLauncherSummaryOutput[]; extern const char kTestLauncherPrintTestStdio[]; extern const char kTestLauncherPrintWritablePath[];
diff --git a/build/build_config.h b/build/build_config.h index c7b02664..4d1ba77f 100644 --- a/build/build_config.h +++ b/build/build_config.h
@@ -140,7 +140,7 @@ #define ARCH_CPU_ARMEL 1 #define ARCH_CPU_32_BITS 1 #define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__aarch64__) +#elif defined(__aarch64__) || defined(_M_ARM64) #define ARCH_CPU_ARM_FAMILY 1 #define ARCH_CPU_ARM64 1 #define ARCH_CPU_64_BITS 1
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 387fdb2..f33cba1 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn
@@ -203,6 +203,7 @@ } else if (host_os == "win") { # On Windows always use the target CPU for host builds for x86/x64. On the # configurations we support this will always work and it saves build steps. + # Windows ARM64 targets require an x64 host for cross build. if (target_cpu == "x86" || target_cpu == "x64") { if (is_clang) { host_toolchain = "//build/toolchain/win:win_clang_$target_cpu"
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 148e913..88a9c1b3 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1772,7 +1772,7 @@ # Code that currently generates warnings for this can include this # config to disable them. config("no_shorten_64_warnings") { - if (current_cpu == "x64") { + if (current_cpu == "x64" || current_cpu == "arm64") { if (is_clang) { cflags = [ "-Wno-shorten-64-to-32" ] } else {
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn index debc64c..50427222 100644 --- a/build/config/sanitizers/BUILD.gn +++ b/build/config/sanitizers/BUILD.gn
@@ -390,6 +390,12 @@ } } +config("cfi_icall_disable") { + if (is_clang && is_cfi && use_cfi_icall) { + cflags = [ "-fno-sanitize=cfi-icall" ] + } +} + config("coverage_flags") { cflags = [] if (use_sanitizer_coverage) {
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn index e605040..3c8f327 100644 --- a/build/config/win/BUILD.gn +++ b/build/config/win/BUILD.gn
@@ -479,6 +479,9 @@ # The number after the comma is the minimum required OS version. # 5.02 = Windows Server 2003. subsystem_version_suffix = ",5.02" +} else if (current_cpu == "arm64") { + # Windows ARM64 requires Windows 10. + subsystem_version_suffix = ",10.0" } else { # 5.01 = Windows XP. subsystem_version_suffix = ",5.01"
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn index 3c6c9d0..5fcda742 100644 --- a/build/toolchain/win/BUILD.gn +++ b/build/toolchain/win/BUILD.gn
@@ -49,6 +49,12 @@ ]) } +if (host_os == "win") { + clang_cl = "clang-cl.exe" +} else { + clang_cl = "clang-cl" +} + # Parameters: # environment: File name of environment file. # @@ -203,10 +209,18 @@ tool("asm") { if (toolchain_args.current_cpu == "x64") { ml = "ml64.exe" + } else if (toolchain_args.current_cpu == "arm64") { + prefix = rebase_path("$clang_base_path/bin", root_build_dir) + ml = "${goma_prefix}${prefix}/${clang_cl} --target=arm64-windows" } else { ml = "ml.exe" } - command = "$python_path $tool_wrapper_path asm-wrapper $env $ml {{defines}} {{include_dirs}} {{asmflags}} /c /Fo{{output}} {{source}}" + command = "$python_path $tool_wrapper_path asm-wrapper $env $ml {{defines}} {{include_dirs}} {{asmflags}} " + if (toolchain_args.current_cpu == "arm64") { + command += "-c -o{{output}} {{source}}" + } else { + command += "/c /Fo{{output}} {{source}}" + } description = "ASM {{output}}" outputs = [ "$object_subdir/{{source_name_part}}.obj", @@ -332,12 +346,6 @@ } } -if (host_os == "win") { - clang_cl = "clang-cl.exe" -} else { - clang_cl = "clang-cl" -} - if (target_cpu == "x86" || target_cpu == "x64") { win_build_host_cpu = target_cpu } else { @@ -392,25 +400,28 @@ } } -# 64-bit toolchains. -x64_toolchain_data = exec_script("setup_toolchain.py", - [ - visual_studio_path, - windows_sdk_path, - visual_studio_runtime_dirs, - "win", - "x64", - "environment.x64", - ], - "scope") +# 64-bit toolchains, including x64 and arm64. +template("win_64bit_toolchains") { + assert(defined(invoker.toolchain_arch)) + toolchain_arch = invoker.toolchain_arch -template("win_x64_toolchains") { + win_64bit_toolchain_data = exec_script("setup_toolchain.py", + [ + visual_studio_path, + windows_sdk_path, + visual_studio_runtime_dirs, + "win", + toolchain_arch, + "environment." + toolchain_arch, + ], + "scope") + msvc_toolchain(target_name) { - environment = "environment.x64" - cl = "${goma_prefix}\"${x64_toolchain_data.vc_bin_dir}/cl.exe\"" + environment = "environment." + toolchain_arch + cl = "${goma_prefix}\"${win_64bit_toolchain_data.vc_bin_dir}/cl.exe\"" if (host_os != "win") { # For win cross build - sys_lib_flags = "${x64_toolchain_data.libpath_flags}" + sys_lib_flags = "${win_64bit_toolchain_data.libpath_flags}" } toolchain_args = { @@ -419,18 +430,18 @@ } is_clang = false current_os = "win" - current_cpu = "x64" + current_cpu = toolchain_arch } } msvc_toolchain("win_clang_" + target_name) { - environment = "environment.x64" + environment = "environment." + toolchain_arch prefix = rebase_path("$clang_base_path/bin", root_build_dir) cl = "${goma_prefix}$prefix/${clang_cl}" - sys_include_flags = "${x64_toolchain_data.include_flags_imsvc}" + sys_include_flags = "${win_64bit_toolchain_data.include_flags_imsvc}" if (host_os != "win") { # For win cross build - sys_lib_flags = "${x64_toolchain_data.libpath_flags}" + sys_lib_flags = "${win_64bit_toolchain_data.libpath_flags}" } toolchain_args = { @@ -439,23 +450,34 @@ } is_clang = true current_os = "win" - current_cpu = "x64" + current_cpu = toolchain_arch } } } -win_x64_toolchains("x64") { +win_64bit_toolchains("x64") { + toolchain_arch = "x64" toolchain_args = { # Use the defaults. } } +if (target_cpu == "arm64") { + win_64bit_toolchains("arm64") { + toolchain_arch = "arm64" + toolchain_args = { + # Use the defaults. + } + } +} + # The nacl_win64 toolchain is nearly identical to the plain x64 toolchain. # It's used solely for building nacl64.exe (//components/nacl/broker:nacl64). # The only reason it's a separate toolchain is so that it can force # is_component_build to false in the toolchain_args() block, because # building nacl64.exe in component style does not work. -win_x64_toolchains("nacl_win64") { +win_64bit_toolchains("nacl_win64") { + toolchain_arch = "x64" toolchain_args = { is_component_build = false }
diff --git a/build/toolchain/win/midl.gni b/build/toolchain/win/midl.gni index 9ff29c67..b46f4cd 100644 --- a/build/toolchain/win/midl.gni +++ b/build/toolchain/win/midl.gni
@@ -77,6 +77,9 @@ } else if (current_cpu == "x64") { win_tool_arch = "environment.x64" idl_target_platform = "x64" + } else if (current_cpu == "arm64") { + win_tool_arch = "environment.arm64" + idl_target_platform = "arm64" } else { assert(false, "Need environment for this arch") }
diff --git a/build/toolchain/win/tool_wrapper.py b/build/toolchain/win/tool_wrapper.py index cb0393e..6479440 100644 --- a/build/toolchain/win/tool_wrapper.py +++ b/build/toolchain/win/tool_wrapper.py
@@ -168,6 +168,11 @@ def ExecAsmWrapper(self, arch, *args): """Filter logo banner from invocations of asm.exe.""" env = self._GetEnv(arch) + if sys.platform == 'win32': + # Windows ARM64 uses clang-cl as assembler which has '/' as path + # separator, convert it to '\\' when running on Windows. + args = list(args) # *args is a tuple by default, which is read-only + args[0] = args[0].replace('/', '\\') popen = subprocess.Popen(args, shell=True, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out, _ = popen.communicate()
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py index 32bad7f4..6a2723e2 100755 --- a/build/vs_toolchain.py +++ b/build/vs_toolchain.py
@@ -238,6 +238,7 @@ # from HostX86/x86. pgo_x86_runtime_dir = os.path.join(pgo_runtime_root, 'HostX86', 'x86') pgo_x64_runtime_dir = os.path.join(pgo_runtime_root, 'HostX64', 'x64') + pgo_arm64_runtime_dir = os.path.join(pgo_runtime_root, 'arm64') else: raise Exception('Unexpected toolchain version: %s.' % env_version) @@ -250,6 +251,8 @@ source = os.path.join(pgo_x86_runtime_dir, runtime) elif target_cpu == 'x64': source = os.path.join(pgo_x64_runtime_dir, runtime) + elif target_cpu == 'arm64': + source = os.path.join(pgo_arm64_runtime_dir, runtime) else: raise NotImplementedError("Unexpected target_cpu value: " + target_cpu) if not os.path.exists(source):
diff --git a/build/win/reorder-imports.py b/build/win/reorder-imports.py index c4b294d..ee27ed1 100755 --- a/build/win/reorder-imports.py +++ b/build/win/reorder-imports.py
@@ -36,7 +36,7 @@ # through the Structure, while other data must bet set through # the set_bytes_*() methods. pe = pefile.PE(input_image, fast_load=True) - if architecture == 'x64': + if architecture == 'x64' or architecture == 'arm64': assert pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE_PLUS else: assert pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE
diff --git a/cc/animation/animation_host_unittest.cc b/cc/animation/animation_host_unittest.cc index 104b16c7..e21a0c9 100644 --- a/cc/animation/animation_host_unittest.cc +++ b/cc/animation/animation_host_unittest.cc
@@ -50,7 +50,8 @@ } void SetOutputState(base::TimeDelta local_time) { - MutatorOutputState::AnimationState state(worklet_animation_id_, local_time); + MutatorOutputState::AnimationState state(worklet_animation_id_); + state.local_times.push_back(local_time); worklet_animation_impl_->SetOutputState(state); }
diff --git a/cc/animation/worklet_animation.cc b/cc/animation/worklet_animation.cc index 34a9746..0c95d0a 100644 --- a/cc/animation/worklet_animation.cc +++ b/cc/animation/worklet_animation.cc
@@ -112,8 +112,12 @@ switch (state_) { case State::PENDING: - input_state->Add( - {worklet_animation_id(), name(), current_time, CloneOptions()}); + // TODO(yigu): cc side WorkletAnimation is only capable of handling single + // keyframe effect at the moment. We should pass in the number of effects + // once Worklet Group Effect is fully implemented in cc. + // https://crbug.com/767043. + input_state->Add({worklet_animation_id(), name(), current_time, + CloneOptions(), 1 /* num_effects */}); state_ = State::RUNNING; break; case State::RUNNING: @@ -127,7 +131,10 @@ void WorkletAnimation::SetOutputState( const MutatorOutputState::AnimationState& state) { - local_time_ = state.local_time; + // TODO(yigu): cc side WorkletAnimation is only capable of handling single + // keyframe effect at the moment. https://crbug.com/767043. + DCHECK_EQ(state.local_times.size(), 1u); + local_time_ = state.local_times[0]; } // TODO(crbug.com/780151): Multiply the result by the play back rate.
diff --git a/cc/animation/worklet_animation_unittest.cc b/cc/animation/worklet_animation_unittest.cc index 673c2cc..fe1bdf55 100644 --- a/cc/animation/worklet_animation_unittest.cc +++ b/cc/animation/worklet_animation_unittest.cc
@@ -64,8 +64,10 @@ false /* not impl instance*/, std::move(effect))); EXPECT_CALL(*mock_effect, Tick(_)).Times(0); - worklet_animation->SetOutputState( - {worklet_animation_id_, base::TimeDelta::FromSecondsD(1)}); + + MutatorOutputState::AnimationState state(worklet_animation_id_); + state.local_times.push_back(base::TimeDelta::FromSecondsD(1)); + worklet_animation->SetOutputState(state); worklet_animation->Tick(base::TimeTicks()); } @@ -87,7 +89,9 @@ keyframe_model->set_needs_synchronized_start_time(false); base::TimeDelta local_time = base::TimeDelta::FromSecondsD(duration / 2); - worklet_animation_->SetOutputState({worklet_animation_id_, local_time}); + MutatorOutputState::AnimationState state(worklet_animation_id_); + state.local_times.push_back(local_time); + worklet_animation_->SetOutputState(state); worklet_animation_->Tick(base::TimeTicks());
diff --git a/cc/raster/bitmap_raster_buffer_provider.cc b/cc/raster/bitmap_raster_buffer_provider.cc index 12eaae7..1e4e21bb 100644 --- a/cc/raster/bitmap_raster_buffer_provider.cc +++ b/cc/raster/bitmap_raster_buffer_provider.cc
@@ -164,4 +164,8 @@ void BitmapRasterBufferProvider::Shutdown() {} +bool BitmapRasterBufferProvider::CheckRasterFinishedQueries() { + return false; +} + } // namespace cc
diff --git a/cc/raster/bitmap_raster_buffer_provider.h b/cc/raster/bitmap_raster_buffer_provider.h index 5174176..9ceb0012 100644 --- a/cc/raster/bitmap_raster_buffer_provider.h +++ b/cc/raster/bitmap_raster_buffer_provider.h
@@ -43,6 +43,7 @@ const base::Closure& callback, uint64_t pending_callback_id) const override; void Shutdown() override; + bool CheckRasterFinishedQueries() override; private: std::unique_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue()
diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc index 6f3c7602..9c516e3 100644 --- a/cc/raster/gpu_raster_buffer_provider.cc +++ b/cc/raster/gpu_raster_buffer_provider.cc
@@ -154,6 +154,7 @@ float recording_to_raster_scale = transform.scale() / raster_source->recording_scale_factor(); gfx::Size content_size = raster_source->GetContentSize(transform.scale()); + // TODO(enne): could skip the clear on new textures, as the service side has // to do that anyway. resource_has_previous_content implies that the texture // is not new, but the reverse does not hold, so more plumbing is needed. @@ -481,23 +482,36 @@ 100.0f * fraction_saved); } - if (enable_oop_rasterization_) { - RasterizeSourceOOP(raster_source, resource_has_previous_content, mailbox, - sync_token, texture_target, texture_is_overlay_candidate, - resource_size, resource_format, color_space, - raster_full_rect, playback_rect, transform, - playback_settings, worker_context_provider_, - msaa_sample_count_); - } else { - RasterizeSource( - raster_source, resource_has_previous_content, mailbox, sync_token, - texture_target, texture_is_overlay_candidate, resource_size, - resource_format, color_space, raster_full_rect, playback_rect, - transform, playback_settings, worker_context_provider_, - msaa_sample_count_, - ShouldUnpremultiplyAndDitherResource(resource_format), max_tile_size_); + // Use a query to time the GPU side work for rasterizing this tile. + pending_raster_queries_.emplace_back(); + auto& query = pending_raster_queries_.back(); + ri->GenQueriesEXT(1, &query.query_id); + ri->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, query.query_id); + + { + base::ElapsedTimer timer; + if (enable_oop_rasterization_) { + RasterizeSourceOOP(raster_source, resource_has_previous_content, mailbox, + sync_token, texture_target, + texture_is_overlay_candidate, resource_size, + resource_format, color_space, raster_full_rect, + playback_rect, transform, playback_settings, + worker_context_provider_, msaa_sample_count_); + } else { + RasterizeSource(raster_source, resource_has_previous_content, mailbox, + sync_token, texture_target, texture_is_overlay_candidate, + resource_size, resource_format, color_space, + raster_full_rect, playback_rect, transform, + playback_settings, worker_context_provider_, + msaa_sample_count_, + ShouldUnpremultiplyAndDitherResource(resource_format), + max_tile_size_); + } + query.worker_duration = timer.Elapsed(); } + ri->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM); + // Generate sync token for cross context synchronization. return viz::ClientResourceProvider::GenerateSyncTokenHelper(ri); } @@ -512,4 +526,52 @@ } } +#define UMA_HISTOGRAM_RASTER_TIME_CUSTOM_MICROSECONDS(name, total_time) \ + UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES( \ + name, total_time, base::TimeDelta::FromMicroseconds(1), \ + base::TimeDelta::FromMilliseconds(100), 100); + +bool GpuRasterBufferProvider::CheckRasterFinishedQueries() { + viz::RasterContextProvider::ScopedRasterContextLock scoped_context( + worker_context_provider_); + auto* ri = scoped_context.RasterInterface(); + + auto it = pending_raster_queries_.begin(); + while (it != pending_raster_queries_.end()) { + GLuint complete = 1; + ri->GetQueryObjectuivEXT(it->query_id, + GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT, + &complete); + if (!complete) + break; + + GLuint gpu_duration = 0u; + ri->GetQueryObjectuivEXT(it->query_id, GL_QUERY_RESULT_EXT, &gpu_duration); + ri->DeleteQueriesEXT(1, &it->query_id); + + base::TimeDelta total_time = + it->worker_duration + base::TimeDelta::FromMicroseconds(gpu_duration); + + // It is safe to use the UMA macros here with runtime generated strings + // because the client name should be initialized once in the process, before + // recording any metrics here. + const char* client_name = GetClientNameForMetrics(); + if (enable_oop_rasterization_) { + UMA_HISTOGRAM_RASTER_TIME_CUSTOM_MICROSECONDS( + base::StringPrintf("Renderer4.%s.RasterTaskTotalDuration.Oop", + client_name), + total_time); + } else { + UMA_HISTOGRAM_RASTER_TIME_CUSTOM_MICROSECONDS( + base::StringPrintf("Renderer4.%s.RasterTaskTotalDuration.Gpu", + client_name), + total_time); + } + + it = pending_raster_queries_.erase(it); + } + + return pending_raster_queries_.size() > 0u; +} + } // namespace cc
diff --git a/cc/raster/gpu_raster_buffer_provider.h b/cc/raster/gpu_raster_buffer_provider.h index 44bc6249..2012687 100644 --- a/cc/raster/gpu_raster_buffer_provider.h +++ b/cc/raster/gpu_raster_buffer_provider.h
@@ -11,6 +11,12 @@ #include "cc/raster/raster_buffer_provider.h" #include "gpu/command_buffer/common/sync_token.h" +namespace gpu { +namespace raster { +class RasterInterface; +} // namespace raster +} // namespace gpu + namespace viz { class ContextProvider; class RasterContextProvider; @@ -47,6 +53,7 @@ const base::Closure& callback, uint64_t pending_callback_id) const override; void Shutdown() override; + bool CheckRasterFinishedQueries() override; gpu::SyncToken PlaybackOnWorkerThread( gpu::Mailbox* mailbox, @@ -118,6 +125,16 @@ const bool unpremultiply_and_dither_low_bit_depth_tiles_; const bool enable_oop_rasterization_; + struct PendingRasterQuery { + // The id for querying the duration in executing the GPU side work. + GLuint query_id = 0u; + + // The duration for executing the work on the raster worker thread. + base::TimeDelta worker_duration; + }; + // This should only be accessed with the context lock acquired. + base::circular_deque<PendingRasterQuery> pending_raster_queries_; + DISALLOW_COPY_AND_ASSIGN(GpuRasterBufferProvider); };
diff --git a/cc/raster/one_copy_raster_buffer_provider.cc b/cc/raster/one_copy_raster_buffer_provider.cc index 5764e17..562d2e2 100644 --- a/cc/raster/one_copy_raster_buffer_provider.cc +++ b/cc/raster/one_copy_raster_buffer_provider.cc
@@ -497,4 +497,8 @@ : gfx::BufferUsage::GPU_READ_CPU_READ_WRITE; } +bool OneCopyRasterBufferProvider::CheckRasterFinishedQueries() { + return false; +} + } // namespace cc
diff --git a/cc/raster/one_copy_raster_buffer_provider.h b/cc/raster/one_copy_raster_buffer_provider.h index 98bb90e..6766cae7 100644 --- a/cc/raster/one_copy_raster_buffer_provider.h +++ b/cc/raster/one_copy_raster_buffer_provider.h
@@ -58,6 +58,7 @@ const base::Closure& callback, uint64_t pending_callback_id) const override; void Shutdown() override; + bool CheckRasterFinishedQueries() override; // Playback raster source and copy result into |resource|. gpu::SyncToken PlaybackAndCopyOnWorkerThread(
diff --git a/cc/raster/raster_buffer_provider.h b/cc/raster/raster_buffer_provider.h index 3e2b1aae..74354c7 100644 --- a/cc/raster/raster_buffer_provider.h +++ b/cc/raster/raster_buffer_provider.h
@@ -88,6 +88,14 @@ // Shutdown for doing cleanup. virtual void Shutdown() = 0; + + // Checks whether GPU side queries issued for previous raster work have been + // finished. Note that this will acquire the worker context lock so it can be + // used from any thread. But usage from the compositor thread should be + // avoided to prevent contention with worker threads. + // Returns true if there are pending queries that could not be completed in + // this check. + virtual bool CheckRasterFinishedQueries() = 0; }; } // namespace cc
diff --git a/cc/raster/raster_buffer_provider_unittest.cc b/cc/raster/raster_buffer_provider_unittest.cc index cbe334d..b18343a 100644 --- a/cc/raster/raster_buffer_provider_unittest.cc +++ b/cc/raster/raster_buffer_provider_unittest.cc
@@ -16,6 +16,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" +#include "base/test/metrics/histogram_tester.h" #include "base/threading/thread_task_runner_handle.h" #include "cc/base/unique_notifier.h" #include "cc/paint/draw_image.h" @@ -487,6 +488,37 @@ EXPECT_FALSE(completed_tasks()[1].canceled); } +TEST_P(RasterBufferProviderTest, MeasureGpuRasterDuration) { + if (GetParam() != RASTER_BUFFER_PROVIDER_TYPE_GPU) + return; + + // Schedule a task. + AppendTask(0u); + ScheduleTasks(); + RunMessageLoopUntilAllTasksHaveCompleted(); + + // Wait for the GPU side work to finish. + base::RunLoop run_loop; + std::vector<const ResourcePool::InUsePoolResource*> array; + for (const auto& resource : resources_) + array.push_back(&resource); + uint64_t callback_id = raster_buffer_provider_->SetReadyToDrawCallback( + array, + base::Bind([](base::RunLoop* run_loop) { run_loop->Quit(); }, &run_loop), + 0); + ASSERT_TRUE(callback_id); + run_loop.Run(); + + // Poll the task and make sure a histogram is logged. + base::HistogramTester histogram_tester; + std::string histogram("Renderer4.Renderer.RasterTaskTotalDuration.Gpu"); + histogram_tester.ExpectTotalCount(histogram, 0); + bool has_pending_queries = + raster_buffer_provider_->CheckRasterFinishedQueries(); + EXPECT_FALSE(has_pending_queries); + histogram_tester.ExpectTotalCount(histogram, 1); +} + INSTANTIATE_TEST_CASE_P( RasterBufferProviderTests, RasterBufferProviderTest,
diff --git a/cc/raster/zero_copy_raster_buffer_provider.cc b/cc/raster/zero_copy_raster_buffer_provider.cc index 037e8a36..21010d7 100644 --- a/cc/raster/zero_copy_raster_buffer_provider.cc +++ b/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -271,4 +271,8 @@ void ZeroCopyRasterBufferProvider::Shutdown() {} +bool ZeroCopyRasterBufferProvider::CheckRasterFinishedQueries() { + return false; +} + } // namespace cc
diff --git a/cc/raster/zero_copy_raster_buffer_provider.h b/cc/raster/zero_copy_raster_buffer_provider.h index 68f78bf..106f7c9 100644 --- a/cc/raster/zero_copy_raster_buffer_provider.h +++ b/cc/raster/zero_copy_raster_buffer_provider.h
@@ -49,6 +49,7 @@ const base::Closure& callback, uint64_t pending_callback_id) const override; void Shutdown() override; + bool CheckRasterFinishedQueries() override; private: std::unique_ptr<base::trace_event::ConvertableToTraceFormat> StateAsValue()
diff --git a/cc/test/cc_test_suite.cc b/cc/test/cc_test_suite.cc index ee7ae53f..53f2531 100644 --- a/cc/test/cc_test_suite.cc +++ b/cc/test/cc_test_suite.cc
@@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/message_loop/message_loop.h" #include "base/threading/thread_id_name_manager.h" +#include "cc/base/histograms.h" #include "components/viz/test/paths.h" #include "gpu/config/gpu_info_collector.h" #include "gpu/config/gpu_preferences.h" @@ -44,6 +45,8 @@ base::ThreadIdNameManager::GetInstance()->SetName("Main"); base::DiscardableMemoryAllocator::SetInstance(&discardable_memory_allocator_); + + SetClientNameForMetrics("Renderer"); } void CCTestSuite::Shutdown() {
diff --git a/cc/test/fake_raster_buffer_provider.cc b/cc/test/fake_raster_buffer_provider.cc index a203f47..9b91296 100644 --- a/cc/test/fake_raster_buffer_provider.cc +++ b/cc/test/fake_raster_buffer_provider.cc
@@ -65,4 +65,8 @@ void FakeRasterBufferProviderImpl::Shutdown() {} +bool FakeRasterBufferProviderImpl::CheckRasterFinishedQueries() { + return false; +} + } // namespace cc
diff --git a/cc/test/fake_raster_buffer_provider.h b/cc/test/fake_raster_buffer_provider.h index b7e8e8d..a93e9c8 100644 --- a/cc/test/fake_raster_buffer_provider.h +++ b/cc/test/fake_raster_buffer_provider.h
@@ -32,6 +32,7 @@ const base::Callback<void()>& callback, uint64_t pending_callback_id) const override; void Shutdown() override; + bool CheckRasterFinishedQueries() override; }; } // namespace cc
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc index 7dc254a..8f07672 100644 --- a/cc/tiles/tile_manager.cc +++ b/cc/tiles/tile_manager.cc
@@ -326,6 +326,36 @@ DISALLOW_COPY_AND_ASSIGN(TaskSetFinishedTaskImpl); }; +class DidFinishRunningAllTilesTask : public TileTask { + public: + using CompletionCb = base::OnceCallback<void(bool has_pending_queries)>; + DidFinishRunningAllTilesTask(base::SequencedTaskRunner* task_runner, + RasterBufferProvider* raster_buffer_provider, + CompletionCb completion_cb) + : TileTask(false /* supports_concurrent_execution */), + task_runner_(task_runner), + raster_buffer_provider_(raster_buffer_provider), + completion_cb_(std::move(completion_cb)) {} + + void RunOnWorkerThread() override { + TRACE_EVENT0("cc", "TaskSetFinishedTaskImpl::RunOnWorkerThread"); + bool has_pending_queries = + raster_buffer_provider_->CheckRasterFinishedQueries(); + task_runner_->PostTask(FROM_HERE, base::BindOnce(std::move(completion_cb_), + has_pending_queries)); + } + + void OnTaskCompleted() override {} + + protected: + ~DidFinishRunningAllTilesTask() override = default; + + private: + base::SequencedTaskRunner* task_runner_; + RasterBufferProvider* raster_buffer_provider_; + CompletionCb completion_cb_; +}; + } // namespace RasterTaskCompletionStats::RasterTaskCompletionStats() @@ -402,6 +432,7 @@ signals_check_notifier_.Cancel(); task_set_finished_weak_ptr_factory_.InvalidateWeakPtrs(); ready_to_draw_callback_weak_ptr_factory_.InvalidateWeakPtrs(); + check_pending_tile_queries_callback_.Cancel(); raster_buffer_provider_ = nullptr; // Ask the tracker to drop any locked decodes since we will be destroying the @@ -457,13 +488,14 @@ signals_check_notifier_.Schedule(); } -void TileManager::DidFinishRunningAllTileTasks() { +void TileManager::DidFinishRunningAllTileTasks(bool has_pending_queries) { TRACE_EVENT0("cc", "TileManager::DidFinishRunningAllTileTasks"); TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this); DCHECK(resource_pool_); DCHECK(tile_task_manager_); has_scheduled_tile_tasks_ = false; + has_pending_queries_ = has_pending_queries; if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && !resource_pool_->ResourceUsageTooHigh()) { @@ -958,8 +990,13 @@ scoped_refptr<TileTask> required_for_draw_done_task = CreateTaskSetFinishedTask( &TileManager::DidFinishRunningTileTasksRequiredForDraw); + + auto all_done_cb = + base::BindOnce(&TileManager::DidFinishRunningAllTileTasks, + task_set_finished_weak_ptr_factory_.GetWeakPtr()); scoped_refptr<TileTask> all_done_task = - CreateTaskSetFinishedTask(&TileManager::DidFinishRunningAllTileTasks); + base::MakeRefCounted<DidFinishRunningAllTilesTask>( + task_runner_, raster_buffer_provider_, std::move(all_done_cb)); // Build a new task queue containing all task currently needed. Tasks // are added in order of priority, highest priority task first. @@ -1350,6 +1387,34 @@ RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW); } +void TileManager::ScheduleCheckRasterFinishedQueries() { + DCHECK(has_pending_queries_); + + if (!check_pending_tile_queries_callback_.IsCancelled()) + return; + + check_pending_tile_queries_callback_.Reset(base::Bind( + &TileManager::CheckRasterFinishedQueries, base::Unretained(this))); + task_runner_->PostDelayedTask(FROM_HERE, + check_pending_tile_queries_callback_.callback(), + base::TimeDelta::FromMilliseconds(100)); +} + +void TileManager::CheckRasterFinishedQueries() { + check_pending_tile_queries_callback_.Cancel(); + + if (!has_pending_queries_) + return; + + // Raster tasks are in progress. The queries will be polled once they finish. + if (has_scheduled_tile_tasks_ || !signals_.all_tile_tasks_completed) + return; + + has_pending_queries_ = raster_buffer_provider_->CheckRasterFinishedQueries(); + if (has_pending_queries_) + ScheduleCheckRasterFinishedQueries(); +} + void TileManager::FlushAndIssueSignals() { TRACE_EVENT0("cc", "TileManager::FlushAndIssueSignals"); tile_task_manager_->CheckForCompletedTasks(); @@ -1389,6 +1454,10 @@ if (!has_scheduled_tile_tasks_) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "TileManager::IssueSignals - all tile tasks completed"); + + if (has_pending_queries_) + ScheduleCheckRasterFinishedQueries(); + signals_.did_notify_all_tile_tasks_completed = true; client_->NotifyAllTileTasksCompleted(); }
diff --git a/cc/tiles/tile_manager.h b/cc/tiles/tile_manager.h index 469b21f..e475cdf 100644 --- a/cc/tiles/tile_manager.h +++ b/cc/tiles/tile_manager.h
@@ -369,7 +369,7 @@ void DidFinishRunningTileTasksRequiredForActivation(); void DidFinishRunningTileTasksRequiredForDraw(); - void DidFinishRunningAllTileTasks(); + void DidFinishRunningAllTileTasks(bool has_pending_queries); scoped_refptr<TileTask> CreateTaskSetFinishedTask( void (TileManager::*callback)()); @@ -397,6 +397,8 @@ void FlushAndIssueSignals(); void CheckPendingGpuWorkAndIssueSignals(); void IssueSignals(); + void ScheduleCheckRasterFinishedQueries(); + void CheckRasterFinishedQueries(); TileManagerClient* client_; base::SequencedTaskRunner* task_runner_; @@ -452,6 +454,11 @@ GURL active_url_; + // The callback scheduled to poll whether the GPU side work for pending tiles + // has completed. + bool has_pending_queries_ = false; + base::CancelableClosure check_pending_tile_queries_callback_; + // We need two WeakPtrFactory objects as the invalidation pattern of each is // different. The |task_set_finished_weak_ptr_factory_| is invalidated any // time new tasks are scheduled, preventing a race when the callback has
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc index 1925b06..6c7fe877 100644 --- a/cc/tiles/tile_manager_unittest.cc +++ b/cc/tiles/tile_manager_unittest.cc
@@ -3344,5 +3344,34 @@ .NumLockedImagesForTesting()); } +class TileManagerCheckRasterQueriesTest : public TileManagerTest { + public: + void SetUp() override { + TileManagerTest::SetUp(); + host_impl()->tile_manager()->SetRasterBufferProviderForTesting( + &raster_buffer_provider_); + } + + protected: + class MockRasterBufferProvider : public FakeRasterBufferProviderImpl { + public: + MOCK_METHOD0(CheckRasterFinishedQueries, bool()); + }; + + MockRasterBufferProvider raster_buffer_provider_; +}; + +TEST_F(TileManagerCheckRasterQueriesTest, + ChecksRasterQueriesInAllTilesDoneTask) { + base::RunLoop run_loop; + EXPECT_FALSE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); + EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted()) + .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); + EXPECT_CALL(raster_buffer_provider_, CheckRasterFinishedQueries()).Times(1); + host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); + EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); + run_loop.Run(); +} + } // namespace } // namespace cc
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index a3a93bbb..4b30c972 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -376,22 +376,14 @@ // Dump property trees and layers if run with: // --vmodule=layer_tree_host=3 if (VLOG_IS_ON(3)) { - VLOG(3) << "After finishing commit on impl, the sync tree:"; - // Because the property tree and layer list output can be verbose, the VLOG - // output is split by line to avoid line buffer limits on android. - VLOG(3) << "property trees:"; std::string property_trees; base::JSONWriter::WriteWithOptions( *sync_tree->property_trees()->AsTracedValue()->ToBaseValue(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &property_trees); - std::stringstream property_trees_stream(property_trees); - for (std::string line; std::getline(property_trees_stream, line);) - VLOG(3) << line; - - VLOG(3) << "layers:"; - std::stringstream layers_stream(host_impl->LayerListAsJson()); - for (std::string line; std::getline(layers_stream, line);) - VLOG(3) << line; + VLOG(3) << "After finishing commit on impl, the sync tree:" + << "\nproperty_trees:\n" + << property_trees << "\nlayers:\n" + << host_impl->LayerListAsJson(); } } @@ -813,33 +805,27 @@ // --vmodule=layer_tree_host=3 // This only prints output for the renderer. if (VLOG_IS_ON(3) && GetClientNameForMetrics() == std::string("Renderer")) { - VLOG(3) << "After updating layers on the main thread:"; - // Because the property tree and layer list output can be verbose, the VLOG - // output is split by line to avoid line buffer limits on android. - VLOG(3) << "property trees:"; std::string property_trees; base::JSONWriter::WriteWithOptions( *property_trees_.AsTracedValue()->ToBaseValue(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &property_trees); - std::stringstream property_trees_stream(property_trees); - for (std::string line; std::getline(property_trees_stream, line);) - VLOG(3) << line; - - VLOG(3) << "layers:"; + std::ostringstream layers; for (auto* layer : *this) { - VLOG(3) << " layer id " << layer->id(); - VLOG(3) << " element_id: " << layer->element_id(); - VLOG(3) << " bounds: " << layer->bounds().ToString(); - VLOG(3) << " opacity: " << layer->opacity(); - VLOG(3) << " position: " << layer->position().ToString(); - VLOG(3) << " draws_content: " << layer->DrawsContent(); - VLOG(3) << " scrollable: " << layer->scrollable(); - VLOG(3) << " contents_opaque: " << layer->contents_opaque(); - VLOG(3) << " transform_tree_index: " << layer->transform_tree_index(); - VLOG(3) << " clip_tree_index: " << layer->clip_tree_index(); - VLOG(3) << " effect_tree_index: " << layer->effect_tree_index(); - VLOG(3) << " scroll_tree_index: " << layer->scroll_tree_index(); + layers << "\n layer id " << layer->id(); + layers << "\n element_id: " << layer->element_id(); + layers << "\n bounds: " << layer->bounds().ToString(); + layers << "\n opacity: " << layer->opacity(); + layers << "\n position: " << layer->position().ToString(); + layers << "\n draws_content: " << layer->DrawsContent(); + layers << "\n scrollable: " << layer->scrollable(); + layers << "\n contents_opaque: " << layer->contents_opaque(); + layers << "\n transform_tree_index: " << layer->transform_tree_index(); + layers << "\n clip_tree_index: " << layer->clip_tree_index(); + layers << "\n effect_tree_index: " << layer->effect_tree_index(); + layers << "\n scroll_tree_index: " << layer->scroll_tree_index(); } + VLOG(3) << "After updating layers on the main thread:\nproperty trees:\n" + << property_trees << "\nlayers:" << layers.str(); } bool painted_content_has_slow_paths = false;
diff --git a/cc/trees/layer_tree_mutator.cc b/cc/trees/layer_tree_mutator.cc index 845ed7d..491eec5 100644 --- a/cc/trees/layer_tree_mutator.cc +++ b/cc/trees/layer_tree_mutator.cc
@@ -12,11 +12,13 @@ WorkletAnimationId worklet_animation_id, std::string name, double current_time, - std::unique_ptr<AnimationOptions> options) + std::unique_ptr<AnimationOptions> options, + int num_effects) : worklet_animation_id(worklet_animation_id), name(name), current_time(current_time), - options(std::move(options)) {} + options(std::move(options)), + num_effects(num_effects) {} AnimationWorkletInput::AddAndUpdateState::AddAndUpdateState( AddAndUpdateState&&) = default; AnimationWorkletInput::AddAndUpdateState::~AddAndUpdateState() = default; @@ -97,11 +99,10 @@ AnimationWorkletOutput::AnimationWorkletOutput() = default; AnimationWorkletOutput::~AnimationWorkletOutput() = default; -AnimationWorkletOutput::AnimationState::AnimationState( - WorkletAnimationId id, - base::Optional<base::TimeDelta> time) - : worklet_animation_id(id), local_time(time) {} +AnimationWorkletOutput::AnimationState::AnimationState(WorkletAnimationId id) + : worklet_animation_id(id) {} AnimationWorkletOutput::AnimationState::AnimationState(const AnimationState&) = default; +AnimationWorkletOutput::AnimationState::~AnimationState() = default; } // namespace cc
diff --git a/cc/trees/layer_tree_mutator.h b/cc/trees/layer_tree_mutator.h index dd702c4..42cc3177 100644 --- a/cc/trees/layer_tree_mutator.h +++ b/cc/trees/layer_tree_mutator.h
@@ -40,11 +40,13 @@ // Worklet animation's current time, from its associated timeline. double current_time; std::unique_ptr<AnimationOptions> options; + int num_effects; AddAndUpdateState(WorkletAnimationId worklet_animation_id, std::string name, double current_time, - std::unique_ptr<AnimationOptions> options); + std::unique_ptr<AnimationOptions> options, + int num_effects); AddAndUpdateState(AddAndUpdateState&&); ~AddAndUpdateState(); @@ -109,16 +111,12 @@ struct CC_EXPORT AnimationWorkletOutput { struct CC_EXPORT AnimationState { - AnimationState(WorkletAnimationId, - base::Optional<base::TimeDelta> local_time); + explicit AnimationState(WorkletAnimationId); AnimationState(const AnimationState&); + ~AnimationState(); WorkletAnimationId worklet_animation_id; - // The animator effect's local time. - // TODO(majidvp): This assumes each animator has a single output effect - // which does not hold once we state support group effects. - // http://crbug.com/767043 - base::Optional<base::TimeDelta> local_time; + std::vector<base::Optional<base::TimeDelta>> local_times; }; AnimationWorkletOutput();
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index d61e686b..b413506 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -1547,10 +1547,14 @@ use_chromium_linker = false uncompress_shared_libraries = true - _native_lib_file = - rebase_path("$root_gen_dir/CHROME_VERSION.json", root_out_dir) - native_lib_version_arg = "@FileArg($_native_lib_file:full-quoted)" - native_lib_version_rule = "//build/util:chrome_version_json" + # Only try to generate the native library version in configurations that + # include a native library. + if (!android_64bit_target_cpu || build_apk_secondary_abi) { + _native_lib_file = + rebase_path("$root_gen_dir/CHROME_VERSION.json", root_out_dir) + native_lib_version_arg = "@FileArg($_native_lib_file:full-quoted)" + native_lib_version_rule = "//build/util:chrome_version_json" + } if (android_64bit_target_cpu) { # Include a 64-bit placeholder library to ensure that the library is treated
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java index 5faf2c6..299fae0 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java
@@ -425,7 +425,7 @@ * the FeedProcessScope will be reset. */ @VisibleForTesting - public static void setInTestMode(boolean inTestMode) { + public static void setInTestMode(boolean inTestMode, TestNetworkClient networkClient) { if (inTestMode) { FeedScheduler feedScheduler = new TestFeedScheduler(); FeedAppLifecycleListener lifecycleListener = @@ -433,9 +433,8 @@ Profile profile = Profile.getLastUsedProfile().getOriginalProfile(); FeedAppLifecycle feedAppLifecycle = new FeedAppLifecycle( lifecycleListener, new FeedLifecycleBridge(profile), feedScheduler); - FeedProcessScopeFactory.createFeedProcessScopeForTesting(feedScheduler, - new TestNetworkClient(), new TestFeedOfflineIndicator(), feedAppLifecycle, - lifecycleListener); + FeedProcessScopeFactory.createFeedProcessScopeForTesting(feedScheduler, networkClient, + new TestFeedOfflineIndicator(), feedAppLifecycle, lifecycleListener); } else { FeedProcessScopeFactory.clearFeedProcessScopeForTesting(); }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java index cd843ce1..3d304607f 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java
@@ -33,7 +33,6 @@ private static FeedProcessScope sFeedProcessScope; private static FeedScheduler sFeedScheduler; private static FeedOfflineIndicator sFeedOfflineIndicator; - private static NetworkClient sTestNetworkClient; private static FeedLoggingBridge sFeedLoggingBridge; /** @return The shared {@link FeedProcessScope} instance. Null if the Feed is disabled. */ @@ -111,17 +110,16 @@ new FeedAppLifecycleListener(new ThreadUtils()); FeedContentStorage contentStorage = new FeedContentStorage(profile); FeedJournalStorage journalStorage = new FeedJournalStorage(profile); - NetworkClient networkClient = sTestNetworkClient == null ? - new FeedNetworkBridge(profile) : sTestNetworkClient; sFeedLoggingBridge = new FeedLoggingBridge(profile); - sFeedProcessScope = new FeedProcessScope - .Builder(configHostApi, Executors.newSingleThreadExecutor(), - new LoggingApiImpl(), networkClient, schedulerBridge, - lifecycleListener, DebugBehavior.SILENT, - ContextUtils.getApplicationContext(), applicationInfo) - .setContentStorage(contentStorage) - .setJournalStorage(journalStorage) - .build(); + sFeedProcessScope = + new FeedProcessScope + .Builder(configHostApi, Executors.newSingleThreadExecutor(), + new LoggingApiImpl(), new FeedNetworkBridge(profile), + schedulerBridge, lifecycleListener, DebugBehavior.SILENT, + ContextUtils.getApplicationContext(), applicationInfo) + .setContentStorage(contentStorage) + .setJournalStorage(journalStorage) + .build(); schedulerBridge.initializeFeedDependencies( sFeedProcessScope.getRequestManager(), sFeedProcessScope.getSessionManager()); @@ -159,19 +157,6 @@ sFeedAppLifecycle = feedAppLifecycle; } - /** Use supplied NetworkClient instead of real one, for tests. */ - @VisibleForTesting - public static void setTestNetworkClient(NetworkClient client) { - if (client == null) { - sTestNetworkClient = null; - } else if (sFeedProcessScope == null) { - sTestNetworkClient = client; - } else { - throw(new IllegalStateException( - "TestNetworkClient can not be set after FeedProcessScope has initialized.")); - } - } - /** Resets the FeedProcessScope after testing is complete. */ @VisibleForTesting static void clearFeedProcessScopeForTesting() {
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/TestNetworkClient.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/TestNetworkClient.java index cc71bd9..56e1a9dd 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/TestNetworkClient.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/TestNetworkClient.java
@@ -59,6 +59,7 @@ mMockServer = MockServer.getDefaultInstance(); } else { mMockServer = MockServer.parseFrom(fs); + fs.close(); } }
diff --git a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_sheet.xml b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_sheet.xml index a1177a9..535f5ace 100644 --- a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_sheet.xml +++ b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_sheet.xml
@@ -76,19 +76,10 @@ android:contentDescription="@string/close" /> </LinearLayout> - <org.chromium.chrome.browser.widget.MaterialProgressBar - android:id="@+id/progress_bar" - android:layout_width="match_parent" - android:layout_height="4dp" - app:colorBackground="@color/modern_grey_300" - app:colorProgress="@color/modern_blue_600" - android:visibility="invisible" /> - <RelativeLayout android:id="@+id/details" android:layout_width="match_parent" android:layout_height="@dimen/autofill_assistant_details_image_size" - android:layout_marginTop="8dp" android:layout_marginStart="24dp" android:layout_marginEnd="24dp" android:layout_marginBottom="8dp"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index 2f38f8b..bef70fe1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -270,6 +270,7 @@ public static final String PWA_PERSISTENT_NOTIFICATION = "PwaPersistentNotification"; public static final String READER_MODE_IN_CCT = "ReaderModeInCCT"; public static final String REMOVE_NAVIGATION_HISTORY = "RemoveNavigationHistory"; + public static final String SERVICE_MANAGER_FOR_DOWNLOAD = "ServiceManagerForDownload"; public static final String SERVICE_WORKER_PAYMENT_APPS = "ServiceWorkerPaymentApps"; public static final String SHOW_TRUSTED_PUBLISHER_URL = "ShowTrustedPublisherURL"; public static final String SIMPLIFIED_NTP = "SimplifiedNTP";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java index c9e9d75..3bfd415 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
@@ -237,16 +237,6 @@ new AutofillAssistantUiDelegate.Details(title, url, date, description)); } - @CalledByNative - private void onShowProgressBar(int progress, String message) { - mUiDelegate.showProgressBar(progress, message); - } - - @CalledByNative - private void onHideProgressBar() { - mUiDelegate.hideProgressBar(); - } - // native methods. private native long nativeInit( WebContents webContents, String[] parameterNames, String[] parameterValues);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java index 9e949dc..c996577 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiDelegate.java
@@ -28,7 +28,6 @@ import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard; import org.chromium.chrome.browser.help.HelpAndFeedback; import org.chromium.chrome.browser.profiles.Profile; -import org.chromium.chrome.browser.widget.MaterialProgressBar; import java.io.InputStream; import java.net.URL; @@ -56,7 +55,6 @@ private final LinearLayout mBottomBar; private final ViewGroup mChipsViewContainer; private final TextView mStatusMessageView; - private final MaterialProgressBar mProgressBar; private final ViewGroup mDetails; private final AppCompatImageView mDetailsImage; @@ -191,7 +189,6 @@ FEEDBACK_CATEGORY_TAG)); mChipsViewContainer = mBottomBar.findViewById(R.id.carousel); mStatusMessageView = mBottomBar.findViewById(R.id.status_message); - mProgressBar = mBottomBar.findViewById(R.id.progress_bar); mDetails = (ViewGroup) mBottomBar.findViewById(R.id.details); mDetailsImage = (AppCompatImageView) mDetails.findViewById(R.id.details_image); @@ -332,21 +329,6 @@ return roundedBitmap; } - public void showProgressBar(int progress, String message) { - ensureFullContainerIsShown(); - // TODO(crbug.com/806868): Animate the progress change. - mProgressBar.setProgress(progress); - mProgressBar.setVisibility(View.VISIBLE); - - if (!message.isEmpty()) { - mStatusMessageView.setText(message); - } - } - - public void hideProgressBar() { - mProgressBar.setVisibility(View.INVISIBLE); - } - /** * Shuts down the Autofill Assistant. The UI disappears and any associated state goes away. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java index 6edf424..1c08137a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadBroadcastManager.java
@@ -33,10 +33,12 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.library_loader.ProcessInitException; import org.chromium.chrome.browser.ChromeApplication; +import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.download.items.OfflineContentAggregatorNotificationBridgeUiFactory; import org.chromium.chrome.browser.init.BrowserParts; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.init.EmptyBrowserParts; +import org.chromium.chrome.browser.init.ServiceManagerStartupUtils; import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.components.offline_items_collection.ContentId; import org.chromium.components.offline_items_collection.LegacyHelpers; @@ -179,9 +181,9 @@ @Override public boolean startServiceManagerOnly() { - // TODO(qinmin): change this to return true once ServiceManager can be started - // without launching full browser. - return false; + return ServiceManagerStartupUtils.canStartServiceManager( + ChromeFeatureList.SERVICE_MANAGER_FOR_DOWNLOAD) + && !ACTION_DOWNLOAD_OPEN.equals(intent.getAction()); } };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java index 22c6d2a..6d92e63 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
@@ -46,10 +46,12 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.ChromeApplication; +import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.download.items.OfflineContentAggregatorNotificationBridgeUiFactory; import org.chromium.chrome.browser.init.BrowserParts; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.init.EmptyBrowserParts; +import org.chromium.chrome.browser.init.ServiceManagerStartupUtils; import org.chromium.chrome.browser.media.MediaViewerUtils; import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder; import org.chromium.chrome.browser.notifications.NotificationBuilderFactory; @@ -1249,6 +1251,13 @@ ? entry.notificationId : -1); } + + @Override + public boolean startServiceManagerOnly() { + return ServiceManagerStartupUtils.canStartServiceManager( + ChromeFeatureList.SERVICE_MANAGER_FOR_DOWNLOAD) + && !ACTION_DOWNLOAD_OPEN.equals(intent.getAction()); + } }; try { ChromeBrowserInitializer.getInstance(ContextUtils.getApplicationContext())
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/storage/StorageSummaryProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/storage/StorageSummaryProvider.java index dcd89797..f657ce3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/storage/StorageSummaryProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/storage/StorageSummaryProvider.java
@@ -96,7 +96,7 @@ public void onItemUpdated(OfflineItem oldItem, OfflineItem item) { // Computes the delta of storage used by downloads. mTotalDownloadSize -= oldItem.receivedBytes; - mTotalDownloadSize += oldItem.receivedBytes; + mTotalDownloadSize += item.receivedBytes; if (item.state != OfflineItemState.IN_PROGRESS) update(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/CategoryCardAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/CategoryCardAdapter.java index 729afb6..01f35103 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/CategoryCardAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/CategoryCardAdapter.java
@@ -123,7 +123,8 @@ } if (key == ExploreSitesPage.SCROLL_TO_CATEGORY_KEY) { int pos = mCategoryModel.get(ExploreSitesPage.SCROLL_TO_CATEGORY_KEY); - mLayoutManager.scrollToPosition(pos); + // Add 1 for title. + mLayoutManager.scrollToPosition(pos + 1); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPage.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPage.java index e09339f3..9045074 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPage.java
@@ -40,6 +40,7 @@ public class ExploreSitesPage extends BasicNativePage { private static final String TAG = "ExploreSitesPage"; private static final String CONTEXT_MENU_USER_ACTION_PREFIX = "ExploreSites"; + private static final int INITIAL_SCROLL_POSITION = 3; static final PropertyModel.WritableIntPropertyKey STATUS_KEY = new PropertyModel.WritableIntPropertyKey(); static final PropertyModel.WritableIntPropertyKey SCROLL_TO_CATEGORY_KEY = @@ -144,6 +145,9 @@ categoryListModel.set(categoryList); if (mNavFragment != null) { lookupCategoryAndScroll(mNavFragment); + } else { + mModel.set(SCROLL_TO_CATEGORY_KEY, + Math.min(categoryListModel.size() - 1, INITIAL_SCROLL_POSITION)); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java index 5292665e..9ecd8c8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
@@ -422,6 +422,7 @@ mNativeInitializationComplete = true; ContentUriUtils.setFileProviderUtil(new FileProviderHelper()); + ServiceManagerStartupUtils.registerEnabledFeatures(); // When a minidump is detected, extract and append a logcat to it, then upload it to the // crash server. Note that the logcat extraction might fail. This is ok; in that case, the
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ServiceManagerStartupUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ServiceManagerStartupUtils.java new file mode 100644 index 0000000..16d5723e --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ServiceManagerStartupUtils.java
@@ -0,0 +1,57 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.init; + +import android.content.SharedPreferences; + +import org.chromium.base.ContextUtils; +import org.chromium.chrome.browser.ChromeFeatureList; + +import java.util.HashSet; +import java.util.Set; + +/** + * Helper class for features to query the SharedPreferences to learn whether they can start + * ServiceManager instead of full browser on startup. Because Java code can only access the feature + * list after native library is loaded, this class stores the feature values in the + * SharedPreferences so that Java classes can access them on next startup. + */ +public class ServiceManagerStartupUtils { + // List of features that supports starting ServiceManager on startup. + private static final String[] SERVICE_MANAGER_FEATURES = { + ChromeFeatureList.SERVICE_MANAGER_FOR_DOWNLOAD}; + // Key in the SharedPreferences for storing all features that will start ServiceManager. + private static final String SERVICE_MANAGER_FEATURES_KEY = "ServiceManagerFeatures"; + + /** + * Check whether ServiceManager can be started for |featureName|. + * @param featureName Feature to query. + * @return Whether the feature can start service manager. + */ + public static boolean canStartServiceManager(String featureName) { + Set<String> features = ContextUtils.getAppSharedPreferences().getStringSet( + SERVICE_MANAGER_FEATURES_KEY, null); + return features != null && features.contains(featureName); + } + + /** + * Register all the service manager startup features with SharedPreferences. + */ + public static void registerEnabledFeatures() { + SharedPreferences.Editor editor = ContextUtils.getAppSharedPreferences().edit(); + Set<String> features = new HashSet<String>(); + for (String feature : SERVICE_MANAGER_FEATURES) { + if (ChromeFeatureList.isEnabled(feature)) { + features.add(feature); + } + } + if (features.isEmpty()) { + editor.remove(SERVICE_MANAGER_FEATURES_KEY); + } else { + editor.putStringSet(SERVICE_MANAGER_FEATURES_KEY, features); + } + editor.apply(); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index cbdfb9f..6a0c7c2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -325,7 +325,16 @@ updateSearchProviderHasLogo(); initializeMainView(activity); - updateMargins(mTab.getBrowserControlsStateConstraints()); + getView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { + @Override + public void onViewAttachedToWindow(View view) { + updateMargins(mTab.getBrowserControlsStateConstraints()); + getView().removeOnAttachStateChangeListener(this); + } + + @Override + public void onViewDetachedFromWindow(View view) {} + }); eventReporter.onSurfaceOpened(); @@ -384,12 +393,7 @@ View view = getView(); ViewGroup.MarginLayoutParams layoutParams = ((ViewGroup.MarginLayoutParams) view.getLayoutParams()); - if (layoutParams == null) { - // We could be updating the margin before the root view is attached to window. - layoutParams = new ViewGroup.MarginLayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); - view.setLayoutParams(layoutParams); - } + if (layoutParams == null) return; int bottomMargin = 0; if (FeatureUtilities.isBottomToolbarEnabled()
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 108acac..fc4ca9b7 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -760,6 +760,7 @@ "java/src/org/chromium/chrome/browser/init/InvalidStartupDialog.java", "java/src/org/chromium/chrome/browser/init/NativeInitializationController.java", "java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java", + "java/src/org/chromium/chrome/browser/init/ServiceManagerStartupUtils.java", "java/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderFactory.java", "java/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderImpl.java", "java/src/org/chromium/chrome/browser/installedapp/PackageHash.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java index 0b1a072..cb2c506a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java
@@ -30,6 +30,7 @@ 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.UrlUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeSwitches; @@ -49,8 +50,11 @@ import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils; import org.chromium.chrome.test.util.browser.suggestions.FakeMostVisitedSites; import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; +import org.chromium.net.NetworkChangeNotifier; import org.chromium.net.test.EmbeddedTestServer; +import java.io.FileInputStream; +import java.io.IOException; import java.util.List; /** @@ -61,6 +65,13 @@ @CommandLineFlags.Add(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE) @Features.EnableFeatures(ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS) public class FeedNewTabPageTest { + private static final String FILEPATH = "chrome/test/data/android/feed/feed_large.gcl.bin"; + private static final String FIRST_CARD_URL = "http://profootballtalk.nbcsports.com/2017/11/10/" + + "jerry-jones-owners-should-approve-of-roger-goodells-decisions/"; + private static final int SIGNIN_PROMO_POSITION = 1; + private static final int ARTICLE_SECTION_HEADER_POSITION = 2; + private static final int FIRST_CARD_POSITION = 3; + @Rule public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); @@ -73,11 +84,22 @@ private FakeMostVisitedSites mMostVisitedSites; private EmbeddedTestServer mTestServer; private List<SiteSuggestion> mSiteSuggestions; + private TestNetworkClient mTestNetworkClient; @Before public void setUp() throws Exception { mActivityTestRule.startMainActivityWithURL("about:blank"); - ThreadUtils.runOnUiThreadBlocking(() -> FeedNewTabPage.setInTestMode(true)); + // Ensure we start in an online state. + ThreadUtils.runOnUiThreadBlocking(() -> { + if (!NetworkChangeNotifier.isInitialized()) { + NetworkChangeNotifier.init(); + } + NetworkChangeNotifier.forceConnectivityState(true); + }); + + mTestNetworkClient = new TestNetworkClient(); + ThreadUtils.runOnUiThreadBlocking( + () -> FeedNewTabPage.setInTestMode(true, mTestNetworkClient)); mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); mSiteSuggestions = NewTabPageTestUtils.createFakeSiteSuggestions(mTestServer); @@ -98,7 +120,7 @@ @After public void tearDown() { mTestServer.stopAndDestroyServer(); - ThreadUtils.runOnUiThreadBlocking(() -> FeedNewTabPage.setInTestMode(false)); + ThreadUtils.runOnUiThreadBlocking(() -> FeedNewTabPage.setInTestMode(false, null)); } @Test @@ -114,18 +136,21 @@ // that sign-in promo is not shown. ThreadUtils.runOnUiThreadBlocking(signinObserver::onSignedIn); RecyclerViewTestUtils.waitForStableRecyclerView(recyclerView); - onView(instanceOf(RecyclerView.class)).perform(RecyclerViewActions.scrollToPosition(1)); + onView(instanceOf(RecyclerView.class)) + .perform(RecyclerViewActions.scrollToPosition(SIGNIN_PROMO_POSITION)); onView(withId(R.id.signin_promo_view_container)).check(doesNotExist()); // Simulate sign out, scroll to the position where sign-in promo could be placed, and verify // that sign-in promo is shown. ThreadUtils.runOnUiThreadBlocking(signinObserver::onSignedOut); RecyclerViewTestUtils.waitForStableRecyclerView(recyclerView); - onView(instanceOf(RecyclerView.class)).perform(RecyclerViewActions.scrollToPosition(1)); + onView(instanceOf(RecyclerView.class)) + .perform(RecyclerViewActions.scrollToPosition(SIGNIN_PROMO_POSITION)); onView(withId(R.id.signin_promo_view_container)).check(matches(isDisplayed())); // Scroll to the article section header in case it is not visible. - onView(instanceOf(RecyclerView.class)).perform(RecyclerViewActions.scrollToPosition(2)); + onView(instanceOf(RecyclerView.class)) + .perform(RecyclerViewActions.scrollToPosition(ARTICLE_SECTION_HEADER_POSITION)); // Hide articles and verify that the sign-in promo is not shown. onView(withId(R.id.header_title)).perform(click()); @@ -256,6 +281,23 @@ Pref.NTP_ARTICLES_SECTION_ENABLED, pref)); } + @Test + @MediumTest + @Feature({"FeedNewTabPage"}) + public void testClickSuggestion() throws InterruptedException, IOException { + FileInputStream is = new FileInputStream(UrlUtils.getIsolatedTestFilePath(FILEPATH)); + mTestNetworkClient.setResponseData(is); + ThreadUtils.runOnUiThreadBlocking(() -> mNtp.getStream().triggerRefresh()); + + ChromeTabUtils.waitForTabPageLoaded(mTab, () -> { + onView(instanceOf(RecyclerView.class)) + .perform(RecyclerViewActions.scrollToPosition(FIRST_CARD_POSITION), + RecyclerViewActions.actionOnItemAtPosition( + FIRST_CARD_POSITION, click())); + }); + Assert.assertEquals(FIRST_CARD_URL, mTab.getUrl()); + } + private boolean getPreferenceForArticleSectionHeader() throws Exception { return ThreadUtils.runOnUiThreadBlocking( () -> PrefServiceBridge.getInstance().getBoolean(Pref.NTP_ARTICLES_LIST_VISIBLE));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java index 6c174325..376e9fb0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
@@ -47,6 +47,7 @@ import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.feed.FeedNewTabPage; +import org.chromium.chrome.browser.feed.TestNetworkClient; import org.chromium.chrome.browser.native_page.ContextMenuManager; import org.chromium.chrome.browser.ntp.cards.NewTabPageAdapter; import org.chromium.chrome.browser.ntp.cards.NewTabPageRecyclerView; @@ -145,7 +146,8 @@ public void setUp() throws Exception { mActivityTestRule.startMainActivityWithURL("about:blank"); if (mInterestFeedEnabled) { - ThreadUtils.runOnUiThreadBlocking(() -> FeedNewTabPage.setInTestMode(true)); + ThreadUtils.runOnUiThreadBlocking( + () -> FeedNewTabPage.setInTestMode(true, new TestNetworkClient())); } mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); @@ -170,7 +172,7 @@ public void tearDown() throws Exception { mTestServer.stopAndDestroyServer(); if (mInterestFeedEnabled) { - ThreadUtils.runOnUiThreadBlocking(() -> FeedNewTabPage.setInTestMode(false)); + ThreadUtils.runOnUiThreadBlocking(() -> FeedNewTabPage.setInTestMode(false, null)); } }
diff --git a/chrome/android/webapk/shell_apk/current_version/current_version.gni b/chrome/android/webapk/shell_apk/current_version/current_version.gni index 066e59bc..1005969 100644 --- a/chrome/android/webapk/shell_apk/current_version/current_version.gni +++ b/chrome/android/webapk/shell_apk/current_version/current_version.gni
@@ -12,4 +12,4 @@ # //chrome/android/webapk/shell_apk:webapk is changed. This includes # Java files, Android resource files and AndroidManifest.xml. Does not affect # Chrome.apk -current_shell_apk_version = 64 +current_shell_apk_version = 65
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java index aba712f6..d561899 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserLauncher.java
@@ -35,7 +35,8 @@ public static void launch(Context context, HostBrowserLauncherParams params) { Log.v(TAG, "WebAPK Launch URL: " + params.getStartUrl()); - if (HostBrowserUtils.shouldLaunchInTab(params.getHostBrowserMajorChromiumVersion())) { + if (HostBrowserUtils.shouldLaunchInTab(params.getHostBrowserPackageName(), + params.getHostBrowserMajorChromiumVersion())) { launchInTab(context, params); return; }
diff --git a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java index c76a74b..29d3153 100644 --- a/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java +++ b/chrome/android/webapk/shell_apk/src/org/chromium/webapk/shell_apk/HostBrowserUtils.java
@@ -29,6 +29,8 @@ private static final int MINIMUM_REQUIRED_CHROME_VERSION = 57; + private static final int MINIMUM_REQUIRED_INTENT_HELPER_VERSION = 2; + private static final String TAG = "cr_HostBrowserUtils"; /** @@ -212,7 +214,16 @@ } /** Returns whether a WebAPK should be launched as a tab. See crbug.com/772398. */ - public static boolean shouldLaunchInTab(int hostBrowserChromiumMajorVersion) { + public static boolean shouldLaunchInTab( + String hostBrowserPackageName, int hostBrowserChromiumMajorVersion) { + if (!sBrowsersSupportingWebApk.contains(hostBrowserPackageName)) { + return true; + } + + if (TextUtils.equals(hostBrowserPackageName, "org.chromium.arc.intent_helper")) { + return hostBrowserChromiumMajorVersion < MINIMUM_REQUIRED_INTENT_HELPER_VERSION; + } + return hostBrowserChromiumMajorVersion < MINIMUM_REQUIRED_CHROME_VERSION; } }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 29b71b9..0d406e83 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -244,6 +244,8 @@ "browsing_data/site_data_size_collector.h", "cache_stats_recorder.cc", "cache_stats_recorder.h", + "cached_image_fetcher/cached_image_fetcher_service_factory.cc", + "cached_image_fetcher/cached_image_fetcher_service_factory.h", "chooser_controller/chooser_controller.cc", "chooser_controller/chooser_controller.h", "chrome_browser_application_mac.h", @@ -803,8 +805,6 @@ "native_window_notification_source.h", "navigation_predictor/navigation_predictor.cc", "navigation_predictor/navigation_predictor.h", - "net/chrome_accept_language_settings.cc", - "net/chrome_accept_language_settings.h", "net/chrome_cookie_notification_details.h", "net/chrome_extensions_network_delegate.cc", "net/chrome_extensions_network_delegate.h", @@ -1781,6 +1781,7 @@ "//components/history/content/browser", "//components/history/core/browser", "//components/history/core/common", + "//components/image_fetcher/core", "//components/infobars/core", "//components/invalidation/impl", "//components/keyed_service/content",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index cbb8dac..12cda67 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4466,6 +4466,12 @@ kOsAndroid, FEATURE_VALUE_TYPE(safe_browsing::kUseLocalBlacklistsV2)}, #endif // defined(OS_ANDROID) +#if defined(OS_CHROMEOS) + {"enable-native-google-assistant", + flag_descriptions::kEnableGoogleAssistantName, + flag_descriptions::kEnableGoogleAssistantDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::switches::kAssistantFeature)}, +#endif // defined(OS_ANDROID) }; class FlagsStateSingleton {
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index 349a7744..8dfa01d 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -239,20 +239,6 @@ month, day, hour, minute, second); } -void UiControllerAndroid::ShowProgressBar(int progress, - const std::string& message) { - JNIEnv* env = AttachCurrentThread(); - Java_AutofillAssistantUiController_onShowProgressBar( - env, java_autofill_assistant_ui_controller_, progress, - base::android::ConvertUTF8ToJavaString(env, message)); -} - -void UiControllerAndroid::HideProgressBar() { - JNIEnv* env = AttachCurrentThread(); - Java_AutofillAssistantUiController_onHideProgressBar( - env, java_autofill_assistant_ui_controller_); -} - std::string UiControllerAndroid::GetApiKey() { std::string api_key; if (google_apis::IsGoogleChromeAPIKeyUsed()) {
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.h b/chrome/browser/android/autofill_assistant/ui_controller_android.h index 73769c69..707702e 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.h +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.h
@@ -42,8 +42,6 @@ override; void HideDetails() override; void ShowDetails(const DetailsProto& details) override; - void ShowProgressBar(int progress, const std::string& message) override; - void HideProgressBar() override; // Overrides Client: std::string GetApiKey() override;
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index ede7ea9..2f31c8c 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -136,6 +136,7 @@ &kReaderModeInCCT, &kSearchEnginePromoExistingDevice, &kSearchEnginePromoNewDevice, + &kServiceManagerForDownload, &kSoleIntegration, &kSpannableInlineAutocomplete, &kSpecialLocaleFeature, @@ -384,6 +385,9 @@ const base::Feature kReaderModeInCCT{"ReaderModeInCCT", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kServiceManagerForDownload{ + "ServiceManagerForDownload", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kSimplifiedNTP{"SimplifiedNTP", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index 0dea05a..f9104a9 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -76,6 +76,7 @@ extern const base::Feature kPwaImprovedSplashScreen; extern const base::Feature kPwaPersistentNotification; extern const base::Feature kReaderModeInCCT; +extern const base::Feature kServiceManagerForDownload; extern const base::Feature kSimplifiedNTP; extern const base::Feature kSoleIntegration; extern const base::Feature kSpannableInlineAutocomplete;
diff --git a/chrome/browser/android/explore_sites/explore_sites_fetcher.cc b/chrome/browser/android/explore_sites/explore_sites_fetcher.cc index 1446f979..d1431d66 100644 --- a/chrome/browser/android/explore_sites/explore_sites_fetcher.cc +++ b/chrome/browser/android/explore_sites/explore_sites_fetcher.cc
@@ -22,7 +22,6 @@ #include "chrome/browser/android/explore_sites/explore_sites_types.h" #include "chrome/browser/android/explore_sites/url_util.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/net/chrome_accept_language_settings.h" #include "chrome/common/channel_info.h" #include "components/variations/service/variations_service.h" #include "components/version_info/version_info.h"
diff --git a/chrome/browser/android/explore_sites/explore_sites_service_impl.cc b/chrome/browser/android/explore_sites/explore_sites_service_impl.cc index c39835a..8e2f63c 100644 --- a/chrome/browser/android/explore_sites/explore_sites_service_impl.cc +++ b/chrome/browser/android/explore_sites/explore_sites_service_impl.cc
@@ -23,9 +23,6 @@ using chrome::android::explore_sites::GetExploreSitesVariation; namespace explore_sites { -namespace { -const int kFaviconsPerCategoryImage = 4; -} ExploreSitesServiceImpl::ExploreSitesServiceImpl( std::unique_ptr<ExploreSitesStore> store,
diff --git a/chrome/browser/android/explore_sites/explore_sites_types.h b/chrome/browser/android/explore_sites/explore_sites_types.h index 88a147f..f9bc42d 100644 --- a/chrome/browser/android/explore_sites/explore_sites_types.h +++ b/chrome/browser/android/explore_sites/explore_sites_types.h
@@ -16,6 +16,8 @@ #include "url/gurl.h" namespace explore_sites { +constexpr int kFaviconsPerCategoryImage = 4; + // The in-memory representation of a site in the ExploreSitesStore. // Image data is not represented here because it is requested separately from // the UI layer.
diff --git a/chrome/browser/android/explore_sites/image_helper.cc b/chrome/browser/android/explore_sites/image_helper.cc index d85887c7..95af464 100644 --- a/chrome/browser/android/explore_sites/image_helper.cc +++ b/chrome/browser/android/explore_sites/image_helper.cc
@@ -19,8 +19,6 @@ namespace explore_sites { namespace { -const int kFaviconsPerCategoryImage = 4; - // Ratio of icon size to the amount of padding between the icons. const int kIconPaddingScale = 8; } // namespace
diff --git a/chrome/browser/background_fetch/background_fetch_delegate_impl.cc b/chrome/browser/background_fetch/background_fetch_delegate_impl.cc index 2b7c5a6..04e30297 100644 --- a/chrome/browser/background_fetch/background_fetch_delegate_impl.cc +++ b/chrome/browser/background_fetch/background_fetch_delegate_impl.cc
@@ -77,10 +77,12 @@ std::unique_ptr<content::BackgroundFetchDescription> fetch_description, const std::string& provider_namespace, bool is_off_the_record) - : paused(fetch_description->start_paused), - offline_item(offline_items_collection::ContentId( + : offline_item(offline_items_collection::ContentId( provider_namespace, fetch_description->job_unique_id)), + job_state(fetch_description->start_paused + ? State::kPendingWillStartPaused + : State::kPendingWillStartDownloading), fetch_description(std::move(fetch_description)) { offline_item.is_off_the_record = is_off_the_record; offline_item.original_url = this->fetch_description->origin.GetURL(); @@ -89,6 +91,13 @@ BackgroundFetchDelegateImpl::JobDetails::~JobDetails() = default; +void BackgroundFetchDelegateImpl::JobDetails::MarkJobAsStarted() { + if (job_state == State::kPendingWillStartDownloading) + job_state = State::kStartedAndDownloading; + else if (job_state == State::kPendingWillStartPaused) + job_state = State::kStartedButPaused; +} + void BackgroundFetchDelegateImpl::JobDetails::UpdateOfflineItem() { DCHECK_GT(fetch_description->total_parts, 0); @@ -115,7 +124,7 @@ offline_item.is_resumable = true; using OfflineItemState = offline_items_collection::OfflineItemState; - if (cancelled) { + if (job_state == State::kCancelled) { offline_item.state = OfflineItemState::CANCELLED; } else if (fetch_description->completed_parts == fetch_description->total_parts) { @@ -123,7 +132,7 @@ // response was an HTTP error, e.g. 404. offline_item.state = OfflineItemState::COMPLETE; offline_item.is_openable = true; - } else if (started && paused) { + } else if (job_state == State::kStartedButPaused) { offline_item.state = OfflineItemState::PAUSED; } else { offline_item.state = OfflineItemState::IN_PROGRESS; @@ -263,14 +272,16 @@ JobDetails& job_details = job_details_map_.find(job_unique_id)->second; - if (!job_details.started) { + if (job_details.job_state == JobDetails::State::kPendingWillStartPaused || + job_details.job_state == + JobDetails::State::kPendingWillStartDownloading) { // Create a notification. for (auto* observer : observers_) observer->OnItemsAdded({job_details.offline_item}); - job_details.started = true; + job_details.MarkJobAsStarted(); } - if (job_details.paused) { + if (job_details.job_state == JobDetails::State::kStartedButPaused) { job_details.on_resume = base::BindOnce(&BackgroundFetchDelegateImpl::StartDownload, GetWeakPtr(), job_unique_id, params); @@ -298,7 +309,7 @@ return; JobDetails& job_details = job_details_iter->second; - job_details.cancelled = true; + job_details.job_state = JobDetails::State::kCancelled; for (const auto& download_guid : job_details.current_download_guids) { GetDownloadService()->CancelDownload(download_guid); @@ -331,6 +342,10 @@ } UpdateOfflineItemAndUpdateObservers(&job_details); + + // UpdateUI() can only be called once, and only when the background fetch + // has succeeded or failed, so we can delete |job_details| now. + job_details_map_.erase(job_details_iter); } void BackgroundFetchDelegateImpl::OnDownloadStarted( @@ -541,7 +556,7 @@ return; JobDetails& job_details = job_details_iter->second; - job_details.paused = true; + job_details.job_state = JobDetails::State::kStartedButPaused; for (auto& download_guid : job_details.current_download_guids) GetDownloadService()->PauseDownload(download_guid); } @@ -554,7 +569,7 @@ return; JobDetails& job_details = job_details_iter->second; - job_details.paused = false; + job_details.job_state = JobDetails::State::kStartedAndDownloading; for (auto& download_guid : job_details.current_download_guids) GetDownloadService()->ResumeDownload(download_guid); @@ -645,7 +660,7 @@ DCHECK(job_details_map_.find(unique_id) != job_details_map_.end()); JobDetails& job_details = job_details_map_.find(unique_id)->second; - job_details.paused = true; + job_details.job_state = JobDetails::State::kStartedButPaused; UpdateOfflineItemAndUpdateObservers(&job_details); } @@ -657,7 +672,7 @@ // If the job is loaded at this point, then it already started // in a previous session. - job_details.started = true; + job_details.MarkJobAsStarted(); std::vector<std::string>& job_outstanding_guids = job_details.fetch_description->outstanding_guids;
diff --git a/chrome/browser/background_fetch/background_fetch_delegate_impl.h b/chrome/browser/background_fetch/background_fetch_delegate_impl.h index 15aed432..ab79b32 100644 --- a/chrome/browser/background_fetch/background_fetch_delegate_impl.h +++ b/chrome/browser/background_fetch/background_fetch_delegate_impl.h
@@ -123,6 +123,16 @@ private: struct JobDetails { + // If a job is part of the |job_details_map_|, it will have one of these + // states. + enum class State { + kPendingWillStartPaused, + kPendingWillStartDownloading, + kStartedButPaused, + kStartedAndDownloading, + kCancelled, + }; + JobDetails(JobDetails&&); JobDetails( std::unique_ptr<content::BackgroundFetchDescription> fetch_description, @@ -131,10 +141,7 @@ ~JobDetails(); void UpdateOfflineItem(); - - bool started = false; - bool cancelled = false; - bool paused = false; + void MarkJobAsStarted(); // Set of DownloadService GUIDs that are currently downloading. They are // added by DownloadUrl and are removed when the download completes, fails @@ -142,6 +149,7 @@ base::flat_set<std::string> current_download_guids; offline_items_collection::OfflineItem offline_item; + State job_state; std::unique_ptr<content::BackgroundFetchDescription> fetch_description; base::OnceClosure on_resume;
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 39860bc..523debb 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -65,6 +65,8 @@ <structure name="IDR_WELCOME_ONBOARDING_WELCOME_LANDING_VIEW_JS" file="resources\welcome\onboarding_welcome\landing_view.js" type="chrome_html" preprocess="true"/> <structure name="IDR_WELCOME_ONBOARDING_WELCOME_NAVIGATION_BEHAVIOR_HTML" file="resources\welcome\onboarding_welcome\navigation_behavior.html" type="chrome_html" preprocess="true"/> <structure name="IDR_WELCOME_ONBOARDING_WELCOME_NAVIGATION_BEHAVIOR_JS" file="resources\welcome\onboarding_welcome\navigation_behavior.js" type="chrome_html" preprocess="true"/> + <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SIGNIN_VIEW_HTML" file="resources\welcome\onboarding_welcome\signin_view.html" type="chrome_html" preprocess="true"/> + <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SIGNIN_VIEW_JS" file="resources\welcome\onboarding_welcome\signin_view.js" type="chrome_html" preprocess="true"/> <structure name="IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_APP_HTML" file="resources\welcome\onboarding_welcome\welcome_app.html" type="chrome_html" preprocess="true"/> <structure name="IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_APP_JS" file="resources\welcome\onboarding_welcome\welcome_app.js" type="chrome_html" preprocess="true"/> <structure name="IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_BROWSER_PROXY_HTML" file="resources\welcome\onboarding_welcome\welcome_browser_proxy.html" type="chrome_html"/> @@ -88,7 +90,11 @@ <structure name="IDR_NUX_SET_AS_DEFAULT_JS" file="resources\welcome\onboarding_welcome\set_as_default\nux_set_as_default.js" type="chrome_html" /> <structure name="IDR_NUX_SET_AS_DEFAULT_PROXY_HTML" file="resources\welcome\onboarding_welcome\set_as_default\nux_set_as_default_proxy.html" type="chrome_html" /> <structure name="IDR_NUX_SET_AS_DEFAULT_PROXY_JS" file="resources\welcome\onboarding_welcome\set_as_default\nux_set_as_default_proxy.js" type="chrome_html" /> - <structure name="IDR_NUX_CHOOSER_SHARED_CSS" file="resources\welcome\onboarding_welcome\shared\chooser_shared_css.html" type="chrome_html" /> + <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ACTION_LINK_STYLE_JS" file="resources\welcome\onboarding_welcome\shared\action_link_style.js" type="chrome_html" /> + <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ACTION_LINK_STYLE_CSS_HTML" file="resources\welcome\onboarding_welcome\shared\action_link_style_css.html" type="chrome_html" /> + <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ONBOARDING_BACKGROUND_HTML" file="resources\welcome\onboarding_welcome\shared\onboarding_background.html" type="chrome_html" /> + <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ONBOARDING_BACKGROUND_JS" file="resources\welcome\onboarding_welcome\shared\onboarding_background.js" type="chrome_html" /> + <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_CHOOSER_SHARED_CSS" file="resources\welcome\onboarding_welcome\shared\chooser_shared_css.html" type="chrome_html" /> <structure name="IDR_WELCOME_ONBOARDING_WELCOME_SHARED_I18N_SETUP_HTML" file="resources\welcome\onboarding_welcome\shared\i18n_setup.html" type="chrome_html" /> </if> <if expr="is_win"> @@ -715,6 +721,13 @@ <include name="IDR_NUX_GOOGLE_APPS_TRANSLATE_2X" file="resources\welcome\onboarding_welcome\images\translate_2x.png" type="BINDATA" /> <include name="IDR_NUX_GOOGLE_APPS_YOUTUBE_1X" file="resources\welcome\onboarding_welcome\images\youtube_1x.png" type="BINDATA" /> <include name="IDR_NUX_GOOGLE_APPS_YOUTUBE_2X" file="resources\welcome\onboarding_welcome\images\youtube_2x.png" type="BINDATA" /> + <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_BLUE_CIRCLE_SVG" file="resources\welcome\onboarding_welcome\images\background_svgs\blue_circle.svg" type="BINDATA" /> + <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_GREEN_RECTANGLE_SVG" file="resources\welcome\onboarding_welcome\images\background_svgs\green_rectangle.svg" type="BINDATA" /> + <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_GREY_OVAL_SVG" file="resources\welcome\onboarding_welcome\images\background_svgs\grey_oval.svg" type="BINDATA" /> + <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_GREY_ROUNDED_RECTANGLE_SVG" file="resources\welcome\onboarding_welcome\images\background_svgs\grey_rounded_rectangle.svg" type="BINDATA" /> + <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_RED_TRIANGLE_SVG" file="resources\welcome\onboarding_welcome\images\background_svgs\red_triangle.svg" type="BINDATA" /> + <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_YELLOW_DOTS_SVG" file="resources\welcome\onboarding_welcome\images\background_svgs\yellow_dots.svg" type="BINDATA" /> + <include name="IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_YELLOW_SEMICIRCLE_SVG" file="resources\welcome\onboarding_welcome\images\background_svgs\yellow_semicircle.svg" type="BINDATA" /> </if> <if expr="is_win"> <include name="IDR_WELCOME_WIN10_DEFAULT_WEBP" file="resources\welcome\default.webp" type="BINDATA" />
diff --git a/chrome/browser/cached_image_fetcher/cached_image_fetcher_service_factory.cc b/chrome/browser/cached_image_fetcher/cached_image_fetcher_service_factory.cc new file mode 100644 index 0000000..449628b --- /dev/null +++ b/chrome/browser/cached_image_fetcher/cached_image_fetcher_service_factory.cc
@@ -0,0 +1,109 @@ +// Copyright 2018 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/cached_image_fetcher/cached_image_fetcher_service_factory.h" + +#include <memory> +#include <utility> + +#include "base/files/file_path.h" +#include "base/sequenced_task_runner.h" +#include "base/task/post_task.h" +#include "base/time/default_clock.h" +#include "build/build_config.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/search/suggestions/image_decoder_impl.h" +#include "components/image_fetcher/core/cached_image_fetcher_service.h" +#include "components/image_fetcher/core/storage/image_cache.h" +#include "components/image_fetcher/core/storage/image_data_store_disk.h" +#include "components/image_fetcher/core/storage/image_metadata_store_leveldb.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/storage_partition.h" + +#if defined(OS_ANDROID) +#include "base/path_service.h" +#endif + +namespace image_fetcher { + +namespace { + +// The path under the browser context's data directory which the image_cache +// will be stored. +const base::FilePath::CharType kImageCacheSubdir[] = + FILE_PATH_LITERAL("image_cache"); + +std::unique_ptr<ImageDecoder> CreateImageDecoderImpl() { + return std::make_unique<suggestions::ImageDecoderImpl>(); +} + +} // namespace + +CachedImageFetcherService* +CachedImageFetcherServiceFactory::GetForBrowserContext( + content::BrowserContext* context) { + return static_cast<CachedImageFetcherService*>( + GetInstance()->GetServiceForBrowserContext(context, true)); +} + +CachedImageFetcherServiceFactory* +CachedImageFetcherServiceFactory::GetInstance() { + return base::Singleton<CachedImageFetcherServiceFactory>::get(); +} + +CachedImageFetcherServiceFactory::CachedImageFetcherServiceFactory() + : BrowserContextKeyedServiceFactory( + "CachedImageFetcherService", + BrowserContextDependencyManager::GetInstance()) {} + +CachedImageFetcherServiceFactory::~CachedImageFetcherServiceFactory() = default; + +KeyedService* CachedImageFetcherServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + base::FilePath cache_path; +#if defined(OS_ANDROID) + // On Android, get a special cache directory that is cleared under pressure. + // The subdirectory under needs to be registered file_paths.xml as well. + if (base::PathService::Get(base::DIR_CACHE, &cache_path)) { + cache_path = cache_path.Append(kImageCacheSubdir); + } +#else + // On other platforms, GetCachePath can be cleared by the user. + cache_path = context->GetCachePath().Append(kImageCacheSubdir); +#endif + + scoped_refptr<base::SequencedTaskRunner> task_runner = + base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE}); + base::DefaultClock* clock = base::DefaultClock::GetInstance(); + + auto metadata_store = std::make_unique<ImageMetadataStoreLevelDB>( + cache_path, task_runner, clock); + auto data_store = + std::make_unique<ImageDataStoreDisk>(cache_path, task_runner); + + Profile* profile = Profile::FromBrowserContext(context); + // TODO(wylieb): Start in read-only mode if user is incognito. + scoped_refptr<ImageCache> image_cache = base::MakeRefCounted<ImageCache>( + std::move(data_store), std::move(metadata_store), profile->GetPrefs(), + clock, task_runner); + + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory = + content::BrowserContext::GetDefaultStoragePartition(profile) + ->GetURLLoaderFactoryForBrowserProcess(); + + return new CachedImageFetcherService( + base::BindRepeating(CreateImageDecoderImpl), + std::move(url_loader_factory), std::move(image_cache)); +} + +content::BrowserContext* +CachedImageFetcherServiceFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + // Return different BrowserContexts for regular/incognito. + return context; +} + +} // namespace image_fetcher
diff --git a/chrome/browser/cached_image_fetcher/cached_image_fetcher_service_factory.h b/chrome/browser/cached_image_fetcher/cached_image_fetcher_service_factory.h new file mode 100644 index 0000000..90c95f5 --- /dev/null +++ b/chrome/browser/cached_image_fetcher/cached_image_fetcher_service_factory.h
@@ -0,0 +1,45 @@ +// Copyright 2018 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_CACHED_IMAGE_FETCHER_CACHED_IMAGE_FETCHER_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_CACHED_IMAGE_FETCHER_CACHED_IMAGE_FETCHER_SERVICE_FACTORY_H_ + +#include "base/macros.h" +#include "base/memory/singleton.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace content { +class BrowserContext; +} // namespace content + +namespace image_fetcher { + +class CachedImageFetcherService; + +// Factory to create one CachedImageFetcherService per browser context. +class CachedImageFetcherServiceFactory + : public BrowserContextKeyedServiceFactory { + public: + static CachedImageFetcherService* GetForBrowserContext( + content::BrowserContext* context); + static CachedImageFetcherServiceFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits<CachedImageFetcherServiceFactory>; + + CachedImageFetcherServiceFactory(); + ~CachedImageFetcherServiceFactory() override; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; + + DISALLOW_COPY_AND_ASSIGN(CachedImageFetcherServiceFactory); +}; + +} // namespace image_fetcher + +#endif // CHROME_BROWSER_CACHED_IMAGE_FETCHER_CACHED_IMAGE_FETCHER_SERVICE_FACTORY_H_
diff --git a/chrome/browser/chrome_main_browsertest.cc b/chrome/browser/chrome_main_browsertest.cc index 6b9a6cc675..532a766 100644 --- a/chrome/browser/chrome_main_browsertest.cc +++ b/chrome/browser/chrome_main_browsertest.cc
@@ -88,17 +88,18 @@ } IN_PROC_BROWSER_TEST_F(ChromeMainTest, SecondLaunchFromIncognitoWithNormalUrl) { + Profile* const profile = browser()->profile(); + // We should start with one normal window. - ASSERT_EQ(1u, chrome::GetTabbedBrowserCount(browser()->profile())); + ASSERT_EQ(1u, chrome::GetTabbedBrowserCount(profile)); // Create an incognito window. - chrome::NewIncognitoWindow(browser()); + chrome::NewIncognitoWindow(profile); ASSERT_EQ(2u, chrome::GetTotalBrowserCount()); - ASSERT_EQ(1u, chrome::GetTabbedBrowserCount(browser()->profile())); + ASSERT_EQ(1u, chrome::GetTabbedBrowserCount(profile)); // Close the first window. - Profile* profile = browser()->profile(); CloseBrowserSynchronously(browser()); // There should only be the incognito window open now.
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.cc index 7e45325..4f36cdd 100644 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.cc +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.cc
@@ -77,9 +77,9 @@ std::move(event)); } -void SpokenFeedbackEventRewriterDelegate::HandleKeyboardEvent( +bool SpokenFeedbackEventRewriterDelegate::HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { - OnUnhandledSpokenFeedbackEvent( - ui::Event::Clone(*static_cast<ui::Event*>(event.os_event))); + OnUnhandledSpokenFeedbackEvent(ui::Event::Clone(*event.os_event)); + return true; }
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.h b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.h index c05d51f12..5faa894 100644 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.h +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.h
@@ -35,7 +35,7 @@ void OnUnhandledSpokenFeedbackEvent(std::unique_ptr<ui::Event> event) const; // WebContentsDelegate: - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override;
diff --git a/chrome/browser/chromeos/arc/arc_util.cc b/chrome/browser/chromeos/arc/arc_util.cc index 81dc64b..66a4d9a 100644 --- a/chrome/browser/chromeos/arc/arc_util.cc +++ b/chrome/browser/chromeos/arc/arc_util.cc
@@ -708,9 +708,15 @@ } bool IsPlayStoreAvailable() { - return (!IsRobotOrOfflineDemoAccountMode() || - chromeos::DemoSession::IsDeviceInDemoMode()) && - !ShouldArcAlwaysStartWithNoPlayStore(); + if (ShouldArcAlwaysStartWithNoPlayStore()) + return false; + + if (!IsRobotOrOfflineDemoAccountMode()) + return true; + + // Demo Mode is the only public session scenario that can launch Play. + return chromeos::DemoSession::IsDeviceInDemoMode() && + chromeos::switches::ShouldShowPlayStoreInDemoMode(); } } // namespace arc
diff --git a/chrome/browser/chromeos/arc/arc_util_unittest.cc b/chrome/browser/chromeos/arc/arc_util_unittest.cc index c92da713..9c1c989 100644 --- a/chrome/browser/chromeos/arc/arc_util_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_util_unittest.cc
@@ -861,6 +861,18 @@ ScopedLogIn login(GetFakeUserManager(), AccountId::FromUserEmail("public_user@gmail.com"), user_manager::USER_TYPE_PUBLIC_ACCOUNT); + EXPECT_FALSE(IsPlayStoreAvailable()); +} + +TEST_F(ChromeArcUtilTest, ArcStartModeDefaultDemoModeWithPlayStore) { + auto* command_line = base::CommandLine::ForCurrentProcess(); + command_line->InitFromArgv( + {"", "--arc-availability=installed", "--show-play-in-demo-mode"}); + chromeos::DemoSession::SetDemoConfigForTesting( + chromeos::DemoSession::DemoModeConfig::kOnline); + ScopedLogIn login(GetFakeUserManager(), + AccountId::FromUserEmail("public_user@gmail.com"), + user_manager::USER_TYPE_PUBLIC_ACCOUNT); EXPECT_TRUE(IsPlayStoreAvailable()); }
diff --git a/chrome/browser/chromeos/drive/drive_integration_service.cc b/chrome/browser/chromeos/drive/drive_integration_service.cc index 42726e5..7403b5ed 100644 --- a/chrome/browser/chromeos/drive/drive_integration_service.cc +++ b/chrome/browser/chromeos/drive/drive_integration_service.cc
@@ -422,9 +422,7 @@ // network::NetworkConnectionTracker::NetworkConnectionObserver void OnConnectionChanged(network::mojom::ConnectionType type) override { - bool is_offline = - type == network::mojom::ConnectionType::CONNECTION_UNKNOWN || - type == network::mojom::ConnectionType::CONNECTION_NONE; + bool is_offline = type == network::mojom::ConnectionType::CONNECTION_NONE; // Check for a pending remount first. In this case, DriveFS will not be // mounted and thus its interface will be null. if (integration_service_->drivefs_holder_ &&
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.cc index 05676ac..772d7bb 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.cc +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_service.cc
@@ -363,7 +363,7 @@ if (state == ScreenlockState::AUTHENTICATED) { if (power_monitor_) power_monitor_->RecordStartUpTime(); - } else if (auth_attempt_.get()) { + } else if (auth_attempt_) { // Clean up existing auth attempt if we can no longer authenticate the // remote device. auth_attempt_.reset(); @@ -381,8 +381,13 @@ const EasyUnlockAuthAttempt::Type auth_attempt_type = GetType() == TYPE_REGULAR ? EasyUnlockAuthAttempt::TYPE_UNLOCK : EasyUnlockAuthAttempt::TYPE_SIGNIN; + if (auth_attempt_) { + PA_LOG(INFO) << "Already attempting auth, skipping this request."; + return; + } + if (!GetAccountId().is_valid()) { - LOG(ERROR) << "Empty user account. Refresh token might go bad."; + PA_LOG(ERROR) << "Empty user account. Auth attempt failed."; return; } @@ -403,7 +408,7 @@ } void EasyUnlockService::FinalizeUnlock(bool success) { - if (!auth_attempt_.get()) + if (!auth_attempt_) return; this->OnWillFinalizeUnlock(success); @@ -421,8 +426,9 @@ } void EasyUnlockService::FinalizeSignin(const std::string& key) { - if (!auth_attempt_.get()) + if (!auth_attempt_) return; + std::string wrapped_secret = GetWrappedSecret(); if (!wrapped_secret.empty()) auth_attempt_->FinalizeSignin(GetAccountId(), wrapped_secret, key);
diff --git a/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc b/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc index b3d542d..5645cbba 100644 --- a/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc +++ b/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc
@@ -321,10 +321,10 @@ return true; } -void OobeUIDialogDelegate::HandleKeyboardEvent( +bool OobeUIDialogDelegate::HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { - unhandled_keyboard_event_handler_.HandleKeyboardEvent( + return unhandled_keyboard_event_handler_.HandleKeyboardEvent( event, dialog_widget_->GetFocusManager()); }
diff --git a/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.h b/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.h index 37627e3..9fecf38b 100644 --- a/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.h +++ b/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.h
@@ -94,7 +94,7 @@ // content::WebContentsDelegate: bool TakeFocus(content::WebContents* source, bool reverse) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override;
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.cc b/chrome/browser/chromeos/login/ui/webui_login_view.cc index 78a826a7..1d80fca 100644 --- a/chrome/browser/chromeos/login/ui/webui_login_view.cc +++ b/chrome/browser/chromeos/login/ui/webui_login_view.cc
@@ -453,15 +453,16 @@ #endif } -void WebUILoginView::HandleKeyboardEvent(content::WebContents* source, +bool WebUILoginView::HandleKeyboardEvent(content::WebContents* source, const NativeWebKeyboardEvent& event) { + bool handled = false; if (forward_keyboard_event_) { // Disable arrow key traversal because arrow keys are handled via // accelerator when this view has focus. ScopedArrowKeyTraversal arrow_key_traversal(false); - unhandled_keyboard_event_handler_.HandleKeyboardEvent(event, - GetFocusManager()); + handled = unhandled_keyboard_event_handler_.HandleKeyboardEvent( + event, GetFocusManager()); } // Make sure error bubble is cleared on keyboard event. This is needed @@ -472,6 +473,7 @@ if (web_ui) web_ui->CallJavascriptFunctionUnsafe("cr.ui.Oobe.clearErrors"); } + return handled; } bool WebUILoginView::TakeFocus(content::WebContents* source, bool reverse) {
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.h b/chrome/browser/chromeos/login/ui/webui_login_view.h index 887b23c..9e803fa 100644 --- a/chrome/browser/chromeos/login/ui/webui_login_view.h +++ b/chrome/browser/chromeos/login/ui/webui_login_view.h
@@ -150,7 +150,7 @@ // Overridden from content::WebContentsDelegate. bool HandleContextMenu(const content::ContextMenuParams& params) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; bool TakeFocus(content::WebContents* source, bool reverse) override;
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/modeller.h b/chrome/browser/chromeos/power/auto_screen_brightness/modeller.h index b61fada1..07070f9 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/modeller.h +++ b/chrome/browser/chromeos/power/auto_screen_brightness/modeller.h
@@ -6,7 +6,8 @@ #define CHROME_BROWSER_CHROMEOS_POWER_AUTO_SCREEN_BRIGHTNESS_MODELLER_H_ #include "base/observer_list_types.h" -#include "chrome/browser/chromeos/power/auto_screen_brightness/trainer.h" +#include "base/optional.h" +#include "chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline.h" namespace chromeos { namespace power { @@ -32,14 +33,15 @@ ~Observer() override = default; // Called when a new curve (|brightness_curve|) is trained. - virtual void OnModelTrained(const BrightnessCurve& brightness_curve) = 0; + virtual void OnModelTrained( + const MonotoneCubicSpline& brightness_curve) = 0; // Called when the model is initialized. Observers will be notified about // both model status and initial curve (|brightness_curve|). If model status - // is |kDisabled|, the |brightness_curve| will be empty. + // is |kDisabled|, the |brightness_curve| will be a nullopt. virtual void OnModelInitialized( Status model_status, - const BrightnessCurve& brightness_curve) = 0; + const base::Optional<MonotoneCubicSpline>& brightness_curve) = 0; private: DISALLOW_COPY_AND_ASSIGN(Observer);
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.cc b/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.cc index 071bac68..0c46567c 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.cc +++ b/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.cc
@@ -26,33 +26,48 @@ namespace auto_screen_brightness { namespace { -// Loads data from a specified location on disk. This should run in another + +// Creates a global/default brightness curve. +// TODO(crbug.com/881215): add actual default curve and then add unit test too. +// TODO(crbug.com/881215): add param flag to allow for experiments. +MonotoneCubicSpline CreateGlobalCurve() { + const std::vector<double> default_log_lux = {0, 100}; + const std::vector<double> default_brightness = {50, 100}; + return MonotoneCubicSpline(default_log_lux, default_brightness); +} + +// Loads curve from a specified location on disk. This should run in another // thread to be non-blocking to the main thread (if |is_testing| is false). -std::string LoadDataFromDisk(const base::FilePath& path, bool is_testing) { +// The ambient values read from disk should be in the log-domain already. +base::Optional<MonotoneCubicSpline> LoadCurveFromDisk( + const base::FilePath& path, + bool is_testing) { DCHECK(is_testing || !content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); if (!PathExists(path)) { - return ""; + return base::nullopt; } std::string content; - if (!base::ReadFileToString(path, &content)) { - return ""; + if (!base::ReadFileToString(path, &content) || content.empty()) { + return base::nullopt; } - return content; + + return MonotoneCubicSpline::FromString(content); } -// Saves data to disk. This should run in another thread to be non-blocking to -// the main thread (if |is_testing| is false). +// Saves |curve| to disk. This should run in another thread to be non-blocking +// to the main thread (if |is_testing| is false). // TODO(jiameng): alternative to WriteFile is WriteFileAtomically, but the // latter is very slow. Investigate whether we need to change to // WriteFileAtomically. void SaveCurveToDisk(const base::FilePath& path, - const BrightnessCurve& curve, + const MonotoneCubicSpline& curve, bool is_testing) { DCHECK(is_testing || !content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - const std::string data = CurveToString(curve); + const std::string data = curve.ToString(); + DCHECK(!data.empty()); const int bytes_written = base::WriteFile(path, data.data(), data.size()); if (bytes_written != static_cast<int>(data.size())) { LOG(ERROR) << "Wrote " << bytes_written << " byte(s) instead of " @@ -60,22 +75,24 @@ } } -// Trains a new curve using the current |curve| and training |data|. Returns the -// new curve. This should run in another thread to be non-blocking to the main +// Trains a new curve using training |data| and returns the new curve. This +// should only be called after trainer has been initialized with a global curve +// and a latest curve. +// This should run in another thread to be non-blocking to the main // thread (if |is_testing| is false). -BrightnessCurve TrainModel(Trainer* trainer, - const BrightnessCurve& curve, - const std::vector<TrainingDataPoint>& data, - bool is_testing) { +MonotoneCubicSpline TrainModel(Trainer* trainer, + const std::vector<TrainingDataPoint>& data, + bool is_testing) { DCHECK(is_testing || !content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - return trainer->Train(curve, data); + return trainer->Train(data); } } // namespace constexpr base::TimeDelta ModellerImpl::kTrainingDelay; -constexpr int ModellerImpl::kMaxTrainingDataPoints; +constexpr size_t ModellerImpl::kMaxTrainingDataPoints; +constexpr size_t ModellerImpl::kMinTrainingDataPoints; constexpr int ModellerImpl::kAmbientLightHorizonSeconds; constexpr base::TimeDelta ModellerImpl::kAmbientLightHorizon; constexpr int ModellerImpl::kNumberAmbientValuesToTrack; @@ -103,7 +120,7 @@ DCHECK(observer); observers_.AddObserver(observer); if (model_status_ != Modeller::Status::kInitializing) { - observer->OnModelInitialized(model_status_, curve_); + observer->OnModelInitialized(model_status_, current_curve_); } } @@ -148,7 +165,8 @@ const double average_ambient_lux = AverageAmbient(ambient_light_values_, -1); data_cache_.push_back({old_brightness_percent, new_brightness_percent, - average_ambient_lux, tick_clock_->NowTicks()}); + ConvertToLog(average_ambient_lux), + tick_clock_->NowTicks()}); if (data_cache_.size() == kMaxTrainingDataPoints) { model_timer_.Stop(); @@ -181,7 +199,7 @@ return AverageAmbient(ambient_light_values_, -1); } -int ModellerImpl::NumberTrainingDataPointsForTesting() const { +size_t ModellerImpl::NumberTrainingDataPointsForTesting() const { return data_cache_.size(); } @@ -189,6 +207,10 @@ return GetCurvePathFromProfile(profile); } +MonotoneCubicSpline ModellerImpl::GetGlobalCurveForTesting() const { + return global_curve_; +} + ModellerImpl::ModellerImpl( Profile* profile, AlsReader* als_reader, @@ -207,6 +229,7 @@ base::OnTaskRunnerDeleter(model_task_runner_)), tick_clock_(tick_clock), model_timer_(tick_clock_), + global_curve_(CreateGlobalCurve()), weak_ptr_factory_(this) { DCHECK(als_reader); DCHECK(brightness_monitor); @@ -274,7 +297,7 @@ base::PostTaskAndReplyWithResult( model_task_runner_.get(), FROM_HERE, - base::BindOnce(&LoadDataFromDisk, curve_path_, is_testing_), + base::BindOnce(&LoadCurveFromDisk, curve_path_, is_testing_), base::BindOnce(&ModellerImpl::OnCurveLoadedFromDisk, weak_ptr_factory_.GetWeakPtr())); } @@ -282,25 +305,22 @@ void ModellerImpl::OnInitializationComplete() { DCHECK_NE(model_status_, Status::kInitializing); for (auto& observer : observers_) - observer.OnModelInitialized(model_status_, curve_); + observer.OnModelInitialized(model_status_, current_curve_); } -// TODO(crbug.com/881215): add actual default curve and then add unit test too. -void ModellerImpl::InitWithDefaultCurve() { - curve_.clear(); - return; -} - -void ModellerImpl::OnCurveLoadedFromDisk(const std::string& content) { - if (content.empty() || !CurveFromString(content, &curve_)) { - InitWithDefaultCurve(); +void ModellerImpl::OnCurveLoadedFromDisk( + const base::Optional<MonotoneCubicSpline>& curve) { + if (!curve.has_value()) { + current_curve_.emplace(global_curve_); model_status_ = Status::kGlobal; } else { + current_curve_.emplace(curve.value()); model_status_ = Status::kPersonal; } OnInitializationComplete(); + trainer_->SetInitialCurves(global_curve_, current_curve_.value()); ScheduleTrainerStart(); } @@ -311,28 +331,28 @@ } void ModellerImpl::StartTraining() { - if (data_cache_.empty()) { + if (data_cache_.size() < kMinTrainingDataPoints) { ScheduleTrainerStart(); return; } base::PostTaskAndReplyWithResult( model_task_runner_.get(), FROM_HERE, - base::BindOnce(&TrainModel, trainer_.get(), curve_, - std::move(data_cache_), is_testing_), + base::BindOnce(&TrainModel, trainer_.get(), std::move(data_cache_), + is_testing_), base::BindOnce(&ModellerImpl::OnTrainingFinished, weak_ptr_factory_.GetWeakPtr())); data_cache_.clear(); } -void ModellerImpl::OnTrainingFinished(const BrightnessCurve& curve) { - curve_ = curve; +void ModellerImpl::OnTrainingFinished(const MonotoneCubicSpline& curve) { + current_curve_.emplace(curve); for (auto& observer : observers_) observer.OnModelTrained(curve); model_task_runner_->PostTask( FROM_HERE, - base::BindOnce(&SaveCurveToDisk, curve_path_, curve_, is_testing_)); + base::BindOnce(&SaveCurveToDisk, curve_path_, curve, is_testing_)); ScheduleTrainerStart(); }
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.h b/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.h index 50d3a16..35c4443 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.h +++ b/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl.h
@@ -44,7 +44,11 @@ // If number of recorded training data has reached |kMaxTrainingDataPoints| we // start training immediately, without waiting for user to become idle for // |kTrainingDelay|. - static constexpr int kMaxTrainingDataPoints = 100; + static constexpr size_t kMaxTrainingDataPoints = 100; + + // Only train when there are at least |kMinTrainingDataPoints| training data + // points. + static constexpr size_t kMinTrainingDataPoints = 10; // TODO(jiameng): we currently use past 10 seconds of ambient values to // calculate average. May revise. @@ -99,11 +103,13 @@ // Current number of training data points stored, which will be used for next // training. - int NumberTrainingDataPointsForTesting() const; + size_t NumberTrainingDataPointsForTesting() const; // Calls GetCurvePathFromProfile directly. base::FilePath GetCurvePathForTesting(Profile* profile) const; + MonotoneCubicSpline GetGlobalCurveForTesting() const; + private: // ModellerImpl has weak dependencies on all parameters except |trainer|. ModellerImpl(Profile* profile, @@ -138,12 +144,11 @@ // |model_status_| is not |kInitializing|. void OnInitializationComplete(); - // Called when there is no saved curve from the disk. - void InitWithDefaultCurve(); - - // Called after reading from disk is complete. |content| may be empty, in that - // case we'll construct a default curve. - void OnCurveLoadedFromDisk(const std::string& content); + // Called after we've attempted to construct a |curve| from data saved on + // disk. |curve| will be assigned to |current_curve_| if |curve| is not + // nullopt. Otherwise, |current_curve_| will have the same value as + // |global_curve_|. + void OnCurveLoadedFromDisk(const base::Optional<MonotoneCubicSpline>& curve); // Starts |model_timer_| to start training after certain inactivity period. void ScheduleTrainerStart(); @@ -153,7 +158,7 @@ void StartTraining(); // Called after training is complete with a new curve. - void OnTrainingFinished(const BrightnessCurve& curve); + void OnTrainingFinished(const MonotoneCubicSpline& curve); // If |is_testing_| is false, we check curve saving/loading and training jobs // are running on non-UI thread. @@ -182,7 +187,10 @@ base::FilePath curve_path_; // Latest trained curve. - BrightnessCurve curve_; + base::Optional<MonotoneCubicSpline> current_curve_; + + // Global curve constructed from predefined params. + const MonotoneCubicSpline global_curve_; // Recent |kNumberAmbientValuesToTrack| ambient values. base::RingBuffer<AmbientLightSample, kNumberAmbientValuesToTrack>
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl_unittest.cc b/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl_unittest.cc index b84454c..970a76a 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl_unittest.cc +++ b/chrome/browser/chromeos/power/auto_screen_brightness/modeller_impl_unittest.cc
@@ -14,6 +14,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/chromeos/power/auto_screen_brightness/fake_als_reader.h" #include "chrome/browser/chromeos/power/auto_screen_brightness/fake_brightness_monitor.h" +#include "chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline.h" #include "chrome/browser/chromeos/power/auto_screen_brightness/trainer.h" #include "chrome/browser/chromeos/power/auto_screen_brightness/utils.h" #include "chrome/test/base/testing_profile.h" @@ -29,18 +30,23 @@ namespace { -void CompareBrightnessCurve(const BrightnessCurve& expected, - const BrightnessCurve& actual) { - EXPECT_EQ(expected.size(), actual.size()); - for (size_t i = 0; i < expected.size(); ++i) { - EXPECT_DOUBLE_EQ(expected[i].first, actual[i].first); - EXPECT_DOUBLE_EQ(expected[i].second, actual[i].second); - } -} +MonotoneCubicSpline CreateTestCurveFromTrainingData( + const std::vector<TrainingDataPoint>& data) { + CHECK_GT(data.size(), 1u); -std::pair<double, double> DataToCurvePoint(const TrainingDataPoint& data) { - return std::make_pair(data.ambient_lux, - (data.brightness_old + data.brightness_new) / 2); + std::vector<double> xs; + std::vector<double> ys; + + const auto& data_point = data[0]; + xs.push_back(data_point.ambient_log_lux); + ys.push_back((data_point.brightness_old + data_point.brightness_new) / 2); + + for (size_t i = 1; i < data.size(); ++i) { + xs.push_back(xs[i - 1] + 1); + ys.push_back(ys[i - 1] + 1); + } + + return MonotoneCubicSpline(xs, ys); } // Testing trainer. @@ -50,16 +56,26 @@ ~FakeTrainer() override = default; // Trainer overrides: - BrightnessCurve Train(const BrightnessCurve& /* curve */, - const std::vector<TrainingDataPoint>& data) override { - BrightnessCurve result_curve; - for (const auto& training_data_point : data) { - result_curve.push_back(DataToCurvePoint(training_data_point)); - } - return result_curve; + void SetInitialCurves(const MonotoneCubicSpline& global_curve, + const MonotoneCubicSpline& current_curve) override { + CHECK(!global_curve_.has_value()); + CHECK(!current_curve_.has_value()); + + global_curve_.emplace(global_curve); + current_curve_.emplace(current_curve); + } + + MonotoneCubicSpline Train( + const std::vector<TrainingDataPoint>& data) override { + CHECK(current_curve_.has_value()); + current_curve_.emplace(CreateTestCurveFromTrainingData(data)); + return current_curve_.value(); } private: + base::Optional<MonotoneCubicSpline> global_curve_; + base::Optional<MonotoneCubicSpline> current_curve_; + DISALLOW_COPY_AND_ASSIGN(FakeTrainer); }; @@ -69,32 +85,38 @@ ~TestObserver() override = default; // Modeller::Observer overrides: - void OnModelTrained(const BrightnessCurve& brightness_curve) override { - brightness_curve_ = base::Optional<BrightnessCurve>(brightness_curve); + void OnModelTrained(const MonotoneCubicSpline& brightness_curve) override { + brightness_curve_.emplace(brightness_curve); + trained_curve_received_ = true; } - void OnModelInitialized(const Modeller::Status model_status, - const BrightnessCurve& brightness_curve) override { + void OnModelInitialized( + const Modeller::Status model_status, + const base::Optional<MonotoneCubicSpline>& brightness_curve) override { model_status_ = base::Optional<Modeller::Status>(model_status); - brightness_curve_ = base::Optional<BrightnessCurve>(brightness_curve); + if (brightness_curve.has_value()) { + brightness_curve_.emplace(brightness_curve.value()); + } } Modeller::Status model_status() const { - DCHECK(model_status_.has_value()); + CHECK(model_status_.has_value()); return model_status_.value(); } - BrightnessCurve brightness_curve() const { - DCHECK(brightness_curve_.has_value()); + MonotoneCubicSpline brightness_curve() const { + CHECK(brightness_curve_.has_value()); return brightness_curve_.value(); } bool HasModelStatus() { return model_status_.has_value(); } bool HasBrightnessCurve() { return brightness_curve_.has_value(); } + bool trained_curve_received() { return trained_curve_received_; } private: base::Optional<Modeller::Status> model_status_; - base::Optional<BrightnessCurve> brightness_curve_; + base::Optional<MonotoneCubicSpline> brightness_curve_; + bool trained_curve_received_ = false; DISALLOW_COPY_AND_ASSIGN(TestObserver); }; @@ -130,12 +152,12 @@ } protected: - void WriteCurveToFile(const BrightnessCurve& curve) { + void WriteCurveToFile(const MonotoneCubicSpline& curve) { const base::FilePath curve_path = modeller_->GetCurvePathForTesting(profile_.get()); CHECK(!curve_path.empty()); - const std::string& data = CurveToString(curve); + const std::string data = curve.ToString(); const int bytes_written = base::WriteFile(curve_path, data.data(), data.size()); ASSERT_EQ(bytes_written, static_cast<int>(data.size())) @@ -168,6 +190,7 @@ SetUpModeller(); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(Modeller::Status::kDisabled, test_observer_->model_status()); + EXPECT_FALSE(test_observer_->HasBrightnessCurve()); } // BrightnessMonitor is |kDisabled| when Modeller is created. @@ -177,6 +200,7 @@ SetUpModeller(); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(Modeller::Status::kDisabled, test_observer_->model_status()); + EXPECT_FALSE(test_observer_->HasBrightnessCurve()); } // AlsReader is |kDisabled| on later notification. @@ -191,6 +215,7 @@ fake_als_reader_.set_als_init_status(AlsReader::AlsInitStatus::kDisabled); fake_als_reader_.ReportReaderInitialized(); EXPECT_EQ(Modeller::Status::kDisabled, test_observer_->model_status()); + EXPECT_FALSE(test_observer_->HasBrightnessCurve()); } // AlsReader is |kSuccess| on later notification. @@ -206,7 +231,8 @@ fake_als_reader_.ReportReaderInitialized(); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(Modeller::Status::kGlobal, test_observer_->model_status()); - EXPECT_TRUE(test_observer_->brightness_curve().empty()); + EXPECT_EQ(test_observer_->brightness_curve(), + modeller_->GetGlobalCurveForTesting()); } // BrightnessMonitor is |kDisabled| on later notification. @@ -221,6 +247,7 @@ fake_brightness_monitor_.set_status(BrightnessMonitor::Status::kDisabled); fake_brightness_monitor_.ReportBrightnessMonitorInitialized(); EXPECT_EQ(Modeller::Status::kDisabled, test_observer_->model_status()); + EXPECT_FALSE(test_observer_->HasBrightnessCurve()); } // BrightnessMonitor is |kSuccess| on later notification. @@ -236,7 +263,8 @@ fake_brightness_monitor_.ReportBrightnessMonitorInitialized(); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(Modeller::Status::kGlobal, test_observer_->model_status()); - EXPECT_TRUE(test_observer_->brightness_curve().empty()); + EXPECT_EQ(test_observer_->brightness_curve(), + modeller_->GetGlobalCurveForTesting()); } // There is no saved curve, hence a global curve is created. @@ -246,13 +274,16 @@ SetUpModeller(); scoped_task_environment_.RunUntilIdle(); EXPECT_EQ(Modeller::Status::kGlobal, test_observer_->model_status()); - EXPECT_TRUE(test_observer_->brightness_curve().empty()); + EXPECT_EQ(test_observer_->brightness_curve(), + modeller_->GetGlobalCurveForTesting()); } // A curve is loaded from disk, this is a personal curve. TEST_F(ModellerImplTest, CurveLoadedFromProfilePath) { - const BrightnessCurve curve = {{10, 15}, {20, 25}, {30, 35}, {40, 45}, - {50, 55}, {60, 65}, {70, 75}, {80, 85}}; + const std::vector<double> xs = {0, 10, 20, 40, 60, 80, 90, 100}; + const std::vector<double> ys = {0, 5, 10, 15, 20, 25, 30, 40}; + MonotoneCubicSpline curve(xs, ys); + WriteCurveToFile(curve); scoped_task_environment_.RunUntilIdle(); @@ -303,7 +334,7 @@ ASSERT_EQ(Modeller::Status::kGlobal, test_observer_->model_status()); std::vector<TrainingDataPoint> expected_data; - for (int i = 0; i < ModellerImpl::kMaxTrainingDataPoints - 1; ++i) { + for (size_t i = 0; i < ModellerImpl::kMaxTrainingDataPoints - 1; ++i) { EXPECT_EQ(i, modeller_->NumberTrainingDataPointsForTesting()); scoped_task_environment_.FastForwardBy( base::TimeDelta::FromMilliseconds(1)); @@ -314,8 +345,9 @@ const double brightness_old = 10.0 + i; const double brightness_new = 20.0 + i; modeller_->OnUserBrightnessChanged(brightness_old, brightness_new); - expected_data.push_back({brightness_old, brightness_new, - modeller_->AverageAmbientForTesting(), now}); + expected_data.push_back( + {brightness_old, brightness_new, + ConvertToLog(modeller_->AverageAmbientForTesting()), now}); } // Training should not have started. @@ -330,16 +362,16 @@ const double brightness_new = 95; modeller_->OnUserBrightnessChanged(brightness_old, brightness_new); expected_data.push_back({brightness_old, brightness_new, - modeller_->AverageAmbientForTesting(), now}); + ConvertToLog(modeller_->AverageAmbientForTesting()), + now}); scoped_task_environment_.RunUntilIdle(); - EXPECT_EQ(0, modeller_->NumberTrainingDataPointsForTesting()); - const BrightnessCurve result_curve = test_observer_->brightness_curve(); - BrightnessCurve expected_curve; - for (auto& training_data_point : expected_data) { - expected_curve.push_back(DataToCurvePoint(training_data_point)); - } - CompareBrightnessCurve(expected_curve, result_curve); + EXPECT_EQ(0u, modeller_->NumberTrainingDataPointsForTesting()); + const MonotoneCubicSpline& result_curve = test_observer_->brightness_curve(); + + const MonotoneCubicSpline expected_curve = + CreateTestCurveFromTrainingData(expected_data); + EXPECT_EQ(expected_curve, result_curve); } // User activities resets timer used to start training. @@ -351,10 +383,25 @@ ASSERT_EQ(Modeller::Status::kGlobal, test_observer_->model_status()); fake_als_reader_.ReportAmbientLightUpdate(30); - modeller_->OnUserBrightnessChanged(10, 20); - const TrainingDataPoint expected_data = { - 10, 20, 30, scoped_task_environment_.GetMockTickClock()->NowTicks()}; - EXPECT_EQ(1, modeller_->NumberTrainingDataPointsForTesting()); + std::vector<TrainingDataPoint> expected_data; + for (size_t i = 0; i < ModellerImpl::kMinTrainingDataPoints; ++i) { + EXPECT_EQ(i, modeller_->NumberTrainingDataPointsForTesting()); + scoped_task_environment_.FastForwardBy( + base::TimeDelta::FromMilliseconds(1)); + const base::TimeTicks now = + scoped_task_environment_.GetMockTickClock()->NowTicks(); + const int lux = i * 20; + fake_als_reader_.ReportAmbientLightUpdate(lux); + const double brightness_old = 10.0 + i; + const double brightness_new = 20.0 + i; + modeller_->OnUserBrightnessChanged(brightness_old, brightness_new); + expected_data.push_back( + {brightness_old, brightness_new, + ConvertToLog(modeller_->AverageAmbientForTesting()), now}); + } + + EXPECT_EQ(ModellerImpl::kMinTrainingDataPoints, + modeller_->NumberTrainingDataPointsForTesting()); scoped_task_environment_.FastForwardBy(ModellerImpl::kTrainingDelay - base::TimeDelta::FromSeconds(10)); @@ -365,7 +412,8 @@ scoped_task_environment_.FastForwardBy(ModellerImpl::kTrainingDelay - base::TimeDelta::FromSeconds(2)); - EXPECT_EQ(1, modeller_->NumberTrainingDataPointsForTesting()); + EXPECT_EQ(ModellerImpl::kMinTrainingDataPoints, + modeller_->NumberTrainingDataPointsForTesting()); // Another user event is received. modeller_->OnUserActivity(&mouse_event); @@ -374,16 +422,40 @@ scoped_task_environment_.FastForwardBy(ModellerImpl::kTrainingDelay - base::TimeDelta::FromSeconds(2)); scoped_task_environment_.RunUntilIdle(); - EXPECT_EQ(1, modeller_->NumberTrainingDataPointsForTesting()); + EXPECT_EQ(ModellerImpl::kMinTrainingDataPoints, + modeller_->NumberTrainingDataPointsForTesting()); // After another 2 seconds, training is scheduled. scoped_task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(2)); scoped_task_environment_.RunUntilIdle(); - EXPECT_EQ(0, modeller_->NumberTrainingDataPointsForTesting()); - const BrightnessCurve result_curve = test_observer_->brightness_curve(); - BrightnessCurve expected_curve = {DataToCurvePoint(expected_data)}; - CompareBrightnessCurve(expected_curve, result_curve); + EXPECT_EQ(0u, modeller_->NumberTrainingDataPointsForTesting()); + const MonotoneCubicSpline& result_curve = test_observer_->brightness_curve(); + + const MonotoneCubicSpline expected_curve = + CreateTestCurveFromTrainingData(expected_data); + EXPECT_EQ(expected_curve, result_curve); +} + +// No training is done because number of training data points is less than +// |kMinTrainingDataPoints|. +TEST_F(ModellerImplTest, MinTrainingDataPointsRequired) { + fake_als_reader_.set_als_init_status(AlsReader::AlsInitStatus::kSuccess); + fake_brightness_monitor_.set_status(BrightnessMonitor::Status::kSuccess); + SetUpModeller(); + scoped_task_environment_.RunUntilIdle(); + ASSERT_EQ(Modeller::Status::kGlobal, test_observer_->model_status()); + + fake_als_reader_.ReportAmbientLightUpdate(30); + modeller_->OnUserBrightnessChanged(10, 20); + + // No training is done because we have too few training data points. + scoped_task_environment_.FastForwardBy(ModellerImpl::kTrainingDelay + + base::TimeDelta::FromSeconds(10)); + scoped_task_environment_.RunUntilIdle(); + EXPECT_EQ(1u, modeller_->NumberTrainingDataPointsForTesting()); + + EXPECT_FALSE(test_observer_->trained_curve_received()); } } // namespace auto_screen_brightness
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline.cc b/chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline.cc index 80d6b80..34166830 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline.cc +++ b/chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline.cc
@@ -8,6 +8,9 @@ #include "base/logging.h" #include "base/macros.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" namespace chromeos { namespace power { @@ -90,6 +93,58 @@ MonotoneCubicSpline::~MonotoneCubicSpline() = default; +base::Optional<MonotoneCubicSpline> MonotoneCubicSpline::FromString( + const std::string& data) { + std::vector<double> xs; + std::vector<double> ys; + + if (data.empty()) + return base::nullopt; + + base::StringPairs key_value_pairs; + if (!base::SplitStringIntoKeyValuePairs(data, ',', '\n', &key_value_pairs)) { + LOG(ERROR) << "Ill-formatted spline"; + return base::nullopt; + } + + for (base::StringPairs::iterator it = key_value_pairs.begin(); + it != key_value_pairs.end(); ++it) { + double x; + if (!base::StringToDouble(it->first, &x)) { + LOG(ERROR) << "Ill-formatted xs"; + return base::nullopt; + } + + double y; + if (!base::StringToDouble(it->second, &y)) { + LOG(ERROR) << "Ill-formatted ys"; + return base::nullopt; + } + xs.push_back(x); + ys.push_back(y); + } + + if (xs.size() < 2) + return base::nullopt; + + return MonotoneCubicSpline(xs, ys); +} + +bool MonotoneCubicSpline::operator==(const MonotoneCubicSpline& spline) const { + if (xs_.size() != spline.xs_.size()) { + return false; + } + + for (size_t i = 0; i < xs_.size(); ++i) { + if (std::abs(xs_[i] - spline.xs_[i]) >= kTol || + std::abs(ys_[i] - spline.ys_[i]) >= kTol) { + return false; + } + } + + return true; +} + double MonotoneCubicSpline::Interpolate(double x) const { DCHECK_GT(num_points_, 1u); @@ -136,6 +191,16 @@ return ys_; } +std::string MonotoneCubicSpline::ToString() const { + std::vector<std::string> rows; + for (size_t i = 0; i < num_points_; ++i) { + rows.push_back(base::JoinString( + {base::NumberToString(xs_[i]), base::NumberToString(ys_[i])}, ",")); + } + + return base::JoinString(rows, "\n"); +} + } // namespace auto_screen_brightness } // namespace power } // namespace chromeos
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline.h b/chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline.h index b2c4a8d..804d54b 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline.h +++ b/chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline.h
@@ -28,6 +28,15 @@ ~MonotoneCubicSpline(); + // Parses and returns a MonotoneCubicSpline from input |data| or nullopt if + // parsing fails. Correct formatting in |data| should be 1 row per + // (<x>, <y>) mapping, and values of xs should strictly increase per row and + // ys should be non-decreasing. + static base::Optional<MonotoneCubicSpline> FromString( + const std::string& data); + + bool operator==(const MonotoneCubicSpline& spline) const; + // Returns interpolated value for |x|. If |x| is smaller|greater than // smallest|largest value in |xs_|, then smallest|largest value in |ys_| will // be returned. @@ -37,6 +46,10 @@ std::vector<double> GetControlPointsY() const; + // Converts to a string. Each (x, y) point in this curve will be converted to + // 1 row and each (x, y) point will converted to x:y format. + std::string ToString() const; + private: const std::vector<double> xs_; const std::vector<double> ys_;
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline_unittest.cc b/chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline_unittest.cc index 08505ec..2de10fa 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline_unittest.cc +++ b/chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline_unittest.cc
@@ -77,6 +77,34 @@ } } +TEST(MonotoneCubicSpline, FromStringCorrectFormat) { + const std::string data("1,10\n2,20\n3,30"); + const base::Optional<MonotoneCubicSpline> spline_from_string = + MonotoneCubicSpline::FromString(data); + const std::vector<double> xs = {1, 2, 3}; + const std::vector<double> ys = {10, 20, 30}; + const MonotoneCubicSpline expected_spline(xs, ys); + EXPECT_EQ(expected_spline, spline_from_string); +} + +TEST(MonotoneCubicSpline, FromStringTooFewRows) { + const std::string data("1,10"); + const base::Optional<MonotoneCubicSpline> spline_from_string = + MonotoneCubicSpline::FromString(data); + EXPECT_FALSE(spline_from_string.has_value()); +} + +TEST(MonotoneCubicSpline, ToString) { + const std::vector<double> xs = {1, 2, 3}; + const std::vector<double> ys = {10, 20, 30}; + const MonotoneCubicSpline spline(xs, ys); + const std::string string_from_spline = spline.ToString(); + + const std::string expected_string("1,10\n2,20\n3,30"); + + EXPECT_EQ(expected_string, string_from_spline); +} + } // namespace auto_screen_brightness } // namespace power } // namespace chromeos
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/trainer.h b/chrome/browser/chromeos/power/auto_screen_brightness/trainer.h index 0ed5c89..b1d271fe 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/trainer.h +++ b/chrome/browser/chromeos/power/auto_screen_brightness/trainer.h
@@ -5,18 +5,17 @@ #ifndef CHROME_BROWSER_CHROMEOS_POWER_AUTO_SCREEN_BRIGHTNESS_TRAINER_H_ #define CHROME_BROWSER_CHROMEOS_POWER_AUTO_SCREEN_BRIGHTNESS_TRAINER_H_ +#include "base/time/time.h" +#include "chrome/browser/chromeos/power/auto_screen_brightness/monotone_cubic_spline.h" + namespace chromeos { namespace power { namespace auto_screen_brightness { -// It is a mapping from ambient light (in lux) to brightness percent. It should -// be sorted in the ascending order in lux. -using BrightnessCurve = std::vector<std::pair<double, double>>; - struct TrainingDataPoint { double brightness_old; double brightness_new; - double ambient_lux; + double ambient_log_lux; base::TimeTicks sample_time; }; @@ -25,8 +24,13 @@ public: virtual ~Trainer() = default; - virtual BrightnessCurve Train(const BrightnessCurve& curve, - const std::vector<TrainingDataPoint>& data) = 0; + virtual void SetInitialCurves(const MonotoneCubicSpline& global_curve, + const MonotoneCubicSpline& current_curve) = 0; + + // Updates current curve stored in trainer with |data|. This function should + // only be called after |SetInitialCurves|. + virtual MonotoneCubicSpline Train( + const std::vector<TrainingDataPoint>& data) = 0; }; } // namespace auto_screen_brightness
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/utils.cc b/chrome/browser/chromeos/power/auto_screen_brightness/utils.cc index fc9b208..a0f62869 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/utils.cc +++ b/chrome/browser/chromeos/power/auto_screen_brightness/utils.cc
@@ -4,59 +4,12 @@ #include "chrome/browser/chromeos/power/auto_screen_brightness/utils.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" - namespace chromeos { namespace power { namespace auto_screen_brightness { -bool CurveFromString(const std::string& data, BrightnessCurve* const curve) { - DCHECK(curve); - curve->clear(); - if (data.empty()) - return true; - - base::StringPairs key_value_pairs; - if (!base::SplitStringIntoKeyValuePairs(data, ',', '\n', &key_value_pairs)) { - LOG(ERROR) << "Ill-formatted curve"; - return false; - } - - for (base::StringPairs::iterator it = key_value_pairs.begin(); - it != key_value_pairs.end(); ++it) { - double lux; - if (!base::StringToDouble(it->first, &lux)) { - LOG(ERROR) << "Ill-formatted lux"; - curve->clear(); - return false; - } - - double brightness; - if (!base::StringToDouble(it->second, &brightness)) { - LOG(ERROR) << "Ill-formatted brightness"; - curve->clear(); - return false; - } - - curve->push_back(std::make_pair(lux, brightness)); - } - return true; -} - -std::string CurveToString(const BrightnessCurve& curve) { - if (curve.empty()) - return ""; - - std::vector<std::string> rows; - for (const auto& kv : curve) { - rows.push_back(base::JoinString( - {base::NumberToString(kv.first), base::NumberToString(kv.second)}, - ",")); - } - - return base::JoinString(rows, "\n"); +double ConvertToLog(double value) { + return std::log(1 + value); } } // namespace auto_screen_brightness
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/utils.h b/chrome/browser/chromeos/power/auto_screen_brightness/utils.h index a5b6cbe..96a2a295 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/utils.h +++ b/chrome/browser/chromeos/power/auto_screen_brightness/utils.h
@@ -10,21 +10,13 @@ #include "base/containers/ring_buffer.h" #include "base/time/time.h" -#include "chrome/browser/chromeos/power/auto_screen_brightness/trainer.h" namespace chromeos { namespace power { namespace auto_screen_brightness { -// Replaces |curve| with the parsed curve data from |data|, returning true if -// successful. Correct formatting in |data| should be 1 row per -// (<ambient_light>, <brightness>) mapping. Ambient light should be a double and -// brightness should be a double. -bool CurveFromString(const std::string& data, BrightnessCurve* const curve); - -// Converts |curve| to a string. An empty string will be returned if |curve| is -// empty. -std::string CurveToString(const BrightnessCurve& curve); +// Returns natural log of 1+|value|. +double ConvertToLog(double value); struct AmbientLightSample { int lux;
diff --git a/chrome/browser/chromeos/tether/tether_service.cc b/chrome/browser/chromeos/tether/tether_service.cc index 54162577..2f0707a1 100644 --- a/chrome/browser/chromeos/tether/tether_service.cc +++ b/chrome/browser/chromeos/tether/tether_service.cc
@@ -685,6 +685,15 @@ kUnavailableSuiteDisabled: return BETTER_TOGETHER_SUITE_DISABLED; case chromeos::multidevice_setup::mojom::FeatureState:: + kUnavailableNoVerifiedHost: + // Note that because of the early return above after + // !HasSyncedTetherHosts, if this point is hit, there are synced tether + // hosts available, but the multidevice state is unverified. This switch + // case can only occur for legacy Magic Tether hosts, in which case the + // service should be enabled. + // TODO(crbug.com/894585): Remove this legacy special case after M71. + return ENABLED; + case chromeos::multidevice_setup::mojom::FeatureState:: kNotSupportedByChromebook: // CryptAuth may not yet know that this device supports // MAGIC_TETHER_CLIENT (and the local device metadata is reflecting @@ -694,10 +703,6 @@ FALLTHROUGH; case chromeos::multidevice_setup::mojom::FeatureState:: kNotSupportedByPhone: - FALLTHROUGH; - case chromeos::multidevice_setup::mojom::FeatureState:: - kUnavailableNoVerifiedHost: - no_available_hosts_false_positive_encountered_ = true; return NO_AVAILABLE_HOSTS; default: // Other FeatureStates:
diff --git a/chrome/browser/chromeos/tether/tether_service_unittest.cc b/chrome/browser/chromeos/tether/tether_service_unittest.cc index 0c7e5d5c9..6c958d6d 100644 --- a/chrome/browser/chromeos/tether/tether_service_unittest.cc +++ b/chrome/browser/chromeos/tether/tether_service_unittest.cc
@@ -77,6 +77,9 @@ for (size_t i = 0; i < kNumTestDevices; ++i) { list.push_back(cryptauth::RemoteDeviceRefBuilder() .SetSupportsMobileHotspot(true) + .SetSoftwareFeatureState( + cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST, + cryptauth::SoftwareFeatureState::kSupported) .Build()); } return list; @@ -727,6 +730,7 @@ TEST_F(TetherServiceTest, TestMultiDeviceSetupClientInitiallyHasNoVerifiedHost) { + fake_tether_host_fetcher_factory_->SetNoInitialDevices(); base::test::ScopedFeatureList feature_list; feature_list.InitWithFeatures( {chromeos::features::kMultiDeviceApi, @@ -745,6 +749,8 @@ chromeos::NetworkTypePattern::Tether())); VerifyTetherActiveStatus(false /* expected_active */); + fake_tether_host_fetcher_factory_->last_created()->set_tether_hosts( + test_devices_); fake_multidevice_setup_client_->SetFeatureState( chromeos::multidevice_setup::mojom::Feature::kInstantTethering, chromeos::multidevice_setup::mojom::FeatureState::kEnabledByUser); @@ -767,6 +773,7 @@ chromeos::NetworkTypePattern::Tether())); VerifyTetherActiveStatus(true /* expected_active */); + fake_tether_host_fetcher_factory_->last_created()->set_tether_hosts({}); fake_multidevice_setup_client_->SetFeatureState( chromeos::multidevice_setup::mojom::Feature::kInstantTethering, chromeos::multidevice_setup::mojom::FeatureState:: @@ -778,6 +785,7 @@ chromeos::NetworkTypePattern::Tether())); VerifyTetherActiveStatus(false /* expected_active */); + mock_timer_->Fire(); ShutdownTetherService(); VerifyTetherFeatureStateRecorded( TetherService::TetherFeatureState::NO_AVAILABLE_HOSTS,
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc index e99d8ad8..79675fe 100644 --- a/chrome/browser/devtools/devtools_window.cc +++ b/chrome/browser/devtools/devtools_window.cc
@@ -144,7 +144,7 @@ content::KeyboardEventProcessingResult PreHandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; void WebContentsDestroyed() override; @@ -186,16 +186,15 @@ return content::KeyboardEventProcessingResult::NOT_HANDLED; } -void DevToolsToolboxDelegate::HandleKeyboardEvent( +bool DevToolsToolboxDelegate::HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { if (event.windows_key_code == 0x08) { // Do not navigate back in history on Windows (http://crbug.com/74156). - return; + return false; } BrowserWindow* window = GetInspectedBrowserWindow(); - if (window) - window->HandleKeyboardEvent(event); + return window && window->HandleKeyboardEvent(event); } void DevToolsToolboxDelegate::WebContentsDestroyed() { @@ -1249,16 +1248,15 @@ return content::KeyboardEventProcessingResult::NOT_HANDLED; } -void DevToolsWindow::HandleKeyboardEvent( +bool DevToolsWindow::HandleKeyboardEvent( WebContents* source, const content::NativeWebKeyboardEvent& event) { if (event.windows_key_code == 0x08) { // Do not navigate back in history on Windows (http://crbug.com/74156). - return; + return true; } BrowserWindow* inspected_window = GetInspectedBrowserWindow(); - if (inspected_window) - inspected_window->HandleKeyboardEvent(event); + return inspected_window && inspected_window->HandleKeyboardEvent(event); } content::JavaScriptDialogManager* DevToolsWindow::GetJavaScriptDialogManager(
diff --git a/chrome/browser/devtools/devtools_window.h b/chrome/browser/devtools/devtools_window.h index fc742cf..09808999 100644 --- a/chrome/browser/devtools/devtools_window.h +++ b/chrome/browser/devtools/devtools_window.h
@@ -319,7 +319,7 @@ content::KeyboardEventProcessingResult PreHandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; content::JavaScriptDialogManager* GetJavaScriptDialogManager(
diff --git a/chrome/browser/devtools/protocol_string.h b/chrome/browser/devtools/protocol_string.h index 4a9c533..af77145 100644 --- a/chrome/browser/devtools/protocol_string.h +++ b/chrome/browser/devtools/protocol_string.h
@@ -79,6 +79,20 @@ static std::unique_ptr<protocol::Value> parseJSON(const String&); }; +// A read-only sequence of uninterpreted bytes with reference-counted storage. +// Though the templates for generating the protocol bindings reference +// this type, thus far it's not used in the Chrome layer, so we provide no +// implementation here and rely on the linker optimizing it away. If this +// changes, look to content/browser/devtools/protocol_string{.h,.cc} for +// inspiration. +class Binary { + public: + const uint8_t* data() const; + size_t size() const; + String toBase64() const; + static Binary fromBase64(const String& base64, bool* success); +}; + std::unique_ptr<protocol::Value> toProtocolValue(const base::Value* value, int depth); std::unique_ptr<base::Value> toBaseValue(protocol::Value* value, int depth);
diff --git a/chrome/browser/extensions/extension_keybinding_apitest.cc b/chrome/browser/extensions/extension_keybinding_apitest.cc index 8bbdaa2..29fb452 100644 --- a/chrome/browser/extensions/extension_keybinding_apitest.cc +++ b/chrome/browser/extensions/extension_keybinding_apitest.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/extensions/browser_action_test_util.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views_mode_controller.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/ui_test_utils.h" @@ -350,6 +351,8 @@ control_is_modifier, false, false, command_is_modifier)); + ui_test_utils::WaitUntilViewFocused(browser(), VIEW_ID_OMNIBOX); + // Activate the shortcut. ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_P, control_is_modifier, false, false,
diff --git a/chrome/browser/extensions/extension_view.h b/chrome/browser/extensions/extension_view.h index 9018f5c..41e89b5d 100644 --- a/chrome/browser/extensions/extension_view.h +++ b/chrome/browser/extensions/extension_view.h
@@ -42,7 +42,7 @@ virtual void RenderViewCreated(content::RenderViewHost* render_view_host) = 0; // Handles unhandled keyboard messages coming back from the renderer process. - virtual void HandleKeyboardEvent( + virtual bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) = 0;
diff --git a/chrome/browser/extensions/extension_view_host.cc b/chrome/browser/extensions/extension_view_host.cc index a8ef1d9..56573ba 100644 --- a/chrome/browser/extensions/extension_view_host.cc +++ b/chrome/browser/extensions/extension_view_host.cc
@@ -193,17 +193,18 @@ return content::KeyboardEventProcessingResult::NOT_HANDLED; } -void ExtensionViewHost::HandleKeyboardEvent( +bool ExtensionViewHost::HandleKeyboardEvent( WebContents* source, const NativeWebKeyboardEvent& event) { if (extension_host_type() == VIEW_TYPE_EXTENSION_POPUP) { if (event.GetType() == NativeWebKeyboardEvent::kRawKeyDown && event.windows_key_code == ui::VKEY_ESCAPE) { Close(); - return; + return true; } } UnhandledKeyboardEvent(source, event); + return true; } bool ExtensionViewHost::PreHandleGestureEvent(
diff --git a/chrome/browser/extensions/extension_view_host.h b/chrome/browser/extensions/extension_view_host.h index d16c9f7..fb034c1 100644 --- a/chrome/browser/extensions/extension_view_host.h +++ b/chrome/browser/extensions/extension_view_host.h
@@ -72,7 +72,7 @@ content::KeyboardEventProcessingResult PreHandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; bool PreHandleGestureEvent(content::WebContents* source,
diff --git a/chrome/browser/feedback/show_feedback_page.cc b/chrome/browser/feedback/show_feedback_page.cc index fff878b3..8b3a682 100644 --- a/chrome/browser/feedback/show_feedback_page.cc +++ b/chrome/browser/feedback/show_feedback_page.cc
@@ -16,8 +16,8 @@ #if defined(OS_CHROMEOS) #include "base/sys_info.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "components/signin/core/browser/signin_manager.h" +#include "chrome/browser/signin/identity_manager_factory.h" +#include "services/identity/public/cpp/identity_manager.h" #endif namespace feedback_private = extensions::api::feedback_private; @@ -85,10 +85,9 @@ : feedback_private::FeedbackFlow::FEEDBACK_FLOW_REGULAR; #if defined(OS_CHROMEOS) - SigninManagerBase* signin_manager = - SigninManagerFactory::GetForProfile(profile); - if (signin_manager && - base::EndsWith(signin_manager->GetAuthenticatedAccountInfo().email, + auto* identity_manager = IdentityManagerFactory::GetForProfile(profile); + if (identity_manager && + base::EndsWith(identity_manager->GetPrimaryAccountInfo().email, kGoogleDotCom, base::CompareCase::INSENSITIVE_ASCII) && IsFromUserInteraction(source) && IsBluetoothLoggingAllowedByBoard()) { flow = feedback_private::FeedbackFlow::FEEDBACK_FLOW_GOOGLEINTERNAL;
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index aad4c470..95e94cd4 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3257,6 +3257,11 @@ "If enabled, the handwriting virtual keyboard will allow user to write " "anywhere on the screen"; +const char kEnableGoogleAssistantName[] = "Enable Google Assistant"; +const char kEnableGoogleAssistantDescription[] = + "Enable an experimental Assistant implementation that will work on all " + "Chromebooks."; + const char kEnableHomeLauncherName[] = "Enable home launcher"; const char kEnableHomeLauncherDescription[] = "Enable home launcher in tablet mode.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 5b27f50..44a2b75 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1984,6 +1984,9 @@ extern const char kEnableFullscreenHandwritingVirtualKeyboardName[]; extern const char kEnableFullscreenHandwritingVirtualKeyboardDescription[]; +extern const char kEnableGoogleAssistantName[]; +extern const char kEnableGoogleAssistantDescription[]; + extern const char kEnableHomeLauncherName[]; extern const char kEnableHomeLauncherDescription[];
diff --git a/chrome/browser/net/chrome_accept_language_settings.cc b/chrome/browser/net/chrome_accept_language_settings.cc deleted file mode 100644 index cf96988..0000000 --- a/chrome/browser/net/chrome_accept_language_settings.cc +++ /dev/null
@@ -1,95 +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/net/chrome_accept_language_settings.h" - -#include <unordered_set> - -#include "base/feature_list.h" -#include "base/strings/string_piece.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "chrome/common/chrome_features.h" -#include "net/http/http_util.h" - -namespace chrome_accept_language_settings { -namespace { - -// Helper class that builds the list of languages for the Accept-Language -// headers. -// The output is a comma-separated list of languages as string. -// Duplicates are removed. -class AcceptLanguageBuilder { - public: - // Adds a language to the string. - // Duplicates are ignored. - void AddLanguageCode(const std::string& language) { - if (seen_.find(language) == seen_.end()) { - if (str_.empty()) { - base::StringAppendF(&str_, "%s", language.c_str()); - } else { - base::StringAppendF(&str_, ",%s", language.c_str()); - } - seen_.insert(language); - } - } - - // Returns the string constructed up to this point. - std::string GetString() const { return str_; } - - private: - // The string that contains the list of languages, comma-separated. - std::string str_; - // Set the remove duplicates. - std::unordered_set<std::string> seen_; -}; - -// Extract the base language code from a language code. -// If there is no '-' in the code, the original code is returned. -std::string GetBaseLanguageCode(const std::string& language_code) { - const std::vector<std::string> tokens = base::SplitString( - language_code, "-", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - return tokens.empty() ? "" : tokens[0]; -} - -} // namespace - -std::string ComputeAcceptLanguageFromPref(const std::string& language_pref) { - std::string accept_languages_str = - base::FeatureList::IsEnabled(features::kUseNewAcceptLanguageHeader) - ? ExpandLanguageList(language_pref) - : language_pref; - return net::HttpUtil::GenerateAcceptLanguageHeader(accept_languages_str); -} - -std::string ExpandLanguageList(const std::string& language_prefs) { - const std::vector<std::string> languages = base::SplitString( - language_prefs, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - - if (languages.empty()) - return ""; - - AcceptLanguageBuilder builder; - - const int size = languages.size(); - for (int i = 0; i < size; ++i) { - const std::string& language = languages[i]; - builder.AddLanguageCode(language); - - // Extract the base language - const std::string& base_language = GetBaseLanguageCode(language); - - // Look ahead and add the base language if the next language is not part - // of the same family. - const int j = i + 1; - if (j >= size || GetBaseLanguageCode(languages[j]) != base_language) { - builder.AddLanguageCode(base_language); - } - } - - return builder.GetString(); -} - -} // namespace chrome_accept_language_settings
diff --git a/chrome/browser/net/chrome_accept_language_settings.h b/chrome/browser/net/chrome_accept_language_settings.h deleted file mode 100644 index 470d1575..0000000 --- a/chrome/browser/net/chrome_accept_language_settings.h +++ /dev/null
@@ -1,21 +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_NET_CHROME_ACCEPT_LANGUAGE_SETTINGS_H_ -#define CHROME_BROWSER_NET_CHROME_ACCEPT_LANGUAGE_SETTINGS_H_ - -#include <string> - -namespace chrome_accept_language_settings { - -// Given value of prefs::kAcceptLanguages pref, computes the corresponding -// Accept-Language header to send. -std::string ComputeAcceptLanguageFromPref(const std::string& language_pref); - -// Adds the base language if a corresponding language+region code is present. -std::string ExpandLanguageList(const std::string& language_prefs); - -} // namespace chrome_accept_language_settings - -#endif // CHROME_BROWSER_NET_CHROME_ACCEPT_LANGUAGE_SETTINGS_H_
diff --git a/chrome/browser/net/chrome_accept_language_settings_unittest.cc b/chrome/browser/net/chrome_accept_language_settings_unittest.cc deleted file mode 100644 index 53ab1f30..0000000 --- a/chrome/browser/net/chrome_accept_language_settings_unittest.cc +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright (c) 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 "chrome/browser/net/chrome_accept_language_settings.h" - -#include "testing/gtest/include/gtest/gtest.h" - -// Test the expansion of the Language List. -TEST(ChromeAcceptLanguageSettings, ExpandLanguageList) { - std::string output = chrome_accept_language_settings::ExpandLanguageList(""); - EXPECT_EQ("", output); - - output = chrome_accept_language_settings::ExpandLanguageList("en-US"); - EXPECT_EQ("en-US,en", output); - - output = chrome_accept_language_settings::ExpandLanguageList("fr"); - EXPECT_EQ("fr", output); - - // The base language is added after all regional codes... - output = chrome_accept_language_settings::ExpandLanguageList("en-US,en-CA"); - EXPECT_EQ("en-US,en-CA,en", output); - - // ... but before other language families. - output = - chrome_accept_language_settings::ExpandLanguageList("en-US,en-CA,fr"); - EXPECT_EQ("en-US,en-CA,en,fr", output); - - output = chrome_accept_language_settings::ExpandLanguageList( - "en-US,en-CA,fr,en-AU"); - EXPECT_EQ("en-US,en-CA,en,fr,en-AU", output); - - output = - chrome_accept_language_settings::ExpandLanguageList("en-US,en-CA,fr-CA"); - EXPECT_EQ("en-US,en-CA,en,fr-CA,fr", output); - - // Add a base language even if it's already in the list. - output = chrome_accept_language_settings::ExpandLanguageList( - "en-US,fr-CA,it,fr,es-AR,it-IT"); - EXPECT_EQ("en-US,en,fr-CA,fr,it,es-AR,es,it-IT", output); -}
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index 109cf2899..dd9f903 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -13,13 +13,13 @@ #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/net/chrome_accept_language_settings.h" #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h" #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h" #include "chrome/browser/net/system_network_context_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_content_client.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_paths_internal.h" #include "chrome/common/pref_names.h" #include "components/certificate_transparency/pref_names.h" @@ -35,6 +35,7 @@ #include "content/public/common/service_names.mojom.h" #include "content/public/common/url_constants.h" #include "mojo/public/cpp/bindings/associated_interface_ptr.h" +#include "net/http/http_util.h" #include "net/net_buildflags.h" #include "services/network/public/cpp/features.h" @@ -53,6 +54,14 @@ return strings; } +std::string ComputeAcceptLanguageFromPref(const std::string& language_pref) { + std::string accept_languages_str = + base::FeatureList::IsEnabled(features::kUseNewAcceptLanguageHeader) + ? net::HttpUtil::ExpandLanguageList(language_pref) + : language_pref; + return net::HttpUtil::GenerateAcceptLanguageHeader(accept_languages_str); +} + } // namespace ProfileNetworkContextService::ProfileNetworkContextService(Profile* profile) @@ -218,8 +227,7 @@ } std::string ProfileNetworkContextService::ComputeAcceptLanguage() const { - return chrome_accept_language_settings::ComputeAcceptLanguageFromPref( - pref_accept_language_.GetValue()); + return ComputeAcceptLanguageFromPref(pref_accept_language_.GetValue()); } void ProfileNetworkContextService::UpdateReferrersEnabled() {
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.css b/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.css index 0a1c639b..9925627a 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.css +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.css
@@ -10,3 +10,38 @@ #footer-text { padding-top: 24px; } + +.oobe-popup { + width: 640px; +} + +#webview-container { + width: 100%; +} + +#webview-container.overlay-loading > webview { + visibility: hidden; +} + +#overlay-webview { + border: 1px solid #d9d9d9; + box-sizing: border-box; + display: block; + height: 300px; + margin: 16px; + width: 608px; +} + +#overlay-close-button { + margin-right: 0; +} + +#close-button-text { + padding: 0 16px 0 16px; +} + +.button-strip { + display: flex; + justify-content: flex-end; + margin: 16px; +}
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.html b/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.html index 2f63a66..d0f650b5 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.html +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.html
@@ -5,6 +5,7 @@ <dom-module id="assistant-third-party"> <template> <link rel="stylesheet" href="../login/oobe_flex_layout.css"> + <link rel="stylesheet" href="../login/oobe_popup_overlay.css"> <link rel="stylesheet" href="assistant_shared_styles.css"> <link rel="stylesheet" href="assistant_third_party.css"> <oobe-dialog id="third-party-dialog" role="dialog" has-buttons hide-shadow @@ -26,5 +27,19 @@ </oobe-next-button> </div> </oobe-dialog> + + <div id="third-party-overlay" class="popup-overlay" hidden> + <div id="overlay-container" class="oobe-popup not-resizable"> + <div id="webview-container"> + <webview id="overlay-webview"></webview> + </div> + <div class="button-strip"> + <oobe-text-button inverse id="overlay-close-button"> + <div i18n-content="assistantOptinOKButton" id="close-button-text"> + </div> + </oobe-text-button> + </div> + </div> + </div> </template> </dom-module>
diff --git a/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.js b/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.js index 9a9aa00e..2c75ab9 100644 --- a/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.js +++ b/chrome/browser/resources/chromeos/assistant_optin/assistant_third_party.js
@@ -69,6 +69,37 @@ }, /** + * Click event handler for information links. + * @param {MouseEvent} e click event. + */ + urlClickHandler: function(e) { + if (!e.target.localName == 'a') { + return; + } + e.preventDefault(); + this.showThirdPartyOverlay(e.target.href); + }, + + /** + * Shows third party information links in overlay dialog. + * @param {string} url URL to show. + */ + showThirdPartyOverlay: function(url) { + this.$['webview-container'].classList.add('overlay-loading'); + this.$['overlay-webview'].src = url; + + var overlay = this.$['third-party-overlay']; + overlay.hidden = false; + }, + + /** + * Hides overlay dialog. + */ + hideOverlay: function() { + this.$['third-party-overlay'].hidden = true; + }, + + /** * Reloads the page. */ reloadPage: function() { @@ -85,6 +116,8 @@ this.$['footer-text'].innerHTML = this.sanitizer_.sanitizeHtml(data['thirdPartyFooter']); + this.$['footer-text'].onclick = this.urlClickHandler.bind(this); + this.consentStringLoaded_ = true; if (this.settingZippyLoaded_) { this.onPageLoaded(); @@ -120,6 +153,8 @@ this.sanitizer_.sanitizeHtml(data['additionalInfo']); zippy.appendChild(additional); + additional.onclick = this.urlClickHandler.bind(this); + this.$['insertion-point'].appendChild(zippy); } @@ -147,6 +182,13 @@ * Signal from host to show the screen. */ onShow: function() { + this.$['overlay-close-button'].addEventListener( + 'click', this.hideOverlay.bind(this)); + var webviewContainer = this.$['webview-container']; + this.$['overlay-webview'].addEventListener('contentload', function() { + webviewContainer.classList.remove('overlay-loading'); + }); + if (!this.settingZippyLoaded_ || !this.consentStringLoaded_) { this.reloadPage(); } else {
diff --git a/chrome/browser/resources/chromeos/login/demo_setup.html b/chrome/browser/resources/chromeos/login/demo_setup.html index fab9a8e..6116e9d 100644 --- a/chrome/browser/resources/chromeos/login/demo_setup.html +++ b/chrome/browser/resources/chromeos/login/demo_setup.html
@@ -34,7 +34,7 @@ <h1 slot="title"> [[i18nDynamic(locale, 'demoSetupProgressScreenTitle')]] </h1> - <div slot="footer" class="flex layout vertical center"> + <div slot="footer" class="flex layout vertical center center-justified"> <paper-spinner-lite id="spinner" dir="ltr" active></paper-spinner-lite> </div> </oobe-dialog> @@ -48,7 +48,7 @@ <div slot="subtitle"> [[i18nDynamic(locale, 'demoSetupErrorScreenSubtitle')]] </div> - <div slot="footer" class="flex layout vertical center"> + <div slot="footer" class="flex layout vertical center center-justified"> <img srcset="images/alert-illustration_1x.svg 1x, images/alert-illustration_2x.svg 2x"> </div>
diff --git a/chrome/browser/resources/chromeos/login/discover/discover_card.html b/chrome/browser/resources/chromeos/login/discover/discover_card.html index f84f896..bd8cc64e 100644 --- a/chrome/browser/resources/chromeos/login/discover/discover_card.html +++ b/chrome/browser/resources/chromeos/login/discover/discover_card.html
@@ -14,6 +14,7 @@ <dom-module id="discover-card"> <template> <style include="iron-flex iron-flex-alignment iron-positioning"></style> + <link rel="stylesheet" href="../oobe_iron_flex_layout_fix.css"> <link rel="stylesheet" href="../oobe_fonts.css"> <link rel="stylesheet" href="discover_card.css"> <div class="fit layout vertical center end-justified">
diff --git a/chrome/browser/resources/chromeos/login/discover/discover_ui.html b/chrome/browser/resources/chromeos/login/discover/discover_ui.html index 53cc2cd..228abb8 100644 --- a/chrome/browser/resources/chromeos/login/discover/discover_ui.html +++ b/chrome/browser/resources/chromeos/login/discover/discover_ui.html
@@ -1,5 +1,4 @@ <link rel="import" href="chrome://resources/html/i18n_behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <!-- Discover App object. Manages all Discover UI behavior.
diff --git a/chrome/browser/resources/chromeos/login/discover/discover_welcome.html b/chrome/browser/resources/chromeos/login/discover/discover_welcome.html index 6f02b947..a325e9c 100644 --- a/chrome/browser/resources/chromeos/login/discover/discover_welcome.html +++ b/chrome/browser/resources/chromeos/login/discover/discover_welcome.html
@@ -10,6 +10,7 @@ <style include="iron-flex iron-flex-alignment iron-positioning paper-button-style cr-icons cr-shared-style"> </style> + <link rel="stylesheet" href="../oobe_iron_flex_layout_fix.css"> <oobe-dialog id="discoverWelcome" role="dialog" no-header no-footer-padding aria-label$="[[i18nDynamic(locale, 'discoverWelcomeTitle')]]"> <div slot="footer" class="flex layout vertical center">
diff --git a/chrome/browser/resources/chromeos/login/discover/modules/discover_module_launch_help_app.html b/chrome/browser/resources/chromeos/login/discover/modules/discover_module_launch_help_app.html index e7f92d17..ae4a5a0 100644 --- a/chrome/browser/resources/chromeos/login/discover/modules/discover_module_launch_help_app.html +++ b/chrome/browser/resources/chromeos/login/discover/modules/discover_module_launch_help_app.html
@@ -1,4 +1,3 @@ -<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html">
diff --git a/chrome/browser/resources/chromeos/login/discover/modules/discover_module_pin_setup.html b/chrome/browser/resources/chromeos/login/discover/modules/discover_module_pin_setup.html index 7883666..2ee8f569 100644 --- a/chrome/browser/resources/chromeos/login/discover/modules/discover_module_pin_setup.html +++ b/chrome/browser/resources/chromeos/login/discover/modules/discover_module_pin_setup.html
@@ -62,6 +62,7 @@ <style include="iron-flex iron-flex-alignment iron-positioning cr-shared-style"> </style> + <link rel="stylesheet" href="../../oobe_iron_flex_layout_fix.css"> <style include="settings-shared"></style> <link rel="stylesheet" href="discover_module_pin_setup.css"> <oobe-dialog id="loading" role="dialog" no-header no-footer-padding
diff --git a/chrome/browser/resources/chromeos/login/discover/modules/discover_module_redeem_offers.html b/chrome/browser/resources/chromeos/login/discover/modules/discover_module_redeem_offers.html index 6ea4cd5b..17d32caa 100644 --- a/chrome/browser/resources/chromeos/login/discover/modules/discover_module_redeem_offers.html +++ b/chrome/browser/resources/chromeos/login/discover/modules/discover_module_redeem_offers.html
@@ -1,4 +1,3 @@ -<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html">
diff --git a/chrome/browser/resources/chromeos/login/discover/modules/discover_module_sync_files.html b/chrome/browser/resources/chromeos/login/discover/modules/discover_module_sync_files.html index bbbcff51..50de0a6 100644 --- a/chrome/browser/resources/chromeos/login/discover/modules/discover_module_sync_files.html +++ b/chrome/browser/resources/chromeos/login/discover/modules/discover_module_sync_files.html
@@ -1,4 +1,3 @@ -<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html">
diff --git a/chrome/browser/resources/chromeos/login/enrollment_license_card.html b/chrome/browser/resources/chromeos/login/enrollment_license_card.html index 58ec66dd..28da411 100644 --- a/chrome/browser/resources/chromeos/login/enrollment_license_card.html +++ b/chrome/browser/resources/chromeos/login/enrollment_license_card.html
@@ -29,6 +29,7 @@ <style include="shared-style iron-flex iron-flex-alignment iron-positioning"> </style> + <link rel="stylesheet" href="oobe_iron_flex_layout_fix.css"> <oobe-dialog id="license-selection-prompt-card" has-buttons> <hd-iron-icon slot="oobe-icon"
diff --git a/chrome/browser/resources/chromeos/login/hd-iron-icon.html b/chrome/browser/resources/chromeos/login/hd-iron-icon.html index d858cb9..b9a670a 100644 --- a/chrome/browser/resources/chromeos/login/hd-iron-icon.html +++ b/chrome/browser/resources/chromeos/login/hd-iron-icon.html
@@ -20,6 +20,7 @@ <dom-module id="hd-iron-icon"> <template> <style include="iron-flex iron-flex-alignment iron-positioning"></style> + <link rel="stylesheet" href="oobe_iron_flex_layout_fix.css"> <link rel="stylesheet" href="hd-iron-icon.css"> <div class="flex layout vertical"> <iron-icon id="icon1x" icon="[[icon1x]]"></iron-icon>
diff --git a/chrome/browser/resources/chromeos/login/offline_ad_login.html b/chrome/browser/resources/chromeos/login/offline_ad_login.html index c64c401..7cc780f 100644 --- a/chrome/browser/resources/chromeos/login/offline_ad_login.html +++ b/chrome/browser/resources/chromeos/login/offline_ad_login.html
@@ -48,6 +48,7 @@ <template> <style include="md-select iron-flex iron-flex-alignment iron-positioning"> </style> + <link rel="stylesheet" href="oobe_iron_flex_layout_fix.css"> <link rel="stylesheet" href="offline_ad_login.css"> <oobe-dialog id="unlockStep" hidden="[[!unlockPasswordStep]]" aria-label$="[[adWelcomeMessage]]" has-buttons>
diff --git a/chrome/browser/resources/chromeos/login/oobe_a11y_option.html b/chrome/browser/resources/chromeos/login/oobe_a11y_option.html index 19d60ed..cbb41e3b 100644 --- a/chrome/browser/resources/chromeos/login/oobe_a11y_option.html +++ b/chrome/browser/resources/chromeos/login/oobe_a11y_option.html
@@ -9,6 +9,7 @@ <style include="shared-style iron-flex iron-flex-alignment iron-positioning"> </style> + <link rel="stylesheet" href="oobe_iron_flex_layout_fix.css"> <div id="elementBox" class="layout horizontal"> <div class="flex layout vertical center-justified"> <div id="titleContainer">
diff --git a/chrome/browser/resources/chromeos/login/oobe_buttons.html b/chrome/browser/resources/chromeos/login/oobe_buttons.html index e6714e1..91ecf3a72 100644 --- a/chrome/browser/resources/chromeos/login/oobe_buttons.html +++ b/chrome/browser/resources/chromeos/login/oobe_buttons.html
@@ -53,6 +53,7 @@ <dom-module id="oobe-text-button"> <template> <style include="iron-flex iron-flex-alignment iron-positioning"></style> + <link rel="stylesheet" href="oobe_iron_flex_layout_fix.css"> <style include="paper-button-style cr-icons cr-shared-style"></style> <link rel="stylesheet" href="oobe_fonts.css"> <link rel="stylesheet" href="oobe_text_buttons.css"> @@ -88,6 +89,7 @@ <dom-module id="oobe-back-button"> <template> <style include="iron-flex iron-flex-alignment iron-positioning"></style> + <link rel="stylesheet" href="oobe_iron_flex_layout_fix.css"> <style include="paper-button-style cr-icons cr-shared-style"></style> <link rel="stylesheet" href="oobe_fonts.css"> <link rel="stylesheet" href="oobe_text_buttons.css"> @@ -110,6 +112,7 @@ <dom-module id="oobe-next-button"> <template> <style include="iron-flex iron-flex-alignment iron-positioning"></style> + <link rel="stylesheet" href="oobe_iron_flex_layout_fix.css"> <style include="paper-button-style cr-icons cr-shared-style"></style> <link rel="stylesheet" href="oobe_fonts.css"> <link rel="stylesheet" href="oobe_text_buttons.css"> @@ -146,6 +149,7 @@ <dom-module id="oobe-welcome-secondary-button"> <template> <style include="iron-flex iron-flex-alignment iron-positioning"></style> + <link rel="stylesheet" href="oobe_iron_flex_layout_fix.css"> <style include="paper-button-style cr-icons cr-shared-style"></style> <link rel="stylesheet" href="oobe_fonts.css"> <link rel="stylesheet" href="oobe_text_buttons.css">
diff --git a/chrome/browser/resources/chromeos/login/oobe_iron_flex_layout_fix.css b/chrome/browser/resources/chromeos/login/oobe_iron_flex_layout_fix.css new file mode 100644 index 0000000..cd8db9d --- /dev/null +++ b/chrome/browser/resources/chromeos/login/oobe_iron_flex_layout_fix.css
@@ -0,0 +1,16 @@ +/* Copyright 2018 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. */ + +/** + * This fixes the issue with polymer 1.0 layout classes. + * (see https://crbug.com/892757) + */ + +.layout.horizontal, +.layout.horizontal-reverse, +.layout.inline, +.layout.vertical, +.layout.vertical-reverse { + min-height: 0; +}
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/BUILD.gn b/chrome/browser/resources/chromeos/zip_archiver/cpp/BUILD.gn index 5cb01cea..fd662fe 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/BUILD.gn +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/BUILD.gn
@@ -45,6 +45,7 @@ test("ziparchiver_unittests") { sources = [ + "compressor_archive_minizip_unittest.cc", "test_module.cc", "volume_archive_minizip_unittest.cc", ]
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.cc b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.cc index aee6265..7995e74d 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.cc +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.cc
@@ -32,100 +32,89 @@ exploded.minute << 5 | exploded.second >> 1; } -}; // namespace - -namespace compressor_archive_functions { - -// Called when minizip tries to open a zip archive file. We do nothing here -// because JavaScript takes care of file opening operation. -void* CustomArchiveOpen(void* compressor, - const char* /*filename*/, - int /*mode*/) { +void* MinizipOpen(void* compressor, const char* /*filename*/, int /*mode*/) { return compressor; } -// This function is not called because we don't unpack zip files here. -uint32_t CustomArchiveRead(void* /*compressor*/, - void* /*stream*/, - void* /*buffur*/, - uint32_t /*size*/) { - return 0 /* Success */; +uint32_t MinizipRead(void* /*compressor*/, + void* /*stream*/, + void* /*buffur*/, + uint32_t /*size*/) { + NOTREACHED(); + return 0; } +int MinizipClose(void* /*compressor*/, void* /*stream*/) { + return 0; +} + +int MinizipError(void* /*compressor*/, void* /*stream*/) { + return 0; +} + +}; // namespace + // Called when data chunk must be written on the archive. It copies data // from the given buffer processed by minizip to an array buffer and passes // it to compressor_stream. -uint32_t CustomArchiveWrite(void* compressor, - void* /*stream*/, - const void* zip_buffer, - uint32_t zip_length) { - CompressorArchiveMinizip* compressor_minizip = - static_cast<CompressorArchiveMinizip*>(compressor); +uint32_t CompressorArchiveMinizip::MinizipWrite(void* compressor, + void* /*stream*/, + const void* zip_buffer, + uint32_t zip_length) { + return static_cast<CompressorArchiveMinizip*>(compressor) + ->StreamWrite(zip_buffer, zip_length); +} - int64_t written_bytes = compressor_minizip->compressor_stream()->Write( - compressor_minizip->offset(), zip_length, - static_cast<const char*>(zip_buffer)); +uint32_t CompressorArchiveMinizip::StreamWrite(const void* zip_buffer, + uint32_t zip_length) { + int64_t written_bytes = compressor_stream()->Write( + offset_, zip_length, static_cast<const char*>(zip_buffer)); if (written_bytes != zip_length) return 0 /* Error */; // Update offset_ and length_. - compressor_minizip->set_offset(compressor_minizip->offset() + written_bytes); - if (compressor_minizip->offset() > compressor_minizip->length()) - compressor_minizip->set_length(compressor_minizip->offset()); - return static_cast<uLong>(written_bytes); + offset_ += written_bytes; + if (offset_ > length_) + length_ = offset_; + return static_cast<uint32_t>(written_bytes); } // Returns the offset from the beginning of the data. -long CustomArchiveTell(void* compressor, void* /*stream*/) { - CompressorArchiveMinizip* compressor_minizip = - static_cast<CompressorArchiveMinizip*>(compressor); - return static_cast<long>(compressor_minizip->offset_); +long CompressorArchiveMinizip::MinizipTell(void* compressor, void* /*stream*/) { + return static_cast<CompressorArchiveMinizip*>(compressor)->StreamTell(); +} + +long CompressorArchiveMinizip::StreamTell() { + return static_cast<long>(offset_); } // Moves the current offset to the specified position. -long CustomArchiveSeek(void* compressor, - void* /*stream*/, - uint32_t offset, - int origin) { - CompressorArchiveMinizip* compressor_minizip = - static_cast<CompressorArchiveMinizip*>(compressor); +long CompressorArchiveMinizip::MinizipSeek(void* compressor, + void* /*stream*/, + uint32_t offset, + int origin) { + return static_cast<CompressorArchiveMinizip*>(compressor) + ->StreamSeek(offset, origin); +} +long CompressorArchiveMinizip::StreamSeek(uint32_t offset, int origin) { if (origin == ZLIB_FILEFUNC_SEEK_CUR) { - compressor_minizip->set_offset( - std::min(compressor_minizip->offset() + static_cast<int64_t>(offset), - compressor_minizip->length())); + offset_ = std::min(offset_ + static_cast<int64_t>(offset), length_); return 0 /* Success */; } if (origin == ZLIB_FILEFUNC_SEEK_END) { - compressor_minizip->set_offset( - std::max(compressor_minizip->length() - static_cast<int64_t>(offset), - static_cast<int64_t>(0))); + offset_ = std::max(length_ - static_cast<int64_t>(offset), + static_cast<int64_t>(0)); return 0 /* Success */; } if (origin == ZLIB_FILEFUNC_SEEK_SET) { - compressor_minizip->set_offset( - std::min(static_cast<int64_t>(offset), compressor_minizip->length())); + offset_ = std::min(static_cast<int64_t>(offset), length_); return 0 /* Success */; } return -1 /* Error */; } -// Releases all used resources. compressor points to compressor_minizip and -// it is deleted in the destructor of Compressor, so we don't need to delete -// it here. -int CustomArchiveClose(void* /*compressor*/, void* /*stream*/) { - return 0 /* Success */; -} - -// Returns the last error that happened when writing data. This function always -// returns zero, which means there are no errors. -int CustomArchiveError(void* /*compressor*/, void* /*stream*/) { - return 0 /* Success */; -} - -} // namespace compressor_archive_functions - CompressorArchiveMinizip::CompressorArchiveMinizip( CompressorStream* compressor_stream) : CompressorArchive(compressor_stream), @@ -140,13 +129,13 @@ bool CompressorArchiveMinizip::CreateArchive() { // Set up archive object. zlib_filefunc_def zip_funcs; - zip_funcs.zopen_file = compressor_archive_functions::CustomArchiveOpen; - zip_funcs.zread_file = compressor_archive_functions::CustomArchiveRead; - zip_funcs.zwrite_file = compressor_archive_functions::CustomArchiveWrite; - zip_funcs.ztell_file = compressor_archive_functions::CustomArchiveTell; - zip_funcs.zseek_file = compressor_archive_functions::CustomArchiveSeek; - zip_funcs.zclose_file = compressor_archive_functions::CustomArchiveClose; - zip_funcs.zerror_file = compressor_archive_functions::CustomArchiveError; + zip_funcs.zopen_file = MinizipOpen; + zip_funcs.zread_file = MinizipRead; + zip_funcs.zwrite_file = MinizipWrite; + zip_funcs.ztell_file = MinizipTell; + zip_funcs.zseek_file = MinizipSeek; + zip_funcs.zclose_file = MinizipClose; + zip_funcs.zerror_file = MinizipError; zip_funcs.opaque = this; zip_file_ = zipOpen2(nullptr /* pathname */, APPEND_STATUS_CREATE,
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.h b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.h index 1fd1da9..d48036a3 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.h +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.h
@@ -14,23 +14,6 @@ class CompressorStream; -// A name space with custom functions passed to minizip. -namespace compressor_archive_functions { - -uLong CustomArchiveWrite(void* compressor, - void* stream, - const void* buffer, - uLong length); - -long CustomArchiveTell(void* compressor, void* stream); - -long CustomArchiveSeek(void* compressor, - void* stream, - uLong offset, - int origin); - -} // namespace compressor_archive_functions - class CompressorArchiveMinizip : public CompressorArchive { public: explicit CompressorArchiveMinizip(CompressorStream* compressor_stream); @@ -52,37 +35,24 @@ base::Time modification_time, bool is_directory) override; - // A getter function for zip_file_. - zipFile zip_file() const { return zip_file_; } - - // Getter and setter for offset_. - int64_t offset() const { return offset_; } - void set_offset(int64_t value) { offset_ = value; } - - // Getter and setter for length_. - int64_t length() const { return length_; } - void set_length(int64_t value) { length_ = value; } - - // A getter function for compressor_stream. - CompressorStream* compressor_stream() const { return compressor_stream_; } - - // Custom functions need to access private variables of - // CompressorArchiveMinizip frequently. - friend uLong compressor_archive_functions::CustomArchiveWrite( - void* compressor, - void* stream, - const void* buffer, - uLong length); - - friend long compressor_archive_functions::CustomArchiveTell(void* compressor, - void* stream); - - friend long compressor_archive_functions::CustomArchiveSeek(void* compressor, - void* stream, - uLong offset, - int origin); - private: + // Stream functions used by minizip. In all cases, |compressor| points to + // |this|. + static uint32_t MinizipWrite(void* compressor, + void* stream, + const void* buffer, + uint32_t length); + static long MinizipTell(void* compressor, void* stream); + static long MinizipSeek(void* compressor, + void* stream, + uint32_t offset, + int origin); + + // Implementation of stream functions used by minizip. + uint32_t StreamWrite(const void* buffer, uint32_t length); + long StreamTell(); + long StreamSeek(uint32_t offset, int origin); + // An instance that takes care of all IO operations. CompressorStream* compressor_stream_;
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip_unittest.cc b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip_unittest.cc new file mode 100644 index 0000000..d07d3316 --- /dev/null +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip_unittest.cc
@@ -0,0 +1,241 @@ +// Copyright 2018 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/resources/chromeos/zip_archiver/cpp/compressor_archive_minizip.h" + +#include <algorithm> +#include <string> +#include <utility> + +#include "base/files/file.h" +#include "base/logging.h" +#include "base/strings/string_piece.h" +#include "base/time/time.h" +#include "chrome/browser/resources/chromeos/zip_archiver/cpp/compressor_stream.h" +#include "chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +const char kTestFileName[] = "test.txt"; +const char kLargeTestFileName[] = "large.file"; +const char kTestDirName[] = "foo"; +const char kTestFileContent[] = "Hello, World!"; +const std::string kLargeTestFileContent(1234567, 'a'); + +class TestCompressorStream : public CompressorStream { + public: + TestCompressorStream() = default; + + int64_t Flush() override { return 0; } + + int64_t Write(int64_t zip_offset, + int64_t zip_length, + const char* zip_buffer) override { + CHECK_EQ(zip_offset, write_offset_); + CHECK_GT(zip_length, 0); + CHECK_NE(zip_buffer, nullptr); + + if (write_error_) + return -1; + + write_buffer_.append(zip_buffer, zip_length); + write_offset_ += zip_length; + return zip_length; + } + + int64_t WriteChunkDone(int64_t write_bytes) override { + NOTREACHED(); + return -1; + } + + int64_t Read(int64_t bytes_to_read, char* destination_buffer) override { + if (read_buffer_.empty()) + return 0; + + int64_t read_length = + std::min(bytes_to_read, static_cast<int64_t>(read_buffer_.size())); + memcpy(destination_buffer, read_buffer_.data(), read_length); + read_buffer_ = read_buffer_.substr(read_length); + return read_length; + } + + int64_t ReadFileChunkDone(int64_t read_bytes, + pp::VarArrayBuffer* buffer) override { + NOTREACHED(); + return -1; + } + + void SetReadBuffer(const std::string& buffer) { read_buffer_ = buffer; } + void SetWriteError() { write_error_ = true; } + + const std::string& write_buffer() { return write_buffer_; } + + private: + std::string write_buffer_; + int64_t write_offset_ = 0; + + bool write_error_ = false; + + std::string read_buffer_; +}; + +class InMemoryVolumeReader : public VolumeReader { + public: + explicit InMemoryVolumeReader(const std::string& file) : file_(file) {} + + int64_t Read(int64_t bytes_to_read, + const void** destination_buffer) override { + if (file_offset_ >= static_cast<int64_t>(file_.size())) + return 0; + + int64_t read_length = std::min( + bytes_to_read, static_cast<int64_t>(file_.size()) - file_offset_); + *destination_buffer = static_cast<const void*>(file_.data() + file_offset_); + file_offset_ += read_length; + return read_length; + } + + int64_t Seek(int64_t offset, base::File::Whence whence) override { + switch (whence) { + case base::File::FROM_BEGIN: + file_offset_ = offset; + break; + case base::File::FROM_CURRENT: + file_offset_ += offset; + break; + case base::File::FROM_END: + file_offset_ = file_.size() + offset; + break; + } + return file_offset_; + } + + std::unique_ptr<std::string> Passphrase() override { return nullptr; } + + int64_t offset() override { return file_offset_; } + + int64_t archive_size() override { return file_.size(); } + + private: + const std::string file_; + int64_t file_offset_ = 0; +}; + +class CompressorArchiveMinizipTest : public testing::Test { + public: + CompressorArchiveMinizipTest() = default; + + void CheckZipContents(const std::string& volume, + const std::string& path, + const std::string& contents) { + std::unique_ptr<InMemoryVolumeReader> reader = + std::make_unique<InMemoryVolumeReader>(volume); + VolumeArchiveMinizip archive(std::move(reader)); + ASSERT_TRUE(archive.Init("")); + + EXPECT_TRUE(archive.SeekHeader(path)); + const char* buffer = nullptr; + int64_t offset = 0; + while (offset < static_cast<int64_t>(contents.size())) { + int64_t read = + archive.ReadData(offset, contents.size() - offset, &buffer); + ASSERT_GT(read, 0); + EXPECT_EQ(contents.substr(offset, read), base::StringPiece(buffer, read)); + offset += read; + } + EXPECT_EQ(offset, static_cast<int64_t>(contents.size())); + } + + void CheckZipMetadata(const std::string& volume, + const std::string& path, + int64_t size, + base::Time mod_time, + bool is_directory) { + std::unique_ptr<InMemoryVolumeReader> reader = + std::make_unique<InMemoryVolumeReader>(volume); + VolumeArchiveMinizip archive(std::move(reader)); + ASSERT_TRUE(archive.Init("")); + + EXPECT_TRUE(archive.SeekHeader(path)); + std::string volume_file_path; + bool volume_is_utf8 = false; + int64_t volume_size = -1; + bool volume_is_directory = false; + time_t volume_mod_time = 0; + auto result = archive.GetCurrentFileInfo(&volume_file_path, &volume_is_utf8, + &volume_size, &volume_is_directory, + &volume_mod_time); + EXPECT_EQ(result, VolumeArchive::RESULT_SUCCESS); + EXPECT_EQ(size, volume_size); + EXPECT_EQ(mod_time.ToTimeT(), volume_mod_time); + EXPECT_EQ(is_directory, volume_is_directory); + } + + private: + std::unique_ptr<CompressorArchiveMinizip> archive_; +}; + +TEST_F(CompressorArchiveMinizipTest, Create) { + TestCompressorStream stream; + CompressorArchiveMinizip archive(&stream); + + const base::Time add_time = base::Time::Now(); + EXPECT_TRUE(archive.CreateArchive()); + stream.SetReadBuffer(kTestFileContent); + EXPECT_TRUE(archive.AddToArchive(kTestFileName, sizeof(kTestFileContent) - 1, + add_time, false)); + stream.SetReadBuffer(kLargeTestFileContent); + EXPECT_TRUE(archive.AddToArchive( + kLargeTestFileName, kLargeTestFileContent.size(), add_time, false)); + EXPECT_TRUE(archive.AddToArchive(kTestDirName, 0, add_time, true)); + + EXPECT_TRUE(archive.CloseArchive(false)); + EXPECT_FALSE(stream.write_buffer().empty()); + + CheckZipMetadata(stream.write_buffer(), kTestFileName, + sizeof(kTestFileContent) - 1, add_time, false); + CheckZipMetadata(stream.write_buffer(), kLargeTestFileName, + kLargeTestFileContent.size(), add_time, false); + CheckZipMetadata(stream.write_buffer(), std::string(kTestDirName) + "/", 0, + add_time, true); + + CheckZipContents(stream.write_buffer(), kTestFileName, kTestFileContent); + CheckZipContents(stream.write_buffer(), kLargeTestFileName, + kLargeTestFileContent); +} + +TEST_F(CompressorArchiveMinizipTest, Create_WriteError) { + TestCompressorStream stream; + CompressorArchiveMinizip archive(&stream); + + const base::Time add_time = base::Time::Now(); + EXPECT_TRUE(archive.CreateArchive()); + stream.SetReadBuffer(kTestFileContent); + EXPECT_TRUE(archive.AddToArchive(kTestFileName, sizeof(kTestFileContent) - 1, + add_time, false)); + stream.SetReadBuffer(kLargeTestFileContent); + stream.SetWriteError(); + EXPECT_FALSE(archive.AddToArchive( + kLargeTestFileName, kLargeTestFileContent.size(), add_time, false)); + EXPECT_FALSE(archive.error_message().empty()); +} + +TEST_F(CompressorArchiveMinizipTest, CreateAndCancel) { + TestCompressorStream stream; + CompressorArchiveMinizip archive(&stream); + + const base::Time add_time = base::Time::Now(); + EXPECT_TRUE(archive.CreateArchive()); + stream.SetReadBuffer(kTestFileContent); + EXPECT_TRUE(archive.AddToArchive(kTestFileName, sizeof(kTestFileContent) - 1, + add_time, false)); + stream.SetReadBuffer(kLargeTestFileContent); + archive.CancelArchive(); + EXPECT_FALSE(archive.AddToArchive( + kLargeTestFileName, kLargeTestFileContent.size(), add_time, false)); + EXPECT_TRUE(archive.error_message().empty()); +} + +} // namespace
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.cc b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.cc index 146e873..5b32737d 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.cc +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.cc
@@ -62,32 +62,96 @@ return exploded_time; } -}; // namespace - -namespace volume_archive_functions { -void* CustomArchiveOpen(void* archive, - const char* /* filename */, - int /* mode */) { +void* MinizipOpen(void* archive, const char* /* filename */, int /* mode */) { return archive; } -int64_t DynamicCache(VolumeArchiveMinizip* archive, int64_t unzip_size) { - int64_t offset = archive->reader()->offset(); - if (archive->reader()->Seek(static_cast<int64_t>(offset), - base::File::FROM_BEGIN) < 0) { +uint32_t MinizipWrite(void* /*archive*/, + void* /*stream*/, + const void* /*buffer*/, + uint32_t /*length*/) { + NOTREACHED(); + return 0; +} + +int MinizipClose(void* /*archive*/, void* /*stream*/) { + return 0; +} + +int MinizipError(void* /*archive*/, void* /*stream*/) { + return 0; +} + +}; // namespace + +uint32_t VolumeArchiveMinizip::MinizipRead(void* archive, + void* /* stream */, + void* buffer, + uint32_t size) { + return static_cast<VolumeArchiveMinizip*>(archive)->StreamRead(buffer, size); +} + +uint32_t VolumeArchiveMinizip::StreamRead(void* buffer, uint32_t size) { + int64_t offset = reader()->offset(); + + // When minizip requests a chunk in static_cache_. + if (offset >= static_cache_offset_) { + // Relative offset in the central directory. + int64_t offset_in_cache = offset - static_cache_offset_; + memcpy(buffer, static_cache_.get() + offset_in_cache, size); + if (reader()->Seek(static_cast<int64_t>(size), base::File::FROM_CURRENT) < + 0) { + return -1 /* Error */; + } + return size; + } + + char* unzip_buffer_pointer = static_cast<char*>(buffer); + int64_t left_length = static_cast<int64_t>(size); + + do { + offset = reader()->offset(); + // If dynamic_cache_ is empty or it cannot be reused, update the cache so + // that it contains the chunk required by minizip. + if (dynamic_cache_size_ == 0 || offset < dynamic_cache_offset_ || + dynamic_cache_offset_ + dynamic_cache_size_ < offset + size) { + if (DynamicCache(size) < 0) + return -1 /* Error */; + } + + // Just copy the required data from the cache. + int64_t offset_in_cache = offset - dynamic_cache_offset_; + int64_t copy_length = + std::min(left_length, dynamic_cache_size_ - offset_in_cache); + memcpy(unzip_buffer_pointer, dynamic_cache_.get() + offset_in_cache, + copy_length); + unzip_buffer_pointer += copy_length; + left_length -= copy_length; + if (reader()->Seek(static_cast<int64_t>(copy_length), + base::File::FROM_CURRENT) < 0) { + return -1 /* Error */; + } + } while (left_length > 0); + + return size; +} + +int64_t VolumeArchiveMinizip::DynamicCache(int64_t unzip_size) { + int64_t offset = reader()->offset(); + if (reader()->Seek(static_cast<int64_t>(offset), base::File::FROM_BEGIN) < + 0) { return -1 /* Error */; } - int64_t bytes_to_read = std::min(kMaximumDataChunkSize, - archive->reader()->archive_size() - offset); + int64_t bytes_to_read = + std::min(kMaximumDataChunkSize, reader()->archive_size() - offset); DCHECK_GT(bytes_to_read, 0); int64_t left_length = bytes_to_read; - char* buffer_pointer = archive->dynamic_cache_.get(); + char* buffer_pointer = dynamic_cache_.get(); const void* destination_buffer; do { - int64_t read_bytes = - archive->reader()->Read(left_length, &destination_buffer); + int64_t read_bytes = reader()->Read(left_length, &destination_buffer); // End of the zip file. if (read_bytes == 0) break; @@ -98,91 +162,33 @@ buffer_pointer += read_bytes; } while (left_length > 0); - if (archive->reader()->Seek(static_cast<int64_t>(offset), - base::File::FROM_BEGIN) < 0) { + if (reader()->Seek(static_cast<int64_t>(offset), base::File::FROM_BEGIN) < + 0) { return -1 /* Error */; } - archive->dynamic_cache_size_ = bytes_to_read - left_length; - archive->dynamic_cache_offset_ = offset; + dynamic_cache_size_ = bytes_to_read - left_length; + dynamic_cache_offset_ = offset; return unzip_size - left_length; } -uint32_t CustomArchiveRead(void* archive, - void* /* stream */, - void* buffer, - uint32_t size) { - VolumeArchiveMinizip* archive_minizip = - static_cast<VolumeArchiveMinizip*>(archive); - int64_t offset = archive_minizip->reader()->offset(); - - // When minizip requests a chunk in static_cache_. - if (offset >= archive_minizip->static_cache_offset_) { - // Relative offset in the central directory. - int64_t offset_in_cache = offset - archive_minizip->static_cache_offset_; - memcpy(buffer, archive_minizip->static_cache_.get() + offset_in_cache, - size); - if (archive_minizip->reader()->Seek(static_cast<int64_t>(size), - base::File::FROM_CURRENT) < 0) { - return -1 /* Error */; - } - return size; - } - - char* unzip_buffer_pointer = static_cast<char*>(buffer); - int64_t left_length = static_cast<int64_t>(size); - - do { - offset = archive_minizip->reader()->offset(); - // If dynamic_cache_ is empty or it cannot be reused, update the cache so - // that it contains the chunk required by minizip. - if (archive_minizip->dynamic_cache_size_ == 0 || - offset < archive_minizip->dynamic_cache_offset_ || - archive_minizip->dynamic_cache_offset_ + - archive_minizip->dynamic_cache_size_ < - offset + size) { - if (volume_archive_functions::DynamicCache(archive_minizip, size) < 0) - return -1 /* Error */; - } - - // Just copy the required data from the cache. - int64_t offset_in_cache = offset - archive_minizip->dynamic_cache_offset_; - int64_t copy_length = std::min( - left_length, archive_minizip->dynamic_cache_size_ - offset_in_cache); - memcpy(unzip_buffer_pointer, - archive_minizip->dynamic_cache_.get() + offset_in_cache, - copy_length); - unzip_buffer_pointer += copy_length; - left_length -= copy_length; - if (archive_minizip->reader()->Seek(static_cast<int64_t>(copy_length), - base::File::FROM_CURRENT) < 0) { - return -1 /* Error */; - } - } while (left_length > 0); - - return size; +long VolumeArchiveMinizip::MinizipTell(void* archive, void* /*stream*/) { + return static_cast<VolumeArchiveMinizip*>(archive)->StreamTell(); } -uint32_t CustomArchiveWrite(void* /*archive*/, - void* /*stream*/, - const void* /*buffer*/, - uint32_t /*length*/) { - return 0 /* Success */; +long VolumeArchiveMinizip::StreamTell() { + return static_cast<long>(reader()->offset()); } -long CustomArchiveTell(void* archive, void* /*stream*/) { - VolumeArchiveMinizip* archive_minizip = - static_cast<VolumeArchiveMinizip*>(archive); - return static_cast<long>(archive_minizip->reader()->offset()); +long VolumeArchiveMinizip::MinizipSeek(void* archive, + void* /*stream*/, + uint32_t offset, + int origin) { + return static_cast<VolumeArchiveMinizip*>(archive)->StreamSeek(offset, + origin); } -long CustomArchiveSeek(void* archive, - void* /*stream*/, - uint32_t offset, - int origin) { - VolumeArchiveMinizip* archive_minizip = - static_cast<VolumeArchiveMinizip*>(archive); - +long VolumeArchiveMinizip::StreamSeek(uint32_t offset, int origin) { base::File::Whence whence; switch (origin) { case ZLIB_FILEFUNC_SEEK_SET: @@ -199,28 +205,13 @@ return -1; } - long return_value = static_cast<long>( - archive_minizip->reader()->Seek(static_cast<int64_t>(offset), whence)); + long return_value = + static_cast<long>(reader()->Seek(static_cast<int64_t>(offset), whence)); if (return_value >= 0) return 0 /* Success */; return -1 /* Error */; } -int CustomArchiveClose(void* /*opaque*/, void* /*stream*/) { - return 0; -} - -int CustomArchiveError(void* /*opaque*/, void* /*stream*/) { - return 0; -} - -std::unique_ptr<std::string> GetPassphrase( - VolumeArchiveMinizip* archive_minizip) { - return archive_minizip->reader()->Passphrase(); -} - -} // namespace volume_archive_functions - VolumeArchiveMinizip::VolumeArchiveMinizip(std::unique_ptr<VolumeReader> reader) : VolumeArchive(std::move(reader)), reader_data_size_(kMinimumDataChunkSize), @@ -251,13 +242,13 @@ bool VolumeArchiveMinizip::Init(const std::string& encoding) { // Set up minizip object. zlib_filefunc_def zip_funcs; - zip_funcs.zopen_file = volume_archive_functions::CustomArchiveOpen; - zip_funcs.zread_file = volume_archive_functions::CustomArchiveRead; - zip_funcs.zwrite_file = volume_archive_functions::CustomArchiveWrite; - zip_funcs.ztell_file = volume_archive_functions::CustomArchiveTell; - zip_funcs.zseek_file = volume_archive_functions::CustomArchiveSeek; - zip_funcs.zclose_file = volume_archive_functions::CustomArchiveClose; - zip_funcs.zerror_file = volume_archive_functions::CustomArchiveError; + zip_funcs.zopen_file = MinizipOpen; + zip_funcs.zread_file = MinizipRead; + zip_funcs.zwrite_file = MinizipWrite; + zip_funcs.ztell_file = MinizipTell; + zip_funcs.zseek_file = MinizipSeek; + zip_funcs.zclose_file = MinizipClose; + zip_funcs.zerror_file = MinizipError; zip_funcs.opaque = static_cast<void*>(this); // Load maximum static_cache_size_ bytes from the end of the archive to @@ -400,7 +391,7 @@ do { if (password_cache_ == nullptr) { // Save passphrase for upcoming file requests. - password_cache_ = volume_archive_functions::GetPassphrase(this); + password_cache_ = reader()->Passphrase(); // check if |password_cache_| is nullptr in case when user clicks Cancel if (password_cache_ == nullptr) { return false;
diff --git a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.h b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.h index 7196fae..be871270 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.h +++ b/chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive_minizip.h
@@ -14,31 +14,6 @@ #include "chrome/browser/resources/chromeos/zip_archiver/cpp/volume_archive.h" -class VolumeArchiveMinizip; - -// A namespace with custom functions passed to minizip. -namespace volume_archive_functions { - -int64_t DynamicCache(VolumeArchiveMinizip* archive, int64_t unz_size); - -uint32_t CustomArchiveRead(void* archive, - void* stream, - void* buf, - uint32_t size); - -// Returns the offset from the beginning of the data. -long CustomArchiveTell(void* archive, void* stream); - -// Moves the current offset to the specified position. -long CustomArchiveSeek(void* archive, - void* stream, - uint32_t offset, - int origin); - -} // namespace volume_archive_functions - -class VolumeArchiveMinizip; - // Defines an implementation of VolumeArchive that wraps all minizip // operations. class VolumeArchiveMinizip : public VolumeArchive { @@ -70,28 +45,26 @@ // See volume_archive_interface.h. void MaybeDecompressAhead() override; - int64_t reader_data_size() const { return reader_data_size_; } - - // Custom functions need to access private variables of - // CompressorArchiveMinizip frequently. - friend int64_t volume_archive_functions::DynamicCache( - VolumeArchiveMinizip* va, - int64_t unz_size); - - friend uint32_t volume_archive_functions::CustomArchiveRead(void* archive, - void* stream, - void* buf, - uint32_t size); - - friend long volume_archive_functions::CustomArchiveTell(void* archive, - void* stream); - - friend long volume_archive_functions::CustomArchiveSeek(void* archive, - void* stream, - uint32_t offset, - int origin); - private: + // Stream functions used by minizip. In all cases, |archive| points to |this|. + static uint32_t MinizipRead(void* archive, + void* stream, + void* buf, + uint32_t size); + static long MinizipTell(void* archive, void* stream); + static long MinizipSeek(void* archive, + void* stream, + uint32_t offset, + int origin); + + // Implementation of stream functions used by minizip. + uint32_t StreamRead(void* buf, uint32_t size); + long StreamTell(); + long StreamSeek(uint32_t offset, int origin); + + // Read cache. + int64_t DynamicCache(int64_t unz_size); + // Decompress length bytes of data starting from offset. void DecompressData(int64_t offset, int64_t length);
diff --git a/chrome/browser/resources/print_preview/new/advanced_settings_dialog.js b/chrome/browser/resources/print_preview/new/advanced_settings_dialog.js index af92c9a7..9ea1f68 100644 --- a/chrome/browser/resources/print_preview/new/advanced_settings_dialog.js +++ b/chrome/browser/resources/print_preview/new/advanced_settings_dialog.js
@@ -42,12 +42,7 @@ attached: function() { this.metrics_.record(print_preview.Metrics.PrintSettingsUiBucket .ADVANCED_SETTINGS_DIALOG_SHOWN); - // This async() call is a workaround to prevent a DCHECK - see - // https://crbug.com/804047. - // TODO(rbpotter): Remove after Polymer2 migration is complete. - this.async(() => { - this.$.dialog.showModal(); - }, 1); + this.$.dialog.showModal(); }, /**
diff --git a/chrome/browser/resources/print_preview/new/destination_list.js b/chrome/browser/resources/print_preview/new/destination_list.js index 0b89769..0bf39f1 100644 --- a/chrome/browser/resources/print_preview/new/destination_list.js +++ b/chrome/browser/resources/print_preview/new/destination_list.js
@@ -27,6 +27,7 @@ loadingDestinations: { type: Boolean, value: false, + observer: 'forceIronResize', }, listName: String,
diff --git a/chrome/browser/resources/print_preview/new/destination_settings.js b/chrome/browser/resources/print_preview/new/destination_settings.js index f635138..e3477e1 100644 --- a/chrome/browser/resources/print_preview/new/destination_settings.js +++ b/chrome/browser/resources/print_preview/new/destination_settings.js
@@ -87,12 +87,7 @@ this.destinationStore.startLoadAllDestinations(); this.invitationStore.startLoadingInvitations(); const dialog = this.$.destinationDialog.get(); - // This async() call is a workaround to prevent a DCHECK - see - // https://crbug.com/804047. - // TODO(rbpotter): Remove after Polymer2 migration is complete. - this.async(() => { - dialog.show(); - }, 1); + dialog.show(); }, showCloudPrintPromo: function() {
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/BUILD.gn b/chrome/browser/resources/welcome/onboarding_welcome/BUILD.gn index 7de44a61..5177fbd1 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/BUILD.gn +++ b/chrome/browser/resources/welcome/onboarding_welcome/BUILD.gn
@@ -16,6 +16,7 @@ js_type_check("welcome_files") { deps = [ ":landing_view", + ":signin_view", ":welcome_app", ] } @@ -27,6 +28,13 @@ ] } +js_library("signin_view") { + deps = [ + ":navigation_behavior", + ":welcome_browser_proxy", + ] +} + js_library("navigation_behavior") { deps = [ "//ui/webui/resources/js:cr",
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/email/BUILD.gn b/chrome/browser/resources/welcome/onboarding_welcome/email/BUILD.gn index f2c5261..b24bc99b 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/email/BUILD.gn +++ b/chrome/browser/resources/welcome/onboarding_welcome/email/BUILD.gn
@@ -20,6 +20,7 @@ js_library("email_chooser") { deps = [ ":nux_email_proxy", + "../:navigation_behavior", "//third_party/polymer/v1_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer-extracted", "//ui/webui/resources/js:cr", "//ui/webui/resources/js:i18n_behavior",
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/email/email_chooser.html b/chrome/browser/resources/welcome/onboarding_welcome/email/email_chooser.html index d588831..f014194 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/email/email_chooser.html +++ b/chrome/browser/resources/welcome/onboarding_welcome/email/email_chooser.html
@@ -8,7 +8,8 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-announcer/iron-a11y-announcer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> -<link rel="import" href="chrome://welcome/shared/chooser_shared_css.html"> +<link rel="import" href="../navigation_behavior.html"> +<link rel="import" href="../shared/chooser_shared_css.html"> <link rel="import" href="../shared/i18n_setup.html"> <link rel="import" href="nux_email_proxy.html">
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/email/email_chooser.js b/chrome/browser/resources/welcome/onboarding_welcome/email/email_chooser.js index 01bed2c..b9891cc 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/email/email_chooser.js +++ b/chrome/browser/resources/welcome/onboarding_welcome/email/email_chooser.js
@@ -70,7 +70,7 @@ if (this.selectedEmailProvider_) { this.browserProxy_.recordProviderSelected( - this.selectedEmailProvider_.id); + this.selectedEmailProvider_.id, this.emailList_.length); } this.browserProxy_.recordFinalize(); @@ -170,15 +170,18 @@ this.revertBookmark_(); this.browserProxy_.toggleBookmarkBar(this.bookmarkBarWasShown_); this.browserProxy_.recordNoThanks(); - window.location.replace('chrome://newtab'); + welcome.navigateToNextStep(); }, /** @private */ onGetStartedClicked_: function() { this.finalized_ = true; - this.browserProxy_.recordProviderSelected(this.selectedEmailProvider_.id); + this.browserProxy_.recordProviderSelected( + this.selectedEmailProvider_.id, this.emailList_.length); this.browserProxy_.recordGetStarted(); - window.location.replace(this.selectedEmailProvider_.url); + // TODO(scottchen): store the selected email provider URL somewhere to + // redirect to at the end. + welcome.navigateToNextStep(); }, /** @private */
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/email/nux_email.html b/chrome/browser/resources/welcome/onboarding_welcome/email/nux_email.html index 83b6458..4652da4 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/email/nux_email.html +++ b/chrome/browser/resources/welcome/onboarding_welcome/email/nux_email.html
@@ -1,77 +1,63 @@ -<!DOCTYPE html> -<html dir="$i18n{textdirection}" lang="$i18n{language}"> -<head> - <meta charset="utf-8"> - <title>$i18n{headerText}</title> - <link rel="import" href="chrome://resources/html/polymer.html"> - <link rel="import" href="email_chooser.html"> +<link rel="import" href="chrome://resources/html/polymer.html"> - <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> - <style> - body { - margin: 0; - } - </style> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> +<link rel="import" href="email_chooser.html"> - <dom-module id="nux-email"> - <template> - <style> - :host { - align-items: center; - display: flex; - height: fit-content; - margin: auto; - min-height: 100vh; - width: fit-content; - } +<dom-module id="nux-email"> + <template> + <style> + :host-context(#viewManager):host([slot='view']) { + /* Unsets cr-view-manager's styling to make all views full-page, and + allows the content to be centered horizontally/vertically on the + page. */ + bottom: initial; + left: initial; + right: initial; + top: initial; + } - .email-ask { - text-align: center; - } + .email-ask { + text-align: center; + } - .email-logo { - content: -webkit-image-set( - url(chrome://welcome/logo.png) 1x, - url(chrome://welcome/logo2x.png) 2x); - height: 48px; - margin: auto; - margin-bottom: 16px; - width: 48px; - } + .email-logo { + content: -webkit-image-set( + url(chrome://welcome/logo.png) 1x, + url(chrome://welcome/logo2x.png) 2x); + height: 48px; + margin: auto; + margin-bottom: 16px; + width: 48px; + } - h1 { - color: #202124; - font-size: 1.5rem; - font-weight: 500; - line-height: 2.5rem; - margin: 0; - } + h1 { + color: var(--google-grey-900); + font-size: 1.5rem; + font-weight: 500; + line-height: 2.5rem; + margin: 0; + } - h2 { - color: #202124; - font-size: 1.125rem; - font-weight: unset; - line-height: 2rem; - margin: 0; - margin-bottom: 48px; - } + h2 { + color: var(--google-grey-900); + font-size: 1.125rem; + font-weight: unset; + line-height: 2rem; + margin: 0; + margin-bottom: 48px; + } - #emailChooser { - color: #202124; - margin-bottom: 48px; - } - </style> - <div class="email-ask"> - <div class="email-logo" alt=""></div> - <h1>$i18n{welcomeTitle}</h1> - <h2>$i18n{emailPrompt}</h2> - <email-chooser id="emailChooser"></email-chooser> - </div> - </template> - <script src="nux_email.js"></script> - </dom-module> -</head> -<body> - <nux-email></nux-email> -</body> -</html> \ No newline at end of file + #emailChooser { + color: var(--google-grey-900); + margin-bottom: 48px; + } + </style> + <div class="email-ask"> + <div class="email-logo" alt=""></div> + <h1>$i18n{welcomeTitle}</h1> + <h2>$i18n{emailPrompt}</h2> + <email-chooser id="emailChooser"></email-chooser> + </div> + </template> + <script src="nux_email.js"></script> +</dom-module> \ No newline at end of file
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/email/nux_email_proxy.js b/chrome/browser/resources/welcome/onboarding_welcome/email/nux_email_proxy.js index bab40557..b7cc4b1 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/email/nux_email_proxy.js +++ b/chrome/browser/resources/welcome/onboarding_welcome/email/nux_email_proxy.js
@@ -76,8 +76,9 @@ /** * @param {number} providerId This should match one of the histogram enum * value for NuxEmailProvidersSelections. + * @param {number} length */ - recordProviderSelected(providerId) {} + recordProviderSelected(providerId, length) {} recordNoThanks() {} @@ -145,10 +146,11 @@ } /** @override */ - recordProviderSelected(providerId) { + recordProviderSelected(providerId, length) { + // TODO(hcarmona): get enum's max from loadTimeData instead, since length + // might not be accurate once we start localizing. chrome.metricsPrivate.recordEnumerationValue( - SELECTION_METRIC_NAME, providerId, - loadTimeData.getInteger('email_count')); + SELECTION_METRIC_NAME, providerId, length); } /** @override */
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/google_apps/BUILD.gn b/chrome/browser/resources/welcome/onboarding_welcome/google_apps/BUILD.gn index c4e96fa3..d4c820e 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/google_apps/BUILD.gn +++ b/chrome/browser/resources/welcome/onboarding_welcome/google_apps/BUILD.gn
@@ -21,6 +21,7 @@ deps = [ ":apps_chooser", ":nux_google_apps_proxy", + "../:navigation_behavior", "../shared:nux_types", ] }
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/google_apps/nux_google_apps.html b/chrome/browser/resources/welcome/onboarding_welcome/google_apps/nux_google_apps.html index fe8a9322..43f6569 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/google_apps/nux_google_apps.html +++ b/chrome/browser/resources/welcome/onboarding_welcome/google_apps/nux_google_apps.html
@@ -1,27 +1,28 @@ -<!DOCTYPE html> -<html dir="$i18n{textdirection}" lang="$i18n{language}"> -<meta charset="utf-8"> -<title>$i18n{headerText}</title> - <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> +<link rel="import" href="../navigation_behavior.html"> <link rel="import" href="apps_chooser.html"> <link rel="import" href="nux_google_apps_proxy.html"> <dom-module id="nux-google-apps"> <template> <style include="paper-button-style"> - body { - margin: 0; + :host-context(#viewManager):host([slot='view']) { + /* Unsets cr-view-manager's styling to make all views full-page, and + allows the content to be centered horizontally/vertically on the + page. */ + bottom: initial; + left: initial; + right: initial; + top: initial; } .apps-ask { margin-left: auto; margin-right: auto; - margin-top: 120px; width: fit-content; } @@ -75,8 +76,3 @@ </template> <script src="nux_google_apps.js"></script> </dom-module> - -<nux-google-apps></nux-google-apps> -<link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> - -</html> \ No newline at end of file
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/google_apps/nux_google_apps.js b/chrome/browser/resources/welcome/onboarding_welcome/google_apps/nux_google_apps.js index 911ec744..90c0370 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/google_apps/nux_google_apps.js +++ b/chrome/browser/resources/welcome/onboarding_welcome/google_apps/nux_google_apps.js
@@ -13,13 +13,13 @@ /** @private */ onNoThanksClicked_: function() { chrome.send('rejectGoogleApps'); - window.location.replace('chrome://newtab'); + welcome.navigateToNextStep(); }, /** @private */ onGetStartedClicked_: function() { let selectedApps = this.$.appChooser.getSelectedAppList(); nux.NuxGoogleAppsProxyImpl.getInstance().addGoogleApps(selectedApps); - window.location.replace('chrome://newtab'); + welcome.navigateToNextStep(); }, });
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/blue_circle.svg b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/blue_circle.svg new file mode 100644 index 0000000..3f34976 --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/blue_circle.svg
@@ -0,0 +1,3 @@ +<svg width="43px" height="43px" viewBox="0 0 43 43" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <circle fill="#1A73E8" fill-rule="evenodd" cx="21.5" cy="21.5" r="21.5"></circle> +</svg> \ No newline at end of file
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/green_rectangle.svg b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/green_rectangle.svg new file mode 100644 index 0000000..8cb0471 --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/green_rectangle.svg
@@ -0,0 +1,3 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="371" height="371" viewBox="0 0 371 371"> + <path fill="#31A753" fill-rule="evenodd" d="M7.61078518,166.895209 L166.895209,7.61078518 C177.042923,-2.53692839 193.495617,-2.53692839 203.643331,7.61078518 L362.935748,166.903202 C373.083461,177.050916 373.083461,193.50361 362.935748,203.651324 L203.651324,362.935748 C193.50361,373.083461 177.050916,373.083461 166.903202,362.935748 L7.61078518,203.643331 C-2.53692839,193.495617 -2.53692839,177.042923 7.61078518,166.895209 Z"/> +</svg>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/grey_oval.svg b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/grey_oval.svg new file mode 100644 index 0000000..cf75ceb --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/grey_oval.svg
@@ -0,0 +1,3 @@ +<svg width="100px" height="100px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <circle fill-rule="evenodd" fill="#F1F3F4" cx="50" cy="50" r="50"></circle> +</svg> \ No newline at end of file
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/grey_rounded_rectangle.svg b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/grey_rounded_rectangle.svg new file mode 100644 index 0000000..71f9fd6 --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/grey_rounded_rectangle.svg
@@ -0,0 +1,3 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="132" height="132" viewBox="0 0 132 132"> + <path fill="#F1F3F4" fill-rule="evenodd" d="M81.6025226,14.0007794 L117.999221,50.3974774 C136.666926,69.0651833 136.666926,99.3315147 117.999221,117.999221 C99.3315147,136.666926 69.0651833,136.666926 50.3974774,117.999221 L14.0007794,81.6025226 C-4.66692648,62.9348167 -4.66692648,32.6684853 14.0007794,14.0007794 C32.6684853,-4.66692648 62.9348167,-4.66692648 81.6025226,14.0007794 Z"/> +</svg>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/red_triangle.svg b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/red_triangle.svg new file mode 100644 index 0000000..d89d1ae --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/red_triangle.svg
@@ -0,0 +1,3 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="65" height="74" viewBox="0 0 65 74"> + <path fill="#E94235" fill-rule="evenodd" d="M64.5429228,7.29310524 L64.3644898,67.9344347 C64.1624511,71.340818 61.2707769,73.9365373 57.9057548,73.732136 C56.9598601,73.6746796 56.0401784,73.3950765 55.2195428,72.9154694 L3.60676683,42.7512281 C0.687353928,41.0450251 -0.312855086,37.266089 1.37273747,34.3107382 C1.84655098,33.4800006 2.50492275,32.7723367 3.29571384,32.2437891 L55.0869229,1.76670102 C57.9001639,-0.113607947 61.6864522,0.670655917 63.5438345,3.51840338 C64.2715067,4.63407375 64.6220761,5.95857646 64.5429228,7.29310524 Z"/> +</svg>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/yellow_dots.svg b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/yellow_dots.svg new file mode 100644 index 0000000..41ce568b --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/yellow_dots.svg
@@ -0,0 +1,46 @@ +<svg width="76px" height="57px" viewBox="0 0 76 57" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <g fill-rule="evenodd" fill="#FDD663"> + <circle cx="14" cy="13" r="2"></circle> + <circle cx="14" cy="2" r="2"></circle> + <circle cx="14" cy="23" r="2"></circle> + <circle cx="14" cy="34" r="2"></circle> + <circle cx="14" cy="45" r="2"></circle> + <circle cx="14" cy="55" r="2"></circle> + <circle cx="2" cy="13" r="2"></circle> + <circle cx="2" cy="2" r="2"></circle> + <circle cx="2" cy="23" r="2"></circle> + <circle cx="2" cy="34" r="2"></circle> + <circle cx="2" cy="45" r="2"></circle> + <circle cx="2" cy="55" r="2"></circle> + <circle cx="26" cy="13" r="2"></circle> + <circle cx="26" cy="2" r="2"></circle> + <circle cx="26" cy="23" r="2"></circle> + <circle cx="26" cy="34" r="2"></circle> + <circle cx="26" cy="45" r="2"></circle> + <circle cx="26" cy="55" r="2"></circle> + <circle cx="38" cy="13" r="2"></circle> + <circle cx="38" cy="2" r="2"></circle> + <circle cx="38" cy="23" r="2"></circle> + <circle cx="38" cy="34" r="2"></circle> + <circle cx="38" cy="45" r="2"></circle> + <circle cx="38" cy="55" r="2"></circle> + <circle cx="50" cy="13" r="2"></circle> + <circle cx="50" cy="2" r="2"></circle> + <circle cx="50" cy="23" r="2"></circle> + <circle cx="50" cy="34" r="2"></circle> + <circle cx="50" cy="45" r="2"></circle> + <circle cx="50" cy="55" r="2"></circle> + <circle cx="62" cy="13" r="2"></circle> + <circle cx="62" cy="2" r="2"></circle> + <circle cx="62" cy="23" r="2"></circle> + <circle cx="62" cy="34" r="2"></circle> + <circle cx="62" cy="45" r="2"></circle> + <circle cx="62" cy="55" r="2"></circle> + <circle cx="74" cy="13" r="2"></circle> + <circle cx="74" cy="2" r="2"></circle> + <circle cx="74" cy="23" r="2"></circle> + <circle cx="74" cy="34" r="2"></circle> + <circle cx="74" cy="45" r="2"></circle> + <circle cx="74" cy="55" r="2"></circle> + </g> +</svg> \ No newline at end of file
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/yellow_semicircle.svg b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/yellow_semicircle.svg new file mode 100644 index 0000000..3fe924d --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/images/background_svgs/yellow_semicircle.svg
@@ -0,0 +1,3 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="211" height="171" viewBox="0 0 211 171"> + <path fill="#FACF4C" fill-rule="evenodd" d="M152.95531,155.322875 C102.461259,184.681893 39.1648672,171.482614 4.01772623,126.776523 C0.528185501,122.337934 -5.16163709,112.29754 9.88388926,103.549542 C48.9517191,80.8341309 106.527836,47.3573508 182.61224,3.1192014 C196.248192,-4.80922088 200.05639,4.35165919 201.923,8.80779391 C224.340646,62.3251755 204.196032,125.529716 152.95531,155.322875 Z"/> +</svg>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/landing_view.html b/chrome/browser/resources/welcome/onboarding_welcome/landing_view.html index e5046308..1d58cd1 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/landing_view.html +++ b/chrome/browser/resources/welcome/onboarding_welcome/landing_view.html
@@ -4,11 +4,13 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> <link rel="import" href="navigation_behavior.html"> +<link rel="import" href="shared/action_link_style_css.html"> +<link rel="import" href="shared/onboarding_background.html"> <link rel="import" href="welcome_browser_proxy.html"> <dom-module id="landing-view"> <template> - <style include="paper-button-style"> + <style include="paper-button-style action-link-style"> #container { align-items: center; display: flex; @@ -16,37 +18,50 @@ height: 100%; justify-content: center; margin: auto; - width: 800px; + min-width: 800px; } h1 { font-size: 4rem; - margin-bottom: 20px; + margin-bottom: 40px; + margin-top: 16px; } h2 { color: darkgrey; font-size: 1.5rem; + font-weight: 500; + line-height: 2.25rem; + margin: 0; } paper-button { font-size: 1rem; - height: 2.5rem; + height: 3rem; + padding-bottom: 12px; + padding-top: 12px; text-align: center; white-space: nowrap; - width: 220px; + width: 256px; + } + + .action-link { + font-size: 1rem; + font-weight: 500; + margin-top: 24px; } </style> <!-- TODO(scottchen): localize --> + <onboarding-background></onboarding-background> <div id="container"> <h2>Set up your browser in a few simple steps</h2> <h1>Make Chrome your own</h1> <paper-button class="action-button" on-click="onNewUserClick_"> Get Started </paper-button> - <paper-button on-click="onExistingUserClick_"> - Already set up? Sign in - </paper-button> + <button class="action-link" on-click="onExistingUserClick_"> + Already a Chrome user? Sign in + </button> </div> </template> <script src="landing_view.js"></script>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/landing_view.js b/chrome/browser/resources/welcome/onboarding_welcome/landing_view.js index 925b6fd..5e3f4f3 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/landing_view.js +++ b/chrome/browser/resources/welcome/onboarding_welcome/landing_view.js
@@ -5,8 +5,6 @@ Polymer({ is: 'landing-view', - behaviors: [welcome.NavigationBehavior], - /** @private */ onExistingUserClick_: function() { welcome.WelcomeBrowserProxyImpl.getInstance().handleActivateSignIn( @@ -15,6 +13,6 @@ /** @private */ onNewUserClick_: function() { - this.navigateTo(welcome.Routes.NEW_USER, 1); + welcome.navigateTo(welcome.Routes.NEW_USER, 1); } });
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/navigation_behavior.js b/chrome/browser/resources/welcome/onboarding_welcome/navigation_behavior.js index c1cdfa6..baf9bbbc 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/navigation_behavior.js +++ b/chrome/browser/resources/welcome/onboarding_welcome/navigation_behavior.js
@@ -57,13 +57,44 @@ const route = /** @type {!welcome.Routes} */ (history.state.route); const step = history.state.step; routeObservers.forEach((observer) => { - observer.onRouteChange(route, step); + (/** @type {{onRouteChange: Function}} */ (observer)) + .onRouteChange(route, step); }); } // Notifies all elements when browser history is popped. window.addEventListener('popstate', notifyObservers); + function navigateToNextStep() { + history.pushState( + { + route: history.state.route, + step: history.state.step + 1, + }, + '', `/${history.state.route}`); + notifyObservers(); + } + + /** + * @param {!welcome.Routes} route + * @param {number} step + */ + function navigateTo(route, step) { + assert([ + Routes.LANDING, + Routes.NEW_USER, + Routes.RETURNING_USER, + ].includes(route)); + + history.pushState( + { + route: route, + step: step, + }, + '', '/' + (route === Routes.LANDING ? '' : route)); + notifyObservers(); + } + /** @polymerBehavior */ const NavigationBehavior = { /** @override */ @@ -85,40 +116,12 @@ /** Elements can override onRouteChange to handle route changes. */ onRouteChange: function() {}, - - navigateToNextStep: function() { - history.pushState( - { - route: history.state.route, - step: history.state.step + 1, - }, - '', `/${history.state.route}`); - notifyObservers(); - }, - - /** - * @param {!welcome.Routes} route - * @param {number} step - */ - navigateTo: function(route, step) { - assert([ - Routes.LANDING, - Routes.NEW_USER, - Routes.RETURNING_USER, - ].includes(route)); - - history.pushState( - { - route: route, - step: step, - }, - '', '/' + (route === Routes.LANDING ? '' : route)); - notifyObservers(); - }, }; return { NavigationBehavior: NavigationBehavior, + navigateTo: navigateTo, + navigateToNextStep: navigateToNextStep, Routes: Routes, }; }); \ No newline at end of file
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/BUILD.gn b/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/BUILD.gn index cf61b6c..cb4851f 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/BUILD.gn +++ b/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/BUILD.gn
@@ -13,6 +13,7 @@ js_library("nux_set_as_default") { deps = [ ":nux_set_as_default_proxy", + "../:navigation_behavior", "//ui/webui/resources/js:web_ui_listener_behavior", ] }
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.html b/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.html index 0e29e03..60125a1 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.html +++ b/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.html
@@ -1,97 +1,87 @@ -<!DOCTYPE html> -<html dir="$i18n{textdirection}" lang="$i18n{language}"> -<head> - <meta charset="utf-8"> - <title>$i18n{headerText}</title> - <link rel="import" href="chrome://resources/html/polymer.html"> - <link rel="import" href="chrome://resources/cr_elements/icons.html"> - <link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> - <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> - <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> - <link rel="import" href="nux_set_as_default_proxy.html"> - <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> - <style> - body { - margin: 0; - } - </style> +<link rel="import" href="chrome://resources/html/polymer.html"> - <dom-module id="nux-set-as-default"> - <template> - <style include="paper-button-style"> - :host { - align-items: center; - display: flex; - height: 100vh; - justify-content: space-around; - } +<link rel="import" href="chrome://resources/cr_elements/icons.html"> +<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> +<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> +<link rel="import" href="../navigation_behavior.html"> +<link rel="import" href="nux_set_as_default_proxy.html"> - .container { - text-align: center; - width: 800px; - } +<dom-module id="nux-set-as-default"> + <template> + <style include="paper-button-style"> + :host-context(#viewManager):host([slot='view']) { + /* Unsets cr-view-manager's styling to make all views full-page, and + allows the content to be centered horizontally/vertically on the + page. */ + bottom: initial; + left: initial; + right: initial; + top: initial; + } - .logo { - margin-bottom: 16px; - /* TODO(scottchen): placeholder; replace when asset is available. */ - width: 32px; - height: 32px; - display: inline-block; - background: red; - } + .container { + text-align: center; + width: 800px; + } - h1 { - color: #202124; - font-weight: 500; - font-size: 1.5rem; - line-height: 2.5rem; - margin: 0; - } + .logo { + /* TODO(scottchen): placeholder; replace when asset is available. */ + background: red; + display: inline-block; + height: 32px; + margin-bottom: 16px; + width: 32px; + } - h2 { - color: #202124; - font-weight: unset; - font-size: 1.25rem; - line-height: 1.875rem; - margin: 0; - margin-top: 16px; - margin-bottom: 48px; - } + h1 { + color: var(--google-grey-900); + font-size: 1.5rem; + font-weight: 500; + line-height: 2.5rem; + margin: 0; + } - img { - /* TODO(scottchen): placeholder; replace when asset is available. */ - width: 454px; - height: 186px; - display: inline-block; - background: red; - } + h2 { + color: var(--google-grey-900); + font-size: 1.25rem; + font-weight: unset; + line-height: 1.875rem; + margin: 0; + margin-bottom: 48px; + margin-top: 16px; + } - .button-bar { - display: flex; - margin-top: 64px; - justify-content: space-between; - } - </style> - <div class="container"> - <div class="logo"></div> - <h1>TODO_HEADER</h1> - <h2>TODO_SUBHEADER</h2> - <!-- TODO(scottchen): WIP behind feature flag, add src later. --> - <img> - <div class="button-bar"> - <paper-button on-click="onDeclineClick_"> - TODO_NO_THANKS - </paper-button> - <paper-button class="action-button" on-click="onSetDefaultClick_"> - TODO_SET_AS_DEFAULT - </paper-button> - </div> + img { + /* TODO(scottchen): placeholder; replace when asset is available. */ + background: red; + display: inline-block; + height: 186px; + width: 454px; + } + + .button-bar { + display: flex; + justify-content: space-between; + margin-top: 64px; + } + </style> + <div class="container"> + <div class="logo"></div> + <h1>TODO_HEADER</h1> + <h2>TODO_SUBHEADER</h2> + <!-- TODO(scottchen): WIP behind feature flag, add src later. --> + <img> + <div class="button-bar"> + <paper-button on-click="onDeclineClick_"> + TODO_NO_THANKS + </paper-button> + <paper-button class="action-button" on-click="onSetDefaultClick_"> + TODO_SET_AS_DEFAULT + </paper-button> </div> - </template> - <script src="nux_set_as_default.js"></script> - </dom-module> -</head> -<body> - <nux-set-as-default></nux-set-as-default> -</body> -</html> \ No newline at end of file + </div> + </template> + <script src="nux_set_as_default.js"></script> +</dom-module> \ No newline at end of file
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.js b/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.js index 97e443a..4e22f8e 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.js +++ b/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.js
@@ -45,7 +45,6 @@ /** @private */ finished_: function() { - // TODO(scottchen): use navigation behavior to go to next step once this - // module is integrated with onboarding-welcome's welcome-app. + welcome.navigateToNextStep(); }, });
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/shared/action_link_style.js b/chrome/browser/resources/welcome/onboarding_welcome/shared/action_link_style.js new file mode 100644 index 0000000..b4e52c4b --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/shared/action_link_style.js
@@ -0,0 +1,9 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Initiates focus-outline-manager for this document so that + * action-link style can take advantage of it. + */ +cr.ui.FocusOutlineManager.forDocument(document); \ No newline at end of file
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/shared/action_link_style_css.html b/chrome/browser/resources/welcome/onboarding_welcome/shared/action_link_style_css.html new file mode 100644 index 0000000..b4fb1e7 --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/shared/action_link_style_css.html
@@ -0,0 +1,34 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> +<link rel="import" href="chrome://resources/html/cr/ui/focus_outline_manager.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> + +<dom-module id="action-link-style"> + <template> + <style> + button.action-link { + @apply --cr-actionable; + -webkit-appearance: none; + background: none; + border: none; + color: var(--google-blue-700); + display: inline-block; + font-family: inherit; + text-decoration: none; + } + + button.action-link[disabled] { + color: var(--paper-grey-600); + cursor: default; + opacity: 0.65; + } + + :host-context(html:not(.focus-outline-visible)) button.action-link { + outline: none; + } + </style> + </template> +</dom-module> + +<script src="action_link_style.js"></script> \ No newline at end of file
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/shared/i18n_setup.html b/chrome/browser/resources/welcome/onboarding_welcome/shared/i18n_setup.html index fa9610d..c505b2c13 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/shared/i18n_setup.html +++ b/chrome/browser/resources/welcome/onboarding_welcome/shared/i18n_setup.html
@@ -1,2 +1,2 @@ <script src="chrome://resources/js/load_time_data.js"></script> -<script src="../strings.js"></script> \ No newline at end of file +<script src="../strings.js"></script>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/shared/onboarding_background.html b/chrome/browser/resources/welcome/onboarding_welcome/shared/onboarding_background.html new file mode 100644 index 0000000..d16b04a --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/shared/onboarding_background.html
@@ -0,0 +1,80 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<dom-module id="onboarding-background"> + <template> + <style> + :host { + position: absolute; + left: 0; + right: 0; + bottom: 0; + top: 0; + overflow: hidden; + max-width: 1280px; + margin: auto; + z-index: -1; + } + + /* The entire container is anchored at the center of the page, and each + is positioned relative to the center. */ + #container { + position: absolute; + left: 50%; + top: 50%; + } + + img { + position: absolute; + } + + #blue-circle { + right: 611px; + bottom: 255px; + } + + #yellow-dots { + right: 397px; + bottom: 194px; + } + + #grey-rounded-rectangle { + right: 573px; + top: -43px; + } + + #red-triangle { + top: 187px; + right: 405px; + } + + #yellow-semicircle { + bottom: 282px; + left: 60px; + } + + #green-rectangle { + left: 483px; + top: -77px; + } + + #grey-oval { + left: 420px; + top: 130px; + mix-blend-mode: multiply; + } + </style> + <div id="container"> + <img id="blue-circle" src="../images/background_svgs/blue_circle.svg"> + <img id="green-rectangle" + src="../images/background_svgs/green_rectangle.svg"> + <img id="grey-oval" src="../images/background_svgs/grey_oval.svg"> + <img id="grey-rounded-rectangle" + src="../images/background_svgs/grey_rounded_rectangle.svg"> + <img id="red-triangle" src="../images/background_svgs/red_triangle.svg"> + <img id="yellow-dots" src="../images/background_svgs/yellow_dots.svg"> + <img id="yellow-semicircle" + src="../images/background_svgs/yellow_semicircle.svg"> + </div> + </template> + <script src="onboarding_background.js"></script> +</dom-module> \ No newline at end of file
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/shared/onboarding_background.js b/chrome/browser/resources/welcome/onboarding_welcome/shared/onboarding_background.js new file mode 100644 index 0000000..12358fa --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/shared/onboarding_background.js
@@ -0,0 +1,11 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview This element contains a set of SVGs that together acts as an + * animated and responsive background for any page that contains it. + */ +Polymer({ + is: 'onboarding-background', +}); \ No newline at end of file
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/signin_view.html b/chrome/browser/resources/welcome/onboarding_welcome/signin_view.html new file mode 100644 index 0000000..a03cb4f --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/signin_view.html
@@ -0,0 +1,53 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> +<link rel="import" href="navigation_behavior.html"> +<link rel="import" href="welcome_browser_proxy.html"> + +<dom-module id="signin-view"> + <template> + <style include="paper-button-style"> + #container { + align-items: center; + display: flex; + flex-direction: column; + height: 100%; + justify-content: center; + margin: auto; + width: 800px; + } + + h1 { + font-size: 4rem; + margin-bottom: 20px; + } + + h2 { + color: darkgrey; + font-size: 1.5rem; + } + + paper-button { + font-size: 1rem; + height: 2.5rem; + text-align: center; + white-space: nowrap; + width: 220px; + } + </style> + <!-- TODO(scottchen): localize --> + <div id="container"> + <h2>TODO Sign in to get your bookmarks on all devices</h2> + <h1>TODO Save your progress</h1> + <paper-button class="action-button" on-click="onSignInClick_"> + Sign in + </paper-button> + <paper-button on-click="onNoThanksClick_"> + No thanks + </paper-button> + </div> + </template> + <script src="signin_view.js"></script> +</dom-module> \ No newline at end of file
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/signin_view.js b/chrome/browser/resources/welcome/onboarding_welcome/signin_view.js new file mode 100644 index 0000000..ea50c42d --- /dev/null +++ b/chrome/browser/resources/welcome/onboarding_welcome/signin_view.js
@@ -0,0 +1,22 @@ +// Copyright 2018 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. + +Polymer({ + is: 'signin-view', + + behaviors: [welcome.NavigationBehavior], + + /** @private */ + onSignInClick_: function() { + // TODO(scottchen): create a feature flag to direct part of the users to + // chrome://welcome/email-interstitial instead of NTP. + // TODO(scottchen): implement chrome://welcome/email-interstitial. + welcome.WelcomeBrowserProxyImpl.getInstance().handleActivateSignIn(); + }, + + /** @private */ + onNoThanksClick_: function() { + welcome.navigateToNextStep(); + } +});
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/welcome_app.html b/chrome/browser/resources/welcome/onboarding_welcome/welcome_app.html index 31388710..2b7f48c8 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/welcome_app.html +++ b/chrome/browser/resources/welcome/onboarding_welcome/welcome_app.html
@@ -1,8 +1,12 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/cr_view_manager/cr_view_manager.html"> -<link rel="import" href="navigation_behavior.html"> +<link rel="import" href="apps/nux_google_apps.html"> +<link rel="import" href="email/nux_email.html"> <link rel="import" href="landing_view.html"> +<link rel="import" href="navigation_behavior.html"> +<link rel="import" href="set_as_default/nux_set_as_default.html"> +<link rel="import" href="signin_view.html"> <dom-module id="welcome-app"> <template> @@ -16,16 +20,6 @@ margin: 0; min-height: 100vh; } - - [slot='view'] { - /* Each view should be centered instead of taking full page. */ - --cr-view-manager-view: { - bottom: initial; - top: initial; - right: initial; - left: initial; - }; - } </style> <cr-view-manager id="viewManager"> <landing-view id="step-landing" slot="view" class="active"></landing-view>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/welcome_app.js b/chrome/browser/resources/welcome/onboarding_welcome/welcome_app.js index 4122b2e..395f63a 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/welcome_app.js +++ b/chrome/browser/resources/welcome/onboarding_welcome/welcome_app.js
@@ -22,8 +22,9 @@ // TODO(scottchen): instead of dummy, get data from finch/load time data. /** @private {NuxOnboardingModules} */ modules_: { - 'new-user': ['h1', 'h1', 'h1'], - 'returning-user': ['h3', 'h3'], + 'new-user': + ['nux-email', 'nux-google-apps', 'nux-set-as-default', 'signin-view'], + 'returning-user': ['nux-set-as-default'], }, /** @@ -65,13 +66,6 @@ element.id = 'step-' + (index + 1); element.setAttribute('slot', 'view'); this.$.viewManager.appendChild(element); - - // TODO(scottchen): this is just to test routing works. Actual elements - // will have buttons that are responsible for navigation. - element.textContent = index + 1; - element.addEventListener('click', () => { - this.navigateToNextStep(); - }); }); }, });
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/welcome_browser_proxy.js b/chrome/browser/resources/welcome/onboarding_welcome/welcome_browser_proxy.js index 679fe655..0f4b33b 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/welcome_browser_proxy.js +++ b/chrome/browser/resources/welcome/onboarding_welcome/welcome_browser_proxy.js
@@ -11,7 +11,7 @@ /** @interface */ class WelcomeBrowserProxy { - /** @param {string} redirectUrl the URL to redirect to, after signing in. */ + /** @param {string=} redirectUrl the URL to go to, after signing in. */ handleActivateSignIn(redirectUrl) {} goToNewTabPage() {} }
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.cc b/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.cc index d43cce3..c01db6f 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.cc
@@ -5,16 +5,18 @@ #include "chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h" #include <algorithm> +#include <string> #include <utility> #include "base/files/file_path.h" #include "base/location.h" #include "base/logging.h" +#include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_service.h" #include "components/crx_file/id_util.h" #include "content/public/browser/browser_thread.h" -#include "extensions/browser/disable_reason.h" +#include "extensions/browser/uninstall_reason.h" namespace safe_browsing { @@ -59,6 +61,9 @@ extension_ids ? ExtensionCollection(extension_ids->begin(), extension_ids->end()) : ExtensionCollection()); + if (extension_ids.has_value()) { + extension_ids_ = extension_ids; + } std::move(on_prompt_user_) .Run(std::move(scanner_results), std::move(callback)); } @@ -67,25 +72,40 @@ void ChromePromptImpl::DisableExtensions( const std::vector<base::string16>& extension_ids, ChromePrompt::DisableExtensionsCallback callback) { - if (extension_service_ == nullptr) { + if (extension_service_ == nullptr || !extension_ids_.has_value()) { std::move(callback).Run(false); return; } + // Clear the stored extension_ids by moving it onto this stack frame, + // so subsequent calls will fail. + base::Optional<std::vector<base::string16>> optional_verified_extension_ids{}; + extension_ids_.swap(optional_verified_extension_ids); + std::vector<base::string16> verified_extension_ids = + optional_verified_extension_ids.value(); bool ids_are_valid = std::all_of( - extension_ids.begin(), extension_ids.end(), [](const base::string16& id) { - return crx_file::id_util::IdIsValid(base::UTF16ToUTF8(id)); + extension_ids.begin(), extension_ids.end(), + [this, &verified_extension_ids](const base::string16& id) { + std::string id_utf8 = base::UTF16ToUTF8(id); + return crx_file::id_util::IdIsValid(id_utf8) && + base::ContainsValue(verified_extension_ids, id) && + extension_service_->GetInstalledExtension(id_utf8) != nullptr; }); if (!ids_are_valid) { std::move(callback).Run(false); return; } - int reason = extensions::disable_reason::DISABLE_EXTERNAL_EXTENSION; + // This only uninstalls extensions that have been displayed to the user on + // the cleanup page. + extensions::UninstallReason reason = + extensions::UNINSTALL_REASON_USER_INITIATED; + bool result = true; for (const base::string16& extension_id : extension_ids) { - extension_service_->DisableExtension(base::UTF16ToUTF8(extension_id), - reason); + result = extension_service_->UninstallExtension( + base::UTF16ToUTF8(extension_id), reason, nullptr) && + result; } - std::move(callback).Run(true); + std::move(callback).Run(result); } } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h b/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h index 9c71ce4..843af0c 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h
@@ -12,6 +12,7 @@ #include "base/callback.h" #include "base/files/file_path.h" #include "base/macros.h" +#include "base/optional.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_scanner_results.h" #include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h" @@ -49,6 +50,7 @@ mojo::Binding<chrome_cleaner::mojom::ChromePrompt> binding_; extensions::ExtensionService* extension_service_; OnPromptUser on_prompt_user_; + base::Optional<std::vector<base::string16>> extension_ids_; DISALLOW_COPY_AND_ASSIGN(ChromePromptImpl); };
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_delete_extension_win_unittest.cc b/chrome/browser/safe_browsing/chrome_cleaner/srt_delete_extension_win_unittest.cc index e0b7e97..9252ef33 100644 --- a/chrome/browser/safe_browsing/chrome_cleaner/srt_delete_extension_win_unittest.cc +++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_delete_extension_win_unittest.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/extensions/extension_service_test_base.h" #include "chrome/browser/extensions/test_extension_service.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/mock_extension_system.h" #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" @@ -47,38 +48,96 @@ std::unique_ptr<ChromePromptImpl> chrome_prompt = std::make_unique<ChromePromptImpl>(extension_service, nullptr, base::DoNothing(), base::DoNothing()); + chrome_prompt->PromptUser({}, {}, extension_ids, base::DoNothing()); std::vector<base::string16> extensions_to_disable{extension_ids[0]}; chrome_prompt->DisableExtensions( extensions_to_disable, base::BindOnce([](bool result) { EXPECT_TRUE(result); })); - EXPECT_FALSE(extension_service->IsExtensionEnabled( - base::UTF16ToUTF8(extension_ids[0]))); - EXPECT_TRUE(extension_service->IsExtensionEnabled( - base::UTF16ToUTF8(extension_ids[1]))); - EXPECT_TRUE(extension_service->IsExtensionEnabled( - base::UTF16ToUTF8(extension_ids[2]))); + EXPECT_EQ(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[0])), + nullptr); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[1])), + nullptr); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[2])), + nullptr); - extensions_to_disable.push_back(extension_ids[2]); + chrome_prompt = std::make_unique<ChromePromptImpl>( + extension_service, nullptr, base::DoNothing(), base::DoNothing()); + chrome_prompt->PromptUser({}, {}, extension_ids, base::DoNothing()); + extensions_to_disable = {extension_ids[2], extension_ids[1]}; chrome_prompt->DisableExtensions( extensions_to_disable, base::BindOnce([](bool result) { EXPECT_TRUE(result); })); - EXPECT_FALSE(extension_service->IsExtensionEnabled( - base::UTF16ToUTF8(extension_ids[0]))); - EXPECT_TRUE(extension_service->IsExtensionEnabled( - base::UTF16ToUTF8(extension_ids[1]))); - EXPECT_FALSE(extension_service->IsExtensionEnabled( - base::UTF16ToUTF8(extension_ids[2]))); + EXPECT_EQ(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[0])), + nullptr); + EXPECT_EQ(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[1])), + nullptr); + EXPECT_EQ(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[2])), + nullptr); +} - extensions_to_disable.push_back(extension_ids[1]); +TEST_F(ExtensionDeletionTest, CantDeleteNonPromptedExtensions) { + std::vector<base::string16> extension_ids{}; + extensions::ExtensionService* extension_service = this->service(); + for (int i = 40; i < 43; i++) { + scoped_refptr<const extensions::Extension> extension = + extensions::ExtensionBuilder(base::NumberToString(i)) + .SetManifestKey("version", "1") + .Build(); + auto id = extension->id(); + extension_ids.push_back(base::UTF8ToUTF16(id)); + extension_service->AddExtension(extension.get()); + extension_service->EnableExtension(id); + } + std::unique_ptr<ChromePromptImpl> chrome_prompt = + std::make_unique<ChromePromptImpl>(extension_service, nullptr, + base::DoNothing(), base::DoNothing()); + std::vector<base::string16> extensions_to_disable{extension_ids[0]}; chrome_prompt->DisableExtensions( extensions_to_disable, - base::BindOnce([](bool result) { EXPECT_TRUE(result); })); - EXPECT_FALSE(extension_service->IsExtensionEnabled( - base::UTF16ToUTF8(extension_ids[0]))); - EXPECT_FALSE(extension_service->IsExtensionEnabled( - base::UTF16ToUTF8(extension_ids[1]))); - EXPECT_FALSE(extension_service->IsExtensionEnabled( - base::UTF16ToUTF8(extension_ids[2]))); + base::BindOnce([](bool result) { EXPECT_FALSE(result); })); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[0])), + nullptr); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[1])), + nullptr); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[2])), + nullptr); + + chrome_prompt = std::make_unique<ChromePromptImpl>( + extension_service, nullptr, base::DoNothing(), base::DoNothing()); + chrome_prompt->DisableExtensions( + extension_ids, base::BindOnce([](bool result) { EXPECT_FALSE(result); })); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[0])), + nullptr); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[1])), + nullptr); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[2])), + nullptr); + + chrome_prompt->PromptUser({}, {}, {{extension_ids[2]}}, base::DoNothing()); + chrome_prompt->DisableExtensions( + {extension_ids[0], extension_ids[1]}, + base::BindOnce([](bool result) { EXPECT_FALSE(result); })); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[0])), + nullptr); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[1])), + nullptr); + EXPECT_NE(extension_service->GetInstalledExtension( + base::UTF16ToUTF8(extension_ids[2])), + nullptr); } TEST_F(ExtensionDeletionTest, EmptyDeletionTest) { @@ -87,6 +146,7 @@ std::unique_ptr<ChromePromptImpl> chrome_prompt = std::make_unique<ChromePromptImpl>(extension_service, nullptr, base::DoNothing(), base::DoNothing()); + chrome_prompt->PromptUser({}, {}, extension_ids, base::DoNothing()); for (int i = 40; i < 43; i++) { scoped_refptr<const extensions::Extension> extension = extensions::ExtensionBuilder(base::NumberToString(i)) @@ -149,7 +209,7 @@ extension_ids.push_back(base::UTF8ToUTF16(id)); } chrome_prompt->DisableExtensions( - extension_ids, base::BindOnce([](bool result) { EXPECT_TRUE(result); })); + extension_ids, base::BindOnce([](bool result) { EXPECT_FALSE(result); })); } } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index 16831b6..8c8c53b 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -313,9 +313,13 @@ class TestSafeBrowsingBlockingPageFactory : public SafeBrowsingBlockingPageFactory { public: - TestSafeBrowsingBlockingPageFactory() { } + TestSafeBrowsingBlockingPageFactory() : always_show_back_to_safety_(true) {} ~TestSafeBrowsingBlockingPageFactory() override {} + void SetAlwaysShowBackToSafety(bool value) { + always_show_back_to_safety_ = value; + } + SafeBrowsingBlockingPage* CreateSafeBrowsingPage( BaseUIManager* delegate, WebContents* web_contents, @@ -340,13 +344,16 @@ web_contents->GetBrowserContext()->IsOffTheRecord(), is_unified_consent_given, IsExtendedReportingEnabled(*prefs), IsExtendedReportingPolicyManaged(*prefs), is_proceed_anyway_disabled, - true, // should_open_links_in_new_tab - false, // check_can_go_back_to_safety + true, // should_open_links_in_new_tab + always_show_back_to_safety_, "cpn_safe_browsing" /* help_center_article_link */); return new TestSafeBrowsingBlockingPage(delegate, web_contents, main_frame_url, unsafe_resources, display_options); } + + private: + bool always_show_back_to_safety_; }; // Tests the safe browsing blocking page in a browser. @@ -427,6 +434,12 @@ embedded_test_server()->GetURL(kEmptyPage), browser); } + // The basic version of this method, which uses an HTTP test URL. + GURL SetupWarningAndNavigateInNewTab(Browser* browser) { + return SetupWarningAndNavigateToURLInNewTab( + embedded_test_server()->GetURL(kEmptyPage), browser); + } + // Navigates to a warning on a valid HTTPS website. GURL SetupWarningAndNavigateToValidHTTPS() { EXPECT_TRUE(https_server_.Start()); @@ -775,6 +788,10 @@ https_server_.GetURL("/title1.html")); } + void SetAlwaysShowBackToSafety(bool val) { + blocking_page_factory_.SetAlwaysShowBackToSafety(val); + } + protected: TestThreatDetailsFactory details_factory_; @@ -788,6 +805,17 @@ EXPECT_TRUE(WaitForReady(browser)); return url; } + // Adds a safebrowsing result of the current test threat to the fake + // safebrowsing service, navigates to that page, and returns the url. + // The various wrappers supply different URLs. + GURL SetupWarningAndNavigateToURLInNewTab(GURL url, Browser* browser) { + SetURLThreatType(url, testing::get<0>(GetParam())); + ui_test_utils::NavigateToURLWithDisposition( + browser, url, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); + EXPECT_TRUE(WaitForReady(browser)); + return url; + } base::test::ScopedFeatureList scoped_feature_list_; TestSafeBrowsingServiceFactory factory_; @@ -1149,6 +1177,20 @@ browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); } +IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, NoBackToSafety) { + SetAlwaysShowBackToSafety(false); + SetupWarningAndNavigateInNewTab(browser()); + + EXPECT_EQ(HIDDEN, GetVisibility("primary-button")); + EXPECT_EQ(HIDDEN, GetVisibility("details")); + EXPECT_EQ(HIDDEN, GetVisibility("proceed-link")); + EXPECT_EQ(HIDDEN, GetVisibility("error-code")); + EXPECT_TRUE(Click("details-button")); + EXPECT_EQ(VISIBLE, GetVisibility("details")); + EXPECT_EQ(VISIBLE, GetVisibility("proceed-link")); + EXPECT_EQ(HIDDEN, GetVisibility("error-code")); +} + // Verifies that the reporting checkbox is hidden when opt-in is // disabled by policy. However, reports can still be sent if extended // reporting is enabled (eg: by its own policy).
diff --git a/chrome/browser/signin/chrome_signin_helper.cc b/chrome/browser/signin/chrome_signin_helper.cc index 711ea81..58fb1c6 100644 --- a/chrome/browser/signin/chrome_signin_helper.cc +++ b/chrome/browser/signin/chrome_signin_helper.cc
@@ -190,7 +190,7 @@ BrowserWindow::AvatarBubbleMode bubble_mode; switch (service_type) { case GAIA_SERVICE_TYPE_INCOGNITO: - chrome::NewIncognitoWindow(browser); + chrome::NewIncognitoWindow(profile); return; case GAIA_SERVICE_TYPE_ADDSESSION: bubble_mode = BrowserWindow::AVATAR_BUBBLE_MODE_ADD_ACCOUNT;
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc index 9c9b41e..84c815a 100644 --- a/chrome/browser/themes/theme_service.cc +++ b/chrome/browser/themes/theme_service.cc
@@ -663,56 +663,37 @@ // static SkColor ThemeService::GetSeparatorColor(SkColor tab_color, SkColor frame_color) { - // We use this alpha value for the separator if possible. - const SkAlpha kAlpha = 0x40; + const float kContrastRatio = 2.f; // In most cases, if the tab is lighter than the frame, we darken the // frame; if the tab is darker than the frame, we lighten the frame. // However, if the frame is already very dark or very light, respectively, // this won't contrast sufficiently with the frame color, so we'll need to // reverse when we're lightening and darkening. - const float tab_luminance = color_utils::GetRelativeLuminance(tab_color); - const float frame_luminance = color_utils::GetRelativeLuminance(frame_color); - const bool lighten = tab_luminance < frame_luminance; - SkColor separator_color = lighten ? SK_ColorWHITE : SK_ColorBLACK; - float separator_luminance = color_utils::GetRelativeLuminance( - color_utils::AlphaBlend(separator_color, frame_color, kAlpha)); - // The minimum contrast ratio here is just under the ~1.1469 in the default MD - // incognito theme. We want the separator to still darken the frame in that - // theme, but that's about as low of contrast as we're willing to accept. - const float kMinContrastRatio = 1.1465f; - if (color_utils::GetContrastRatio(separator_luminance, frame_luminance) >= - kMinContrastRatio) - return SkColorSetA(separator_color, kAlpha); + const bool lighten = color_utils::GetRelativeLuminance(tab_color) < + color_utils::GetRelativeLuminance(frame_color); + SkColor separator_color = + lighten ? SK_ColorWHITE : color_utils::GetDarkestColor(); - // We need to reverse whether we're darkening or lightening. We know the new - // separator color will contrast with the frame; check whether it also - // contrasts at least as well with the tab. - separator_color = color_utils::InvertColor(separator_color); - separator_luminance = color_utils::GetRelativeLuminance( - color_utils::AlphaBlend(separator_color, frame_color, kAlpha)); - if (color_utils::GetContrastRatio(separator_luminance, tab_luminance) >= - color_utils::GetContrastRatio(separator_luminance, frame_luminance)) - return SkColorSetA(separator_color, kAlpha); - - // The reversed separator doesn't contrast enough with the tab. Compute the - // resulting luminance from adjusting the tab color, instead of the frame - // color, by the separator color. - const float target_luminance = color_utils::GetRelativeLuminance( - color_utils::AlphaBlend(separator_color, tab_color, kAlpha)); - - // Now try to compute an alpha for the separator such that, when blended with - // the frame, it results in the above luminance. Because the luminance - // computation is not easily invertible, we use a binary search over the - // possible range of alpha values. - SkAlpha alpha = 128; - for (int delta = lighten ? 64 : -64; delta != 0; delta /= 2) { - const float luminance = color_utils::GetRelativeLuminance( - color_utils::AlphaBlend(separator_color, frame_color, alpha)); - if (luminance == target_luminance) - break; - alpha += (luminance < target_luminance) ? -delta : delta; + SkAlpha alpha = color_utils::FindBlendValueForContrastRatio( + frame_color, separator_color, frame_color, kContrastRatio, 0); + if (color_utils::GetContrastRatio( + color_utils::AlphaBlend(separator_color, frame_color, alpha), + frame_color) >= kContrastRatio) { + return SkColorSetA(separator_color, alpha); } + + separator_color = + color_utils::BlendTowardOppositeLuma(separator_color, SK_AlphaOPAQUE); + + // If the above call failed to create sufficient contrast, the frame color is + // already very dark or very light. Since separators are only used when the + // tab has low contrast against the frame, the tab color is similarly very + // dark or very light, just not quite as much so as the frame color. Blend + // towards the opposite separator color, and compute the contrast against the + // tab instead of the frame to ensure both contrasts hit the desired minimum. + alpha = color_utils::FindBlendValueForContrastRatio( + frame_color, separator_color, tab_color, kContrastRatio, 0); return SkColorSetA(separator_color, alpha); }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 25368f3..15e72dd 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1444,8 +1444,6 @@ "views/frame/browser_non_client_frame_view_ash.h", "views/frame/immersive_context_mus.cc", "views/frame/immersive_context_mus.h", - "views/frame/immersive_focus_watcher_mus.cc", - "views/frame/immersive_focus_watcher_mus.h", "views/frame/immersive_handler_factory_mus.cc", "views/frame/immersive_handler_factory_mus.h", "views/frame/immersive_mode_controller_ash.cc", @@ -3334,8 +3332,8 @@ sources += [ "in_product_help/active_tab_tracker.cc", "in_product_help/active_tab_tracker.h", - "in_product_help/reopen_tab_iph_trigger.cc", - "in_product_help/reopen_tab_iph_trigger.h", + "in_product_help/reopen_tab_in_product_help_trigger.cc", + "in_product_help/reopen_tab_in_product_help_trigger.h", ] }
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc index a8419a1b..e88405c 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/ui/app_list/arc/arc_package_syncable_service.h" #include "chrome/browser/ui/app_list/arc/arc_pai_starter.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/chromeos_switches.h" #include "components/arc/arc_prefs.h" #include "components/arc/arc_service_manager.h" #include "components/arc/arc_util.h" @@ -1030,7 +1031,8 @@ // TODO(khmel): Use show_in_launcher flag to hide the Play Store app. if (app_id == arc::kPlayStoreAppId && arc::IsRobotOrOfflineDemoAccountMode() && - !chromeos::DemoSession::IsDeviceInDemoMode()) { + !(chromeos::DemoSession::IsDeviceInDemoMode() && + chromeos::switches::ShouldShowPlayStoreInDemoMode())) { return; }
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc index b738d06..7c6f711 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
@@ -167,6 +167,12 @@ ->GetShelfViewForTesting(); } +int64_t GetDisplayIdForBrowserWindow(BrowserWindow* window) { + return display::Screen::GetScreen() + ->GetDisplayNearestWindow(window->GetNativeWindow()) + .id(); +} + } // namespace class LauncherPlatformAppBrowserTest @@ -855,10 +861,11 @@ // Ensures browser 2 is above browser 1 in display 1. browser_list->SetLastActive(browser2); browser_list->SetLastActive(browser0); + aura::test::WaitForAllChangesToComplete(); EXPECT_EQ(browser_list->size(), 3U); - EXPECT_EQ(browser0->window()->GetNativeWindow()->GetRootWindow(), roots[0]); - EXPECT_EQ(browser1->window()->GetNativeWindow()->GetRootWindow(), roots[1]); - EXPECT_EQ(browser2->window()->GetNativeWindow()->GetRootWindow(), roots[1]); + EXPECT_EQ(displays[0].id(), GetDisplayIdForBrowserWindow(browser0->window())); + EXPECT_EQ(displays[1].id(), GetDisplayIdForBrowserWindow(browser1->window())); + EXPECT_EQ(displays[1].id(), GetDisplayIdForBrowserWindow(browser2->window())); EXPECT_EQ(browser0->tab_strip_model()->count(), 1); EXPECT_EQ(browser1->tab_strip_model()->count(), 1); EXPECT_EQ(browser2->tab_strip_model()->count(), 1); @@ -897,8 +904,9 @@ BrowserList* browser_list = BrowserList::GetInstance(); Browser* browser0 = browser(); browser0->window()->SetBounds(displays[0].work_area()); + aura::test::WaitForAllChangesToComplete(); EXPECT_EQ(browser_list->size(), 1U); - EXPECT_EQ(browser0->window()->GetNativeWindow()->GetRootWindow(), roots[0]); + EXPECT_EQ(displays[0].id(), GetDisplayIdForBrowserWindow(browser0->window())); EXPECT_EQ(browser0->tab_strip_model()->count(), 1); // Launches an app from the shelf of display 0 and expects a new browser with
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index f8f817f..30f4864 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1296,16 +1296,12 @@ return window()->PreHandleKeyboardEvent(event); } -void Browser::HandleKeyboardEvent(content::WebContents* source, +bool Browser::HandleKeyboardEvent(content::WebContents* source, const NativeWebKeyboardEvent& event) { DevToolsWindow* devtools_window = DevToolsWindow::GetInstanceForInspectedWebContents(source); - bool handled = false; - if (devtools_window) - handled = devtools_window->ForwardKeyboardEvent(event); - - if (!handled) - window()->HandleKeyboardEvent(event); + return (devtools_window && devtools_window->ForwardKeyboardEvent(event)) || + window()->HandleKeyboardEvent(event); } bool Browser::TabsNeedBeforeUnloadFired() {
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 4bcc4ab5..875f5d8 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -482,7 +482,7 @@ content::KeyboardEventProcessingResult PreHandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; bool PreHandleGestureEvent(content::WebContents* source,
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index 0649a4c5..6dfff626 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -342,7 +342,7 @@ NewWindow(browser_); break; case IDC_NEW_INCOGNITO_WINDOW: - NewIncognitoWindow(browser_); + NewIncognitoWindow(profile()); break; case IDC_CLOSE_WINDOW: base::RecordAction(base::UserMetricsAction("CloseWindowByKey"));
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index fe98ecab..10b3d0e 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -577,13 +577,13 @@ NewEmptyWindow(browser->profile()->GetOriginalProfile()); } -void NewIncognitoWindow(Browser* browser) { +void NewIncognitoWindow(Profile* profile) { #if BUILDFLAG(ENABLE_DESKTOP_IN_PRODUCT_HELP) feature_engagement::IncognitoWindowTrackerFactory::GetInstance() - ->GetForProfile(browser->profile()) + ->GetForProfile(profile) ->OnIncognitoWindowOpened(); #endif - NewEmptyWindow(browser->profile()->GetOffTheRecordProfile()); + NewEmptyWindow(profile->GetOffTheRecordProfile()); } void CloseWindow(Browser* browser) {
diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h index 4b31e64..5c6b768 100644 --- a/chrome/browser/ui/browser_commands.h +++ b/chrome/browser/ui/browser_commands.h
@@ -70,7 +70,7 @@ void OpenCurrentURL(Browser* browser); void Stop(Browser* browser); void NewWindow(Browser* browser); -void NewIncognitoWindow(Browser* browser); +void NewIncognitoWindow(Profile* profile); void CloseWindow(Browser* browser); void NewTab(Browser* browser); void CloseTab(Browser* browser);
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 21ee7f04..19d4ce76 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h
@@ -366,7 +366,7 @@ // Allows the BrowserWindow object to handle the specified keyboard event, // if the renderer did not process it. - virtual void HandleKeyboardEvent( + virtual bool HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) = 0; // Clipboard commands applied to the whole browser window.
diff --git a/chrome/browser/ui/in_product_help/reopen_tab_iph_trigger.cc b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.cc similarity index 70% rename from chrome/browser/ui/in_product_help/reopen_tab_iph_trigger.cc rename to chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.cc index 0ae8154..d667c2d7 100644 --- a/chrome/browser/ui/in_product_help/reopen_tab_iph_trigger.cc +++ b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.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/browser/ui/in_product_help/reopen_tab_iph_trigger.h" +#include "chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.h" #include <utility> @@ -13,17 +13,18 @@ namespace in_product_help { // static -const base::TimeDelta ReopenTabIPHTrigger::kTabMinimumActiveDuration = +const base::TimeDelta ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration = base::TimeDelta::FromSeconds(10); // static -const base::TimeDelta ReopenTabIPHTrigger::kNewTabOpenedTimeout = +const base::TimeDelta ReopenTabInProductHelpTrigger::kNewTabOpenedTimeout = base::TimeDelta::FromSeconds(10); // static -const base::TimeDelta ReopenTabIPHTrigger::kOmniboxFocusedTimeout = +const base::TimeDelta ReopenTabInProductHelpTrigger::kOmniboxFocusedTimeout = base::TimeDelta::FromSeconds(10); -ReopenTabIPHTrigger::ReopenTabIPHTrigger(feature_engagement::Tracker* tracker, - const base::TickClock* clock) +ReopenTabInProductHelpTrigger::ReopenTabInProductHelpTrigger( + feature_engagement::Tracker* tracker, + const base::TickClock* clock) : tracker_(tracker), clock_(clock), trigger_state_(NO_ACTIONS_SEEN) { DCHECK(tracker); DCHECK(clock); @@ -33,14 +34,16 @@ DCHECK(!kOmniboxFocusedTimeout.is_zero()); } -ReopenTabIPHTrigger::~ReopenTabIPHTrigger() = default; +ReopenTabInProductHelpTrigger::~ReopenTabInProductHelpTrigger() = default; -void ReopenTabIPHTrigger::SetShowHelpCallback(ShowHelpCallback callback) { +void ReopenTabInProductHelpTrigger::SetShowHelpCallback( + ShowHelpCallback callback) { DCHECK(callback); cb_ = std::move(callback); } -void ReopenTabIPHTrigger::ActiveTabClosed(base::TimeTicks activation_time) { +void ReopenTabInProductHelpTrigger::ActiveTabClosed( + base::TimeTicks activation_time) { // Reset all flags at this point. We should only trigger IPH if the events // happen in the prescribed order. ResetTriggerState(); @@ -53,7 +56,7 @@ } } -void ReopenTabIPHTrigger::NewTabOpened() { +void ReopenTabInProductHelpTrigger::NewTabOpened() { if (trigger_state_ != ACTIVE_TAB_CLOSED) return; @@ -67,7 +70,7 @@ } } -void ReopenTabIPHTrigger::OmniboxFocused() { +void ReopenTabInProductHelpTrigger::OmniboxFocused() { if (trigger_state_ != NEW_TAB_OPENED) return; @@ -83,12 +86,12 @@ } } -void ReopenTabIPHTrigger::HelpDismissed() { +void ReopenTabInProductHelpTrigger::HelpDismissed() { tracker_->Dismissed(feature_engagement::kIPHReopenTabFeature); ResetTriggerState(); } -void ReopenTabIPHTrigger::ResetTriggerState() { +void ReopenTabInProductHelpTrigger::ResetTriggerState() { time_of_last_step_ = base::TimeTicks(); trigger_state_ = NO_ACTIONS_SEEN; }
diff --git a/chrome/browser/ui/in_product_help/reopen_tab_iph_trigger.h b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.h similarity index 81% rename from chrome/browser/ui/in_product_help/reopen_tab_iph_trigger.h rename to chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.h index 1fa1fc58..82a74c17 100644 --- a/chrome/browser/ui/in_product_help/reopen_tab_iph_trigger.h +++ b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.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_BROWSER_UI_IN_PRODUCT_HELP_REOPEN_TAB_IPH_TRIGGER_H_ -#define CHROME_BROWSER_UI_IN_PRODUCT_HELP_REOPEN_TAB_IPH_TRIGGER_H_ +#ifndef CHROME_BROWSER_UI_IN_PRODUCT_HELP_REOPEN_TAB_IN_PRODUCT_HELP_TRIGGER_H_ +#define CHROME_BROWSER_UI_IN_PRODUCT_HELP_REOPEN_TAB_IN_PRODUCT_HELP_TRIGGER_H_ #include "base/callback.h" #include "base/time/tick_clock.h" @@ -22,11 +22,11 @@ // // Clients should listen for the relevant user events and pass them to this // class. Additionally, clients must display IPH when told by this class. -class ReopenTabIPHTrigger { +class ReopenTabInProductHelpTrigger { public: - ReopenTabIPHTrigger(feature_engagement::Tracker* tracker, - const base::TickClock* clock); - ~ReopenTabIPHTrigger(); + ReopenTabInProductHelpTrigger(feature_engagement::Tracker* tracker, + const base::TickClock* clock); + ~ReopenTabInProductHelpTrigger(); using ShowHelpCallback = base::RepeatingCallback<void()>; @@ -74,9 +74,9 @@ base::TimeTicks time_of_last_step_; - DISALLOW_COPY_AND_ASSIGN(ReopenTabIPHTrigger); + DISALLOW_COPY_AND_ASSIGN(ReopenTabInProductHelpTrigger); }; } // namespace in_product_help -#endif // CHROME_BROWSER_UI_IN_PRODUCT_HELP_REOPEN_TAB_IPH_TRIGGER_H_ +#endif // CHROME_BROWSER_UI_IN_PRODUCT_HELP_REOPEN_TAB_IN_PRODUCT_HELP_TRIGGER_H_
diff --git a/chrome/browser/ui/in_product_help/reopen_tab_iph_trigger_unittest.cc b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.cc similarity index 71% rename from chrome/browser/ui/in_product_help/reopen_tab_iph_trigger_unittest.cc rename to chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.cc index d18ae7e5..8d3517f 100644 --- a/chrome/browser/ui/in_product_help/reopen_tab_iph_trigger_unittest.cc +++ b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.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/browser/ui/in_product_help/reopen_tab_iph_trigger.h" +#include "chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.h" #include "base/bind.h" #include "base/test/simple_test_tick_clock.h" @@ -22,18 +22,19 @@ namespace { -void DismissImmediately(ReopenTabIPHTrigger* trigger) { +void DismissImmediately(ReopenTabInProductHelpTrigger* trigger) { trigger->HelpDismissed(); } -void DismissAndSetFlag(ReopenTabIPHTrigger* trigger, bool* triggered) { +void DismissAndSetFlag(ReopenTabInProductHelpTrigger* trigger, + bool* triggered) { *triggered = true; trigger->HelpDismissed(); } } // namespace -TEST(ReopenTabIPHTriggerTest, TriggersIPH) { +TEST(ReopenTabInProductHelpTriggerTest, TriggersIPH) { NiceMock<MockTracker> mock_tracker; // We expect to send the backend our trigger event and ask if we should @@ -50,19 +51,19 @@ // Instantiate IPH and send sequence of user interactions. base::SimpleTestTickClock clock; - ReopenTabIPHTrigger reopen_tab_iph(&mock_tracker, &clock); + ReopenTabInProductHelpTrigger reopen_tab_iph(&mock_tracker, &clock); reopen_tab_iph.SetShowHelpCallback( base::BindRepeating(DismissImmediately, &reopen_tab_iph)); auto activation_time = clock.NowTicks(); - clock.Advance(ReopenTabIPHTrigger::kTabMinimumActiveDuration); + clock.Advance(ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration); reopen_tab_iph.ActiveTabClosed(activation_time); reopen_tab_iph.NewTabOpened(); reopen_tab_iph.OmniboxFocused(); } -TEST(ReopenTabIPHTriggerTest, RespectsBackendShouldTrigger) { +TEST(ReopenTabInProductHelpTriggerTest, RespectsBackendShouldTrigger) { NiceMock<MockTracker> mock_tracker; EXPECT_CALL(mock_tracker, ShouldTriggerHelpUI(_)) @@ -71,62 +72,62 @@ EXPECT_CALL(mock_tracker, Dismissed(_)).Times(0); base::SimpleTestTickClock clock; - ReopenTabIPHTrigger reopen_tab_iph(&mock_tracker, &clock); + ReopenTabInProductHelpTrigger reopen_tab_iph(&mock_tracker, &clock); reopen_tab_iph.SetShowHelpCallback( base::BindRepeating(DismissImmediately, &reopen_tab_iph)); auto activation_time = clock.NowTicks(); - clock.Advance(ReopenTabIPHTrigger::kTabMinimumActiveDuration); + clock.Advance(ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration); reopen_tab_iph.ActiveTabClosed(activation_time); reopen_tab_iph.NewTabOpened(); reopen_tab_iph.OmniboxFocused(); } -TEST(ReopenTabIPHTriggerTest, TabNotActiveLongEnough) { +TEST(ReopenTabInProductHelpTriggerTest, TabNotActiveLongEnough) { NiceMock<MockTracker> mock_tracker; EXPECT_CALL(mock_tracker, NotifyEvent(_)).Times(0); EXPECT_CALL(mock_tracker, ShouldTriggerHelpUI(_)).Times(0); base::SimpleTestTickClock clock; - ReopenTabIPHTrigger reopen_tab_iph(&mock_tracker, &clock); + ReopenTabInProductHelpTrigger reopen_tab_iph(&mock_tracker, &clock); auto activation_time = clock.NowTicks(); - clock.Advance(ReopenTabIPHTrigger::kTabMinimumActiveDuration / 2); + clock.Advance(ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration / 2); reopen_tab_iph.ActiveTabClosed(activation_time); reopen_tab_iph.NewTabOpened(); reopen_tab_iph.OmniboxFocused(); } -TEST(ReopenTabIPHTriggerTest, RespectsTimeouts) { +TEST(ReopenTabInProductHelpTriggerTest, RespectsTimeouts) { NiceMock<MockTracker> mock_tracker; EXPECT_CALL(mock_tracker, NotifyEvent(_)).Times(0); EXPECT_CALL(mock_tracker, ShouldTriggerHelpUI(_)).Times(0); base::SimpleTestTickClock clock; - ReopenTabIPHTrigger reopen_tab_iph(&mock_tracker, &clock); + ReopenTabInProductHelpTrigger reopen_tab_iph(&mock_tracker, &clock); reopen_tab_iph.SetShowHelpCallback( base::BindRepeating(DismissImmediately, &reopen_tab_iph)); auto activation_time = clock.NowTicks(); - clock.Advance(ReopenTabIPHTrigger::kTabMinimumActiveDuration); + clock.Advance(ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration); reopen_tab_iph.ActiveTabClosed(activation_time); - clock.Advance(ReopenTabIPHTrigger::kNewTabOpenedTimeout); + clock.Advance(ReopenTabInProductHelpTrigger::kNewTabOpenedTimeout); reopen_tab_iph.NewTabOpened(); reopen_tab_iph.OmniboxFocused(); activation_time = clock.NowTicks(); - clock.Advance(ReopenTabIPHTrigger::kTabMinimumActiveDuration); + clock.Advance(ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration); reopen_tab_iph.ActiveTabClosed(activation_time); reopen_tab_iph.NewTabOpened(); - clock.Advance(ReopenTabIPHTrigger::kOmniboxFocusedTimeout); + clock.Advance(ReopenTabInProductHelpTrigger::kOmniboxFocusedTimeout); reopen_tab_iph.OmniboxFocused(); } -TEST(ReopenTabIPHTriggerTest, TriggersTwice) { +TEST(ReopenTabInProductHelpTriggerTest, TriggersTwice) { NiceMock<MockTracker> mock_tracker; EXPECT_CALL( @@ -139,14 +140,14 @@ EXPECT_CALL(mock_tracker, Dismissed(_)).Times(2); base::SimpleTestTickClock clock; - ReopenTabIPHTrigger reopen_tab_iph(&mock_tracker, &clock); + ReopenTabInProductHelpTrigger reopen_tab_iph(&mock_tracker, &clock); bool triggered = false; reopen_tab_iph.SetShowHelpCallback( base::BindRepeating(DismissAndSetFlag, &reopen_tab_iph, &triggered)); auto activation_time = clock.NowTicks(); - clock.Advance(ReopenTabIPHTrigger::kTabMinimumActiveDuration); + clock.Advance(ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration); reopen_tab_iph.ActiveTabClosed(activation_time); reopen_tab_iph.NewTabOpened(); reopen_tab_iph.OmniboxFocused(); @@ -154,7 +155,7 @@ EXPECT_TRUE(triggered); triggered = false; - clock.Advance(ReopenTabIPHTrigger::kTabMinimumActiveDuration); + clock.Advance(ReopenTabInProductHelpTrigger::kTabMinimumActiveDuration); reopen_tab_iph.ActiveTabClosed(activation_time); reopen_tab_iph.NewTabOpened(); reopen_tab_iph.OmniboxFocused();
diff --git a/chrome/browser/ui/libgtkui/gtk_ui.cc b/chrome/browser/ui/libgtkui/gtk_ui.cc index 451a892..e5a50b0 100644 --- a/chrome/browser/ui/libgtkui/gtk_ui.cc +++ b/chrome/browser/ui/libgtkui/gtk_ui.cc
@@ -327,57 +327,6 @@ } } -// COLOR_TOOLBAR_TOP_SEPARATOR represents the border between tabs and the -// frame, as well as the border between tabs and the toolbar. For this -// reason, it is difficult to calculate the One True Color that works well on -// all themes and is opaque. However, we can cheat to get a good color that -// works well for both borders. The idea is we have two variables: alpha and -// lightness. And we have two constraints (on lightness): -// 1. the border color, when painted on |header_bg|, should give |header_fg| -// 2. the border color, when painted on |tab_bg|, should give |tab_fg| -// This gives the equations: -// alpha*lightness + (1 - alpha)*header_bg = header_fg -// alpha*lightness + (1 - alpha)*tab_bg = tab_fg -// The algorithm below is just a result of solving those equations for alpha -// and lightness. If a problem is encountered, like division by zero, or -// |a| or |l| not in [0, 1], then fallback on |header_fg| or |tab_fg|. -SkColor GetToolbarTopSeparatorColor(SkColor header_fg, - SkColor header_bg, - SkColor tab_fg, - SkColor tab_bg) { - using namespace color_utils; - - SkColor default_color = SkColorGetA(header_fg) ? header_fg : tab_fg; - if (!SkColorGetA(default_color)) - return SK_ColorTRANSPARENT; - - auto get_lightness = [](SkColor color) { - HSL hsl; - SkColorToHSL(color, &hsl); - return hsl.l; - }; - - double f1 = get_lightness(GetResultingPaintColor(header_fg, header_bg)); - double b1 = get_lightness(header_bg); - double f2 = get_lightness(GetResultingPaintColor(tab_fg, tab_bg)); - double b2 = get_lightness(tab_bg); - - if (b1 == b2) - return default_color; - double a = (f1 - f2 - b1 + b2) / (b2 - b1); - if (a == 0) - return default_color; - double l = (f1 - (1 - a) * b1) / a; - if (a < 0 || a > 1 || l < 0 || l > 1) - return default_color; - // Take the hue and saturation from |default_color|, but use the - // calculated lightness. - HSL border; - SkColorToHSL(default_color, &border); - border.l = l; - return HSLToSkColor(border, a * 0xff); -} - } // namespace GtkUi::GtkUi() { @@ -423,6 +372,8 @@ G_CALLBACK(OnThemeChanged), this); g_signal_connect_after(settings, "notify::gtk-icon-theme-name", G_CALLBACK(OnThemeChanged), this); + g_signal_connect_after(settings, "notify::gtk-application-prefer-dark-theme", + G_CALLBACK(OnThemeChanged), this); GdkScreen* screen = gdk_screen_get_default(); // Listen for DPI changes. @@ -1008,22 +959,36 @@ // These colors represent the border drawn around tabs and between // the tabstrip and toolbar. - SkColor toolbar_top_separator = - GetBorderColor(header_selector + " GtkButton#button"); + SkColor toolbar_top_separator = GetBorderColor( + header_selector + " GtkSeparator#separator.vertical.titlebutton"); SkColor toolbar_top_separator_inactive = - GetBorderColor(header_selector + ":backdrop GtkButton#button"); - if (!ui::MaterialDesignController::IsRefreshUi()) { - toolbar_top_separator = GetToolbarTopSeparatorColor( - toolbar_top_separator, frame_color, tab_border, tab_color); - toolbar_top_separator_inactive = GetToolbarTopSeparatorColor( - toolbar_top_separator_inactive, frame_color_inactive, tab_border, - tab_color); + GetBorderColor(header_selector + + ":backdrop GtkSeparator#separator.vertical.titlebutton"); + + auto toolbar_top_separator_has_good_contrast = [&]() { + // This constant is copied from chrome/browser/themes/theme_service.cc. + const float kMinContrastRatio = 2.f; + + SkColor active = color_utils::GetResultingPaintColor( + toolbar_top_separator, frame_color); + SkColor inactive = color_utils::GetResultingPaintColor( + toolbar_top_separator_inactive, frame_color_inactive); + return color_utils::GetContrastRatio(frame_color, active) >= + kMinContrastRatio && + color_utils::GetContrastRatio(frame_color_inactive, inactive) >= + kMinContrastRatio; + }; + + if (!toolbar_top_separator_has_good_contrast()) { + toolbar_top_separator = + GetBorderColor(header_selector + " GtkButton#button"); + toolbar_top_separator_inactive = + GetBorderColor(header_selector + ":backdrop GtkButton#button"); } - // Unlike with toolbars, we always want a border around tabs, so let - // ThemeService choose the border color if the theme doesn't provide one. - if (SkColorGetA(toolbar_top_separator) && - SkColorGetA(toolbar_top_separator_inactive)) { + // If we can't get a contrasting stroke from the theme, have ThemeService + // provide a stroke color for us. + if (toolbar_top_separator_has_good_contrast()) { color_map[ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR] = toolbar_top_separator; color_map[ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR_INACTIVE] = @@ -1095,6 +1060,9 @@ } void GtkUi::ResetStyle() { + colors_.clear(); + custom_frame_colors_.clear(); + native_frame_colors_.clear(); LoadGtkValues(); native_theme_->NotifyObservers(); }
diff --git a/chrome/browser/ui/login/OWNERS b/chrome/browser/ui/login/OWNERS index 6cbbda3..6e808f5 100644 --- a/chrome/browser/ui/login/OWNERS +++ b/chrome/browser/ui/login/OWNERS
@@ -1,5 +1,5 @@ +carlosil@chromium.org davidben@chromium.org -meacer@chromium.org vabr@chromium.org # COMPONENT: Internals>Network>Auth
diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_client.cc b/chrome/browser/ui/omnibox/chrome_omnibox_client.cc index 9182362..c0c47c5 100644 --- a/chrome/browser/ui/omnibox/chrome_omnibox_client.cc +++ b/chrome/browser/ui/omnibox/chrome_omnibox_client.cc
@@ -37,6 +37,8 @@ #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/sessions/session_tab_helper.h" #include "chrome/browser/translate/chrome_translate_client.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/omnibox/chrome_omnibox_edit_controller.h" #include "chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.h" @@ -483,6 +485,10 @@ controller_->GetWebContents()->GetController().DiscardNonCommittedEntries(); } +void ChromeOmniboxClient::NewIncognitoWindow() { + chrome::NewIncognitoWindow(profile_); +} + void ChromeOmniboxClient::PromptPageTranslation() { content::WebContents* contents = controller_->GetWebContents(); if (contents) {
diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_client.h b/chrome/browser/ui/omnibox/chrome_omnibox_client.h index b791ab6..8372fac 100644 --- a/chrome/browser/ui/omnibox/chrome_omnibox_client.h +++ b/chrome/browser/ui/omnibox/chrome_omnibox_client.h
@@ -80,6 +80,7 @@ void OnURLOpenedFromOmnibox(OmniboxLog* log) override; void OnBookmarkLaunched() override; void DiscardNonCommittedNavigations() override; + void NewIncognitoWindow() override; void PromptPageTranslation() override; private:
diff --git a/chrome/browser/ui/signin_view_controller_delegate.cc b/chrome/browser/ui/signin_view_controller_delegate.cc index 23499a80..9312b16 100644 --- a/chrome/browser/ui/signin_view_controller_delegate.cc +++ b/chrome/browser/ui/signin_view_controller_delegate.cc
@@ -95,10 +95,11 @@ } } -void SigninViewControllerDelegate::HandleKeyboardEvent( +bool SigninViewControllerDelegate::HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { NOTREACHED(); + return false; } bool SigninViewControllerDelegate::CanGoBack(
diff --git a/chrome/browser/ui/signin_view_controller_delegate.h b/chrome/browser/ui/signin_view_controller_delegate.h index 967dc4eb..475247b 100644 --- a/chrome/browser/ui/signin_view_controller_delegate.h +++ b/chrome/browser/ui/signin_view_controller_delegate.h
@@ -98,7 +98,7 @@ bool to_different_document) override; // Subclasses must override this method to correctly handle accelerators. - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override;
diff --git a/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc b/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc index a2f5b76..ac8b2f0 100644 --- a/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc +++ b/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc
@@ -117,7 +117,7 @@ ~WebDialogWebContentsDelegateViews() override {} // ui::WebDialogWebContentsDelegate: - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override { // Forward shortcut keys in dialog to our initiator's delegate. @@ -125,12 +125,15 @@ // Disabled on Mac due to http://crbug.com/112173 #if !defined(OS_MACOSX) if (!initiator_observer_->web_contents()) - return; + return false; auto* delegate = initiator_observer_->web_contents()->GetDelegate(); if (!delegate) - return; - delegate->HandleKeyboardEvent(initiator_observer_->web_contents(), event); + return false; + return delegate->HandleKeyboardEvent(initiator_observer_->web_contents(), + event); +#else + return false; #endif } @@ -191,10 +194,10 @@ } // contents::WebContentsDelegate: - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override { - unhandled_keyboard_event_handler_.HandleKeyboardEvent( + return unhandled_keyboard_event_handler_.HandleKeyboardEvent( event, view_->GetFocusManager()); }
diff --git a/chrome/browser/ui/views/extensions/extension_view_views.cc b/chrome/browser/ui/views/extensions/extension_view_views.cc index c2ddada..4f3f949 100644 --- a/chrome/browser/ui/views/extensions/extension_view_views.cc +++ b/chrome/browser/ui/views/extensions/extension_view_views.cc
@@ -89,11 +89,11 @@ WebView::RenderViewCreated(render_view_host); } -void ExtensionViewViews::HandleKeyboardEvent( +bool ExtensionViewViews::HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { - unhandled_keyboard_event_handler_.HandleKeyboardEvent(event, - GetFocusManager()); + return unhandled_keyboard_event_handler_.HandleKeyboardEvent( + event, GetFocusManager()); } void ExtensionViewViews::OnLoaded() {
diff --git a/chrome/browser/ui/views/extensions/extension_view_views.h b/chrome/browser/ui/views/extensions/extension_view_views.h index 880fd8d..976bc4b 100644 --- a/chrome/browser/ui/views/extensions/extension_view_views.h +++ b/chrome/browser/ui/views/extensions/extension_view_views.h
@@ -57,7 +57,7 @@ void ResizeDueToAutoResize(content::WebContents* web_contents, const gfx::Size& new_size) override; void RenderViewCreated(content::RenderViewHost* render_view_host) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; void OnLoaded() override;
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 4f4dd58..d057bd18 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1523,12 +1523,12 @@ return content::KeyboardEventProcessingResult::NOT_HANDLED_IS_SHORTCUT; } -void BrowserView::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { +bool BrowserView::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { if (frame_->HandleKeyboardEvent(event)) - return; + return true; - unhandled_keyboard_event_handler_.HandleKeyboardEvent(event, - GetFocusManager()); + return unhandled_keyboard_event_handler_.HandleKeyboardEvent( + event, GetFocusManager()); } // TODO(devint): http://b/issue?id=1117225 Cut, Copy, and Paste are always
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index d6bafcb..2499f3c 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -385,7 +385,7 @@ void ShowAppMenu() override; content::KeyboardEventProcessingResult PreHandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) override; void CutCopyPaste(int command_id) override; FindBar* CreateFindBar() override;
diff --git a/chrome/browser/ui/views/frame/immersive_focus_watcher_mus.h b/chrome/browser/ui/views/frame/immersive_focus_watcher_mus.h deleted file mode 100644 index 69e32e1..0000000 --- a/chrome/browser/ui/views/frame/immersive_focus_watcher_mus.h +++ /dev/null
@@ -1,79 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_IMMERSIVE_FOCUS_WATCHER_MUS_H_ -#define CHROME_BROWSER_UI_VIEWS_FRAME_IMMERSIVE_FOCUS_WATCHER_MUS_H_ - -#include "ash/public/cpp/immersive/immersive_focus_watcher.h" -#include "ui/aura/client/focus_change_observer.h" -#include "ui/aura/client/transient_window_client_observer.h" -#include "ui/views/focus/focus_manager.h" -#include "ui/wm/public/activation_change_observer.h" - -namespace ash { -class ImmersiveFullscreenController; -class ImmersiveRevealedLock; -} // namespace ash - -// ImmersiveFocusWatcherMus is responsible for grabbing a reveal lock based on -// activation and/or focus. This implementation grabs a lock if views focus is -// in the top view, a bubble is showing that is anchored to the top view, or -// the focused window is a transient child of the top view's widget. -class ImmersiveFocusWatcherMus - : public ash::ImmersiveFocusWatcher, - public views::FocusChangeListener, - public aura::client::TransientWindowClientObserver, - public ::wm::ActivationChangeObserver { - public: - explicit ImmersiveFocusWatcherMus( - ash::ImmersiveFullscreenController* controller); - ~ImmersiveFocusWatcherMus() override; - - // ImmersiveFocusWatcher: - void UpdateFocusRevealedLock() override; - void ReleaseLock() override; - - private: - class BubbleObserver; - - views::Widget* GetWidget(); - aura::Window* GetWidgetWindow(); - - // Recreate |bubble_observer_| and start observing any bubbles anchored to a - // child of |top_container_|. - void RecreateBubbleObserver(); - - // views::FocusChangeListener overrides: - void OnWillChangeFocus(views::View* focused_before, - views::View* focused_now) override; - void OnDidChangeFocus(views::View* focused_before, - views::View* focused_now) override; - - // aura::client::TransientWindowClientObserver overrides: - void OnTransientChildWindowAdded(aura::Window* window, - aura::Window* transient) override; - void OnTransientChildWindowRemoved(aura::Window* window, - aura::Window* transient) override; - - // ::wm::ActivationChangeObserver: - void OnWindowActivated( - ::wm::ActivationChangeObserver::ActivationReason reason, - aura::Window* gaining_active, - aura::Window* losing_active) override; - - ash::ImmersiveFullscreenController* immersive_fullscreen_controller_; - - // Lock which keeps the top-of-window views revealed based on the focused view - // and the active widget. Acquiring the lock never triggers a reveal because - // a view is not focusable till a reveal has made it visible. - std::unique_ptr<ash::ImmersiveRevealedLock> lock_; - - // Manages bubbles which are anchored to a child of - // |ImmersiveFullscreenController::top_container_|. - std::unique_ptr<BubbleObserver> bubble_observer_; - - DISALLOW_COPY_AND_ASSIGN(ImmersiveFocusWatcherMus); -}; - -#endif // CHROME_BROWSER_UI_VIEWS_FRAME_IMMERSIVE_FOCUS_WATCHER_MUS_H_
diff --git a/chrome/browser/ui/views/frame/immersive_handler_factory_mus.cc b/chrome/browser/ui/views/frame/immersive_handler_factory_mus.cc index 70def3f2..eabd98f 100644 --- a/chrome/browser/ui/views/frame/immersive_handler_factory_mus.cc +++ b/chrome/browser/ui/views/frame/immersive_handler_factory_mus.cc
@@ -4,21 +4,13 @@ #include "chrome/browser/ui/views/frame/immersive_handler_factory_mus.h" -#include "ash/public/cpp/immersive/immersive_focus_watcher.h" #include "ash/public/cpp/immersive/immersive_gesture_handler.h" #include "base/logging.h" -#include "chrome/browser/ui/views/frame/immersive_focus_watcher_mus.h" ImmersiveHandlerFactoryMus::ImmersiveHandlerFactoryMus() {} ImmersiveHandlerFactoryMus::~ImmersiveHandlerFactoryMus() {} -std::unique_ptr<ash::ImmersiveFocusWatcher> -ImmersiveHandlerFactoryMus::CreateFocusWatcher( - ash::ImmersiveFullscreenController* controller) { - return std::make_unique<ImmersiveFocusWatcherMus>(controller); -} - std::unique_ptr<ash::ImmersiveGestureHandler> ImmersiveHandlerFactoryMus::CreateGestureHandler( ash::ImmersiveFullscreenController* controller) {
diff --git a/chrome/browser/ui/views/frame/immersive_handler_factory_mus.h b/chrome/browser/ui/views/frame/immersive_handler_factory_mus.h index 2504868..ef55a5c 100644 --- a/chrome/browser/ui/views/frame/immersive_handler_factory_mus.h +++ b/chrome/browser/ui/views/frame/immersive_handler_factory_mus.h
@@ -14,8 +14,6 @@ ~ImmersiveHandlerFactoryMus() override; // ImmersiveHandlerFactory: - std::unique_ptr<ash::ImmersiveFocusWatcher> CreateFocusWatcher( - ash::ImmersiveFullscreenController* controller) override; std::unique_ptr<ash::ImmersiveGestureHandler> CreateGestureHandler( ash::ImmersiveFullscreenController* controller) override;
diff --git a/chrome/browser/ui/views/frame/test_with_browser_view.cc b/chrome/browser/ui/views/frame/test_with_browser_view.cc index b930cbb1..45cf73a 100644 --- a/chrome/browser/ui/views/frame/test_with_browser_view.cc +++ b/chrome/browser/ui/views/frame/test_with_browser_view.cc
@@ -103,11 +103,11 @@ // TemplateURLService is normally null during testing. Instant extended // needs this service so set a custom factory function. TemplateURLServiceFactory::GetInstance()->SetTestingFactory( - profile, &CreateTemplateURLService); + profile, base::BindRepeating(&CreateTemplateURLService)); // TODO(jamescook): Eliminate this by introducing a mock toolbar or mock // location bar. AutocompleteClassifierFactory::GetInstance()->SetTestingFactory( - profile, &CreateAutocompleteClassifier); + profile, base::BindRepeating(&CreateAutocompleteClassifier)); // Configure the GaiaCookieManagerService to return no accounts. FakeGaiaCookieManagerService* gcms =
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc index 4b60650f..d84ee939 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -319,10 +319,6 @@ return zoom_view->GetTextForTooltipAndAccessibleName(); } -views::View* ZoomBubbleView::GetInitiallyFocusedView() { - return reset_button_; -} - int ZoomBubbleView::GetDialogButtons() const { return ui::DIALOG_BUTTON_NONE; }
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h index 5fb7f558..45f2fbd3 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
@@ -93,7 +93,6 @@ ~ZoomBubbleView() override; // LocationBarBubbleDelegateView: - View* GetInitiallyFocusedView() override; base::string16 GetAccessibleWindowTitle() const override; int GetDialogButtons() const override; void OnFocus() override;
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc index acaa3ac..214f9d8 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
@@ -360,7 +360,7 @@ // Focus is usually gained via a key combination like alt+shift+a. The test // simulates this by focusing the bubble and then sending an empty KeyEvent. - focus_manager->SetFocusedView(bubble->GetInitiallyFocusedView()); + focus_manager->SetFocusedView(bubble->reset_button_); bubble->OnKeyEvent(nullptr); // |auto_close_timer_| should not be running since focus should prevent the // bubble from closing.
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index a744523..ef3bbc0 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -650,7 +650,7 @@ PostActionPerformed(ProfileMetrics::PROFILE_DESKTOP_MENU_OPEN_USER_MANAGER); } else if (sender == go_incognito_button_) { DCHECK(ShouldShowGoIncognito()); - chrome::NewIncognitoWindow(browser_); + chrome::NewIncognitoWindow(browser_->profile()); PostActionPerformed(ProfileMetrics::PROFILE_DESKTOP_MENU_GO_INCOGNITO); } else if (sender == lock_button_) { profiles::LockProfile(browser_->profile());
diff --git a/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc b/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc index 1cd9951..5bfd0b6 100644 --- a/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc +++ b/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.cc
@@ -121,7 +121,7 @@ } } -void SigninViewControllerDelegateViews::HandleKeyboardEvent( +bool SigninViewControllerDelegateViews::HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { // If this is a MODAL_TYPE_CHILD, then GetFocusManager() will return the focus @@ -129,8 +129,8 @@ // accelerators will fire. If this is a MODAL_TYPE_WINDOW, then this will have // no effect, since no accelerators have been registered for this standalone // window. - unhandled_keyboard_event_handler_.HandleKeyboardEvent(event, - GetFocusManager()); + return unhandled_keyboard_event_handler_.HandleKeyboardEvent( + event, GetFocusManager()); } void SigninViewControllerDelegateViews::DisplayModal() {
diff --git a/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.h b/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.h index 71c00179..9fae456 100644 --- a/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.h +++ b/chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.h
@@ -75,7 +75,7 @@ void ResizeNativeView(int height) override; // content::WebContentsDelegate: - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override;
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.cc b/chrome/browser/ui/views/select_file_dialog_extension.cc index 60efdab..05abd2a 100644 --- a/chrome/browser/ui/views/select_file_dialog_extension.cc +++ b/chrome/browser/ui/views/select_file_dialog_extension.cc
@@ -294,6 +294,11 @@ return NULL; } +bool SelectFileDialogExtension::IsResizeable() const { + DCHECK(extension_dialog_.get()); + return extension_dialog_->CanResize(); +} + void SelectFileDialogExtension::NotifyListener() { if (!listener_) return;
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.h b/chrome/browser/ui/views/select_file_dialog_extension.h index 7779bae..7e112bf 100644 --- a/chrome/browser/ui/views/select_file_dialog_extension.h +++ b/chrome/browser/ui/views/select_file_dialog_extension.h
@@ -97,6 +97,10 @@ // Returns true if the dialog has multiple file type choices. bool HasMultipleFileTypeChoicesImpl() override; + // Returns true if |extension_dialog_| is resizable; the dialog must be + // non-null at the time of this call. + bool IsResizeable() const; + bool has_multiple_file_type_choices_; // Host for the extension that implements this dialog.
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc index 108c206..f1ce561 100644 --- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -80,6 +80,7 @@ #include "ui/aura/window_event_dispatcher.h" #include "ui/base/ui_base_features.h" #include "ui/display/manager/display_manager.h" +#include "ui/events/gesture_detection/gesture_configuration.h" #include "ui/events/test/event_generator.h" #endif @@ -425,6 +426,10 @@ #if defined(OS_CHROMEOS) root_ = browser()->window()->GetNativeWindow()->GetRootWindow(); event_generator_ = std::make_unique<ui::test::EventGenerator>(root_); + // Disable flings which might otherwise inadvertently be generated from + // tests' touch events. + ui::GestureConfiguration::GetInstance()->set_min_fling_velocity( + std::numeric_limits<float>::max()); #endif #if defined(OS_MACOSX) // Currently MacViews' browser windows are shown in the background and could
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc index aa3c784e..ccb4c42 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
@@ -88,13 +88,6 @@ // TODO(pbos): Consolidate with ToolbarButton::OnBoundsChanged. SetProperty(views::kHighlightPathKey, CreateToolbarHighlightPath(this, gfx::Insets()).release()); - if (focus_ring()) { - // For extensions we can't use a circular focus ring path since it may - // obscure the extension icon. - gfx::Path path; - path.addRect(RectToSkRect(GetLocalBounds())); - focus_ring()->SetPath(path); - } MenuButton::OnBoundsChanged(previous_bounds); } @@ -307,9 +300,6 @@ DCHECK(visible()); // We should never show a context menu for a hidden item. - gfx::Point screen_loc; - ConvertPointToScreen(this, &screen_loc); - int run_types = views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU; if (delegate_->ShownInsideMenu()) @@ -330,7 +320,7 @@ menu_ = menu_adapter_->CreateMenu(); menu_runner_.reset(new views::MenuRunner(menu_, run_types)); - menu_runner_->RunMenuAt(parent, this, gfx::Rect(screen_loc, size()), + menu_runner_->RunMenuAt(parent, this, GetAnchorBoundsInScreen(), views::MENU_ANCHOR_TOPLEFT, source_type); }
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc index bfbed7e9..0647fc5 100644 --- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc +++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc
@@ -6,7 +6,7 @@ #include "base/metrics/histogram_macros.h" #include "chrome/browser/consent_auditor/consent_auditor_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/webui/chromeos/user_image_source.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" @@ -14,6 +14,7 @@ #include "components/consent_auditor/consent_auditor.h" #include "components/signin/core/browser/signin_manager_base.h" #include "components/user_manager/user_manager.h" +#include "services/identity/public/cpp/identity_manager.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/webui/web_ui_util.h" @@ -208,10 +209,9 @@ void RecordActivityControlConsent(Profile* profile, std::string ui_audit_key, bool opted_in) { - SigninManagerBase* signin_manager = - SigninManagerFactory::GetForProfile(profile); - DCHECK(signin_manager->IsAuthenticated()); - std::string account_id = signin_manager->GetAuthenticatedAccountId(); + auto* identity_manager = IdentityManagerFactory::GetForProfile(profile); + DCHECK(identity_manager->HasPrimaryAccount()); + const std::string account_id = identity_manager->GetPrimaryAccountId(); UserConsentTypes::AssistantActivityControlConsent consent; consent.set_ui_audit_key(ui_audit_key);
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h index 01f918c..f5013d2 100644 --- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h +++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h
@@ -20,17 +20,17 @@ // histogram and should be treated as append-only. enum AssistantOptInFlowStatus { FLOW_STARTED = 0, - ACTIVITY_CONTROL_SHOWN, - ACTIVITY_CONTROL_ACCEPTED, - ACTIVITY_CONTROL_SKIPPED, - THIRD_PARTY_SHOWN, - THIRD_PARTY_CONTINUED, - GET_MORE_SHOWN, - EMAIL_OPTED_IN, - EMAIL_OPTED_OUT, - GET_MORE_CONTINUED, - READY_SCREEN_SHOWN, - READY_SCREEN_CONTINUED, + ACTIVITY_CONTROL_SHOWN = 1, + ACTIVITY_CONTROL_ACCEPTED = 2, + ACTIVITY_CONTROL_SKIPPED = 3, + THIRD_PARTY_SHOWN = 4, + THIRD_PARTY_CONTINUED = 5, + GET_MORE_SHOWN = 6, + EMAIL_OPTED_IN = 7, + EMAIL_OPTED_OUT = 8, + GET_MORE_CONTINUED = 9, + READY_SCREEN_SHOWN = 10, + READY_SCREEN_CONTINUED = 11, // Magic constant used by the histogram macros. kMaxValue = READY_SCREEN_CONTINUED };
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.cc b/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.cc index 5a36e498..8a1efd47 100644 --- a/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.cc +++ b/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.cc
@@ -100,9 +100,10 @@ return web_contents_; } -void ConstrainedWebDialogDelegateBase::HandleKeyboardEvent( +bool ConstrainedWebDialogDelegateBase::HandleKeyboardEvent( content::WebContents* source, const NativeWebKeyboardEvent& event) { + return false; } gfx::Size ConstrainedWebDialogDelegateBase::GetConstrainedWebDialogMinimumSize()
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h b/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h index 56111eb2..bea210c 100644 --- a/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h +++ b/chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h
@@ -51,7 +51,7 @@ void WebContentsDestroyed() override; // WebDialogWebContentsDelegate interface. - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override;
diff --git a/chrome/browser/ui/webui/extensions/extensions_internals_source.cc b/chrome/browser/ui/webui/extensions/extensions_internals_source.cc index 6b410ca..f1768b4 100644 --- a/chrome/browser/ui/webui/extensions/extensions_internals_source.cc +++ b/chrome/browser/ui/webui/extensions/extensions_internals_source.cc
@@ -115,10 +115,13 @@ // DICT // "event_listeners": DICT // "count": INT -// "events": LIST +// "listeners": LIST // DICT -// "name": STRING +// "event_name": STRING // "filter": DICT +// "is_for_service_worker": STRING +// "is_lazy": STRING +// "url": STRING // "id": STRING // "keepalive": DICT // "activities": LIST @@ -135,14 +138,18 @@ constexpr base::StringPiece kActivitesKey = "activites"; constexpr base::StringPiece kCountKey = "count"; -constexpr base::StringPiece kEventsKey = "events"; +constexpr base::StringPiece kEventNameKey = "event_name"; constexpr base::StringPiece kEventsListenersKey = "event_listeners"; constexpr base::StringPiece kExtraDataKey = "extra_data"; constexpr base::StringPiece kFilterKey = "filter"; constexpr base::StringPiece kInternalsIdKey = "id"; constexpr base::StringPiece kInternalsNameKey = "name"; constexpr base::StringPiece kInternalsVersionKey = "version"; +constexpr base::StringPiece kIsForServiceWorkerKey = "is_for_service_worker"; +constexpr base::StringPiece kIsLazyKey = "is_lazy"; +constexpr base::StringPiece kListenersKey = "listeners"; constexpr base::StringPiece kKeepaliveKey = "keepalive"; +constexpr base::StringPiece kListenerUrlKey = "url"; constexpr base::StringPiece kLocationKey = "location"; constexpr base::StringPiece kManifestVersionKey = "manifest_version"; constexpr base::StringPiece kPathKey = "path"; @@ -172,30 +179,35 @@ void AddEventListenerData(extensions::EventRouter* event_router, base::Value* data) { CHECK(data->is_list()); - // A map of extension ID to the event data for that extension, + // A map of extension ID to the listener data for that extension, // which is of type LIST of DICTIONARY. std::unordered_map<base::StringPiece, base::Value, base::StringPieceHash> - events_map; + listeners_map; // Build the map of extension IDs to the list of events. for (const auto& entry : event_router->listeners().listeners()) { for (const auto& listener_entry : entry.second) { - auto& events_list = events_map[listener_entry->extension_id()]; - if (events_list.is_none()) { + auto& listeners_list = listeners_map[listener_entry->extension_id()]; + if (listeners_list.is_none()) { // Not there, so make it a LIST. - events_list = base::Value(base::Value::Type::LIST); + listeners_list = base::Value(base::Value::Type::LIST); } - // The data for each event is a dictionary, with a name and a - // filter. - base::Value event_data(base::Value::Type::DICTIONARY); - event_data.SetKey(kInternalsNameKey, - base::Value(listener_entry->event_name())); + // The data for each listener is a dictionary. + base::Value listener_data(base::Value::Type::DICTIONARY); + listener_data.SetKey(kEventNameKey, + base::Value(listener_entry->event_name())); + listener_data.SetKey( + kIsForServiceWorkerKey, + base::Value(listener_entry->is_for_service_worker())); + listener_data.SetKey(kIsLazyKey, base::Value(listener_entry->IsLazy())); + listener_data.SetKey(kListenerUrlKey, + base::Value(listener_entry->listener_url().spec())); // Add the filter if one exists. base::Value* const filter = listener_entry->filter(); if (filter != nullptr) { - event_data.SetKey(kFilterKey, filter->Clone()); + listener_data.SetKey(kFilterKey, filter->Clone()); } - events_list.GetList().push_back(std::move(event_data)); + listeners_list.GetList().push_back(std::move(listener_data)); } } @@ -203,20 +215,21 @@ for (auto& output_entry : data->GetList()) { const base::Value* const value = output_entry.FindKey(kInternalsIdKey); CHECK(value && value->is_string()); - const auto it = events_map.find(value->GetString()); - base::Value listeners(base::Value::Type::DICTIONARY); - if (it == events_map.end()) { + const auto it = listeners_map.find(value->GetString()); + base::Value event_listeners(base::Value::Type::DICTIONARY); + if (it == listeners_map.end()) { // We didn't find any events, so initialize an empty dictionary. - listeners.SetKey(kCountKey, base::Value(0)); - listeners.SetKey(kEventsKey, base::Value(base::Value::Type::LIST)); + event_listeners.SetKey(kCountKey, base::Value(0)); + event_listeners.SetKey(kListenersKey, + base::Value(base::Value::Type::LIST)); } else { // Set the count and the events values. - listeners.SetKey( + event_listeners.SetKey( kCountKey, base::Value(base::checked_cast<int>(it->second.GetList().size()))); - listeners.SetKey(kEventsKey, std::move(it->second)); + event_listeners.SetKey(kListenersKey, std::move(it->second)); } - output_entry.SetKey(kEventsListenersKey, std::move(listeners)); + output_entry.SetKey(kEventsListenersKey, std::move(event_listeners)); } }
diff --git a/chrome/browser/ui/webui/welcome/welcome_ui.cc b/chrome/browser/ui/webui/welcome/welcome_ui.cc index 45010722..baf359e 100644 --- a/chrome/browser/ui/webui/welcome/welcome_ui.cc +++ b/chrome/browser/ui/webui/welcome/welcome_ui.cc
@@ -81,6 +81,10 @@ html_source->AddResourcePath( "navigation_behavior.js", IDR_WELCOME_ONBOARDING_WELCOME_NAVIGATION_BEHAVIOR_JS); + html_source->AddResourcePath( + "signin_view.html", IDR_WELCOME_ONBOARDING_WELCOME_SIGNIN_VIEW_HTML); + html_source->AddResourcePath("signin_view.js", + IDR_WELCOME_ONBOARDING_WELCOME_SIGNIN_VIEW_JS); html_source->AddResourcePath("welcome.css", IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_CSS); html_source->AddResourcePath( @@ -95,11 +99,45 @@ IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_BROWSER_PROXY_JS); // Add resources shared by the NUX modules. - html_source->AddResourcePath("shared/chooser_shared_css.html", - IDR_NUX_CHOOSER_SHARED_CSS); + html_source->AddResourcePath( + "shared/action_link_style_css.html", + IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ACTION_LINK_STYLE_CSS_HTML); + html_source->AddResourcePath( + "shared/action_link_style.js", + IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ACTION_LINK_STYLE_JS); + html_source->AddResourcePath( + "shared/chooser_shared_css.html", + IDR_WELCOME_ONBOARDING_WELCOME_SHARED_CHOOSER_SHARED_CSS); + html_source->AddResourcePath( + "shared/onboarding_background.html", + IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ONBOARDING_BACKGROUND_HTML); + html_source->AddResourcePath( + "shared/onboarding_background.js", + IDR_WELCOME_ONBOARDING_WELCOME_SHARED_ONBOARDING_BACKGROUND_JS); html_source->AddResourcePath( "shared/i18n_setup.html", IDR_WELCOME_ONBOARDING_WELCOME_SHARED_I18N_SETUP_HTML); + html_source->AddResourcePath( + "images/background_svgs/blue_circle.svg", + IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_BLUE_CIRCLE_SVG); + html_source->AddResourcePath( + "images/background_svgs/green_rectangle.svg", + IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_GREEN_RECTANGLE_SVG); + html_source->AddResourcePath( + "images/background_svgs/grey_oval.svg", + IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_GREY_OVAL_SVG); + html_source->AddResourcePath( + "images/background_svgs/grey_rounded_rectangle.svg", + IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_GREY_ROUNDED_RECTANGLE_SVG); + html_source->AddResourcePath( + "images/background_svgs/red_triangle.svg", + IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_RED_TRIANGLE_SVG); + html_source->AddResourcePath( + "images/background_svgs/yellow_dots.svg", + IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_YELLOW_DOTS_SVG); + html_source->AddResourcePath( + "images/background_svgs/yellow_semicircle.svg", + IDR_WELCOME_ONBOARDING_WELCOME_IMAGES_BACKGROUND_SVGS_YELLOW_SEMICIRCLE_SVG); // Add email provider bookmarking onboarding module. web_ui->AddMessageHandler(std::make_unique<nux::EmailHandler>(
diff --git a/chrome/credential_provider/gaiacp/BUILD.gn b/chrome/credential_provider/gaiacp/BUILD.gn index 4d8d07f..771abce 100644 --- a/chrome/credential_provider/gaiacp/BUILD.gn +++ b/chrome/credential_provider/gaiacp/BUILD.gn
@@ -115,11 +115,37 @@ output = "$root_out_dir/gaia_credential_provider.rc" } +if (is_chrome_branded) { + gaia_credential_provider_clsid = "0b5bfdf0-4594-47ac-940a-cfc69abc561c" +} else { + gaia_credential_provider_clsid = "89adae71-aee5-4ee2-bffb-e8424e06f519" +} + +action("generate_credential_provider_idl_file") { + script = "//build/util/version.py" + + inputs = [ + "gaia_credential_provider_idl.templ", + ] + outputs = [ + "$target_gen_dir/gaia_credential_provider.idl", + ] + + args = [ + "-e", + "GAIA_CREDENTIAL_PROVIDER_CLSID='$gaia_credential_provider_clsid'", + rebase_path(inputs[0], root_build_dir), + rebase_path(outputs[0], root_build_dir), + ] +} + midl("gaia_credential_provider_idl") { - sources = [ - "gaia_credential_provider.idl", + dynamic_guid = gaia_credential_provider_clsid + deps = [ + ":generate_credential_provider_idl_file", ] header_file = "gaia_credential_provider_i.h" + sources = get_target_outputs(":generate_credential_provider_idl_file") } grit("resources") {
diff --git a/chrome/credential_provider/gaiacp/dllmain.cc b/chrome/credential_provider/gaiacp/dllmain.cc index a7f4e8e..68f37b0 100644 --- a/chrome/credential_provider/gaiacp/dllmain.cc +++ b/chrome/credential_provider/gaiacp/dllmain.cc
@@ -74,6 +74,7 @@ LOGFN(INFO) << "_AtlModule.DllRegisterServer hr=" << putHR(hr); } +#if defined(GOOGLE_CHROME_BUILD) // Register with Google Update. if (SUCCEEDED(hr)) { base::win::RegKey key(HKEY_LOCAL_MACHINE, @@ -92,17 +93,22 @@ } } } +#endif // defined(GOOGLE_CHROME_BUILD) return hr; } // DllUnregisterServer - Removes entries from the system registry. STDAPI DllUnregisterServer(void) { - // Unegister with Google Update. +#if defined(GOOGLE_CHROME_BUILD) + // Unregister with Google Update. base::win::RegKey key(HKEY_LOCAL_MACHINE, L"", DELETE | KEY_WOW64_32KEY); LONG sts = key.DeleteKey(credential_provider::kRegUpdaterClientsAppPath); bool all_succeeded = sts == ERROR_SUCCESS; +#else + bool all_succeeded = true; +#endif HRESULT hr = credential_provider::CGaiaCredentialBase::OnDllUnregisterServer();
diff --git a/chrome/credential_provider/gaiacp/gaia_credential.h b/chrome/credential_provider/gaiacp/gaia_credential.h index c26e469..b29f828 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential.h +++ b/chrome/credential_provider/gaiacp/gaia_credential.h
@@ -14,7 +14,6 @@ // Implementation of an ICredentialProviderCredential backed by a Gaia account. class ATL_NO_VTABLE CGaiaCredential : public CComObjectRootEx<CComMultiThreadModel>, - public CComCoClass<CGaiaCredential, &CLSID_GaiaCredential>, public CGaiaCredentialBase { public: DECLARE_NO_REGISTRY() @@ -45,8 +44,6 @@ BSTR* error_text) override; }; -OBJECT_ENTRY_AUTO(__uuidof(GaiaCredential), CGaiaCredential) - } // namespace credential_provider #endif // CHROME_CREDENTIAL_PROVIDER_GAIACP_GAIA_CREDENTIAL_H_
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base.cc b/chrome/credential_provider/gaiacp/gaia_credential_base.cc index f2e7ab0..49c1e8b8 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_base.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_base.cc
@@ -512,6 +512,7 @@ // static void CGaiaCredentialBase::TellOmahaDidRun() { +#if defined(GOOGLE_CHROME_BUILD) // Tell omaha that product was used. Best effort only. // // This code always runs as LocalSystem, which means that HKCU maps to @@ -527,6 +528,7 @@ if (sts != ERROR_SUCCESS) LOGFN(INFO) << "Unable to write omaha dr value sts=" << sts; } +#endif // defined(GOOGLE_CHROME_BUILD) } // static
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider.rgs b/chrome/credential_provider/gaiacp/gaia_credential_provider.rgs index 38330ed..fdaa1d3 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider.rgs +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider.rgs
@@ -2,13 +2,12 @@ { NoRemove CLSID { - ForceRemove {0B5BFDF0-4594-47AC-940A-CFC69ABC561C} = s 'GaiaCredentialProvider Class' + ForceRemove %CREDENTIAL_PROVIDER_CLASS_GUID% = s 'Google Credential Provider Class' { InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' } - TypeLib = s '{4ADC3A52-8673-4CE3-81F6-833D18BEEBA2}' Version = s '%VERSION%' } } @@ -27,7 +26,7 @@ { NoRemove 'Credential Providers' { - ForceRemove {0B5BFDF0-4594-47AC-940A-CFC69ABC561C} = s 'Google Credential Provider' + ForceRemove %CREDENTIAL_PROVIDER_CLASS_GUID% = s 'Google Credential Provider' { } }
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider.idl b/chrome/credential_provider/gaiacp/gaia_credential_provider_idl.templ similarity index 65% rename from chrome/credential_provider/gaiacp/gaia_credential_provider.idl rename to chrome/credential_provider/gaiacp/gaia_credential_provider_idl.templ index c37971c..c49c134 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider.idl +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider_idl.templ
@@ -1,90 +1,76 @@ // Copyright 2018 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. - -// This file will be processed by the MIDL tool to -// produce the type library (GaiaCredentialProvider.tlb) and marshalling code. - -import "oaidl.idl"; -import "ocidl.idl"; - -[ - object, - uuid(CEC9EF6C-B2E6-4BB6-8F1E-1747BA4F7138), - pointer_default(unique) -] -interface IGaiaCredentialProvider : IUnknown { - HRESULT OnUserAuthenticated([in] IUnknown* credential, - [in] BSTR username, - [in] BSTR password, - [in] BSTR sid); -}; - -[ - object, - uuid(224CE2FB-2977-4585-BD46-1BAE8D7964DE), - pointer_default(unique) -] -interface IGaiaCredentialProviderForTesting : IUnknown { - HRESULT SetReauthCheckDoneEvent([in] INT_PTR event); -}; - -[ - object, - uuid(E5BF88DF-9966-465B-B233-C1CAC7510A59), - pointer_default(unique) -] -interface IGaiaCredential : IUnknown { - HRESULT Initialize([in] IGaiaCredentialProvider* provider); - HRESULT Terminate(); - HRESULT FinishAuthentication([in] BSTR username, - [in] BSTR password, - [in] BSTR fullname, - [out] BSTR* sid, - [out] BSTR* error_text); - HRESULT OnUserAuthenticated([in] BSTR username, - [in] BSTR password, - [in] BSTR sid); - HRESULT ReportError([in] LONG status, - [in] LONG substatus, - [in] BSTR status_text); -}; - -[ - object, - uuid(CC75BCEA-A636-4798-BF8E-0FF64D743451), - pointer_default(unique) -] -interface IReauthCredential : IUnknown { - HRESULT SetUserInfo([in] BSTR sid, [in] BSTR email); -}; - -[ - uuid(4ADC3A52-8673-4CE3-81F6-833D18BEEBA2), - version(1.0), -] -library GaiaCredentialProviderLib -{ - importlib("stdole2.tlb"); - [ - uuid(0B5BFDF0-4594-47AC-940A-CFC69ABC561C) - ] - coclass GaiaCredentialProvider - { - [default] interface IGaiaCredentialProvider; - }; - [ - uuid(44AF95AC-6B23-4C54-94BE-EDB1CB52DAFD) - ] - coclass GaiaCredential - { - [default] interface IGaiaCredential; - }; - [ - uuid(E6CC5D8B-54C2-4586-ADC3-748ED16284B7) - ] - coclass ReauthCredential - { - [default] interface IGaiaCredential; - }; -}; + +// This file will be processed by the MIDL tool to +// produce the type library (GaiaCredentialProvider.tlb) and marshalling code. + +import "oaidl.idl"; +import "ocidl.idl"; + +[ + object, + uuid(CEC9EF6C-B2E6-4BB6-8F1E-1747BA4F7138), + pointer_default(unique) +] +interface IGaiaCredentialProvider : IUnknown { + HRESULT OnUserAuthenticated([in] IUnknown* credential, + [in] BSTR username, + [in] BSTR password, + [in] BSTR sid); +}; + +[ + object, + uuid(224CE2FB-2977-4585-BD46-1BAE8D7964DE), + pointer_default(unique) +] +interface IGaiaCredentialProviderForTesting : IUnknown { + HRESULT SetReauthCheckDoneEvent([in] INT_PTR event); +}; + +[ + object, + uuid(E5BF88DF-9966-465B-B233-C1CAC7510A59), + pointer_default(unique) +] +interface IGaiaCredential : IUnknown { + HRESULT Initialize([in] IGaiaCredentialProvider* provider); + HRESULT Terminate(); + HRESULT FinishAuthentication([in] BSTR username, + [in] BSTR password, + [in] BSTR fullname, + [out] BSTR* sid, + [out] BSTR* error_text); + HRESULT OnUserAuthenticated([in] BSTR username, + [in] BSTR password, + [in] BSTR sid); + HRESULT ReportError([in] LONG status, + [in] LONG substatus, + [in] BSTR status_text); +}; + +[ + object, + uuid(CC75BCEA-A636-4798-BF8E-0FF64D743451), + pointer_default(unique) +] +interface IReauthCredential : IUnknown { + HRESULT SetUserInfo([in] BSTR sid, [in] BSTR email); +}; + +[ + uuid(4ADC3A52-8673-4CE3-81F6-833D18BEEBA2), + version(1.0), +] +library GaiaCredentialProviderLib +{ + importlib("stdole2.tlb"); + [ + uuid(@GAIA_CREDENTIAL_PROVIDER_CLSID@), + ] + coclass GaiaCredentialProvider + { + [default] interface IGaiaCredentialProvider; + }; +};
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider_module.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider_module.cc index 2a694ed..e8720c1 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider_module.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider_module.cc
@@ -48,8 +48,11 @@ eventlog_path = eventlog_path.Append(FILE_PATH_LITERAL("gcp_eventlog_provider.dll")); + wchar_t guid_in_wchar[64]; + StringFromGUID2(CLSID_GaiaCredentialProvider, guid_in_wchar, base::size(guid_in_wchar)); + ATL::_ATL_REGMAP_ENTRY regmap[] = { - {L"APPID", L"{C2DDF2F2-F760-4B27-92F4-3461EE8A7A0B}"}, + {L"CREDENTIAL_PROVIDER_CLASS_GUID", guid_in_wchar}, {L"VERSION", TEXT(CHROME_VERSION_STRING)}, {L"EVENTLOG_PATH", eventlog_path.value().c_str()}, {nullptr, nullptr},
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc index 5decba9..2924512 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc
@@ -87,14 +87,12 @@ // Expect "good" sid to still in the registry, "bad" one to be cleaned up. base::win::RegKey key; - ASSERT_EQ(ERROR_SUCCESS, - key.Open(HKEY_LOCAL_MACHINE, L"Software\\Google\\GCP\\Users\\", - KEY_READ)); + ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_LOCAL_MACHINE, + GetUsersRootKeyForTesting(), KEY_READ)); EXPECT_EQ(ERROR_SUCCESS, key.OpenKey(OLE2CW(sid_good), KEY_READ)); - ASSERT_EQ(ERROR_SUCCESS, - key.Open(HKEY_LOCAL_MACHINE, L"Software\\Google\\GCP\\Users\\", - KEY_READ)); + ASSERT_EQ(ERROR_SUCCESS, key.Open(HKEY_LOCAL_MACHINE, + GetUsersRootKeyForTesting(), KEY_READ)); EXPECT_NE(ERROR_SUCCESS, key.OpenKey(OLE2CW(sid_bad), KEY_READ)); }
diff --git a/chrome/credential_provider/gaiacp/reauth_credential.h b/chrome/credential_provider/gaiacp/reauth_credential.h index 443d6b97..00358df 100644 --- a/chrome/credential_provider/gaiacp/reauth_credential.h +++ b/chrome/credential_provider/gaiacp/reauth_credential.h
@@ -13,7 +13,6 @@ // Implementation of a ICredentialProviderCredential backed by a Gaia account. class ATL_NO_VTABLE CReauthCredential : public CComObjectRootEx<CComMultiThreadModel>, - public CComCoClass<CReauthCredential, &CLSID_ReauthCredential>, public CGaiaCredentialBase, public IReauthCredential { public: @@ -62,8 +61,6 @@ CComBSTR user_email_; }; -OBJECT_ENTRY_AUTO(__uuidof(ReauthCredential), CReauthCredential) - } // namespace credential_provider #endif // CHROME_CREDENTIAL_PROVIDER_GAIACP_REAUTH_CREDENTIAL_H_
diff --git a/chrome/credential_provider/gaiacp/reg_utils.cc b/chrome/credential_provider/gaiacp/reg_utils.cc index 471209b..446dc85 100644 --- a/chrome/credential_provider/gaiacp/reg_utils.cc +++ b/chrome/credential_provider/gaiacp/reg_utils.cc
@@ -15,9 +15,13 @@ namespace { // Root registry key for GCP configuration and state. -// TODO(crbug.com/883943): This should be different between Chromium and -// Google Chrome builds. -const wchar_t kGcpRootKeyName[] = L"Software\\Google\\GCP"; +#if defined(GOOGLE_CHROME_BUILD) +#define CREDENTIAL_PROVIDER_REGISTRY_KEY L"Software\\Google\\GCP" +#else +#define CREDENTIAL_PROVIDER_REGISTRY_KEY L"Software\\Chromium\\GCP" +#endif // defined(GOOGLE_CHROME_BUILD) + +const wchar_t kGcpRootKeyName[] = CREDENTIAL_PROVIDER_REGISTRY_KEY; HRESULT GetRegDWORD(const base::string16& key_name, const base::string16& name, @@ -177,4 +181,8 @@ return S_OK; } +const wchar_t* GetUsersRootKeyForTesting() { + return CREDENTIAL_PROVIDER_REGISTRY_KEY L"\\Users"; +} + } // namespace credential_provider
diff --git a/chrome/credential_provider/gaiacp/reg_utils.h b/chrome/credential_provider/gaiacp/reg_utils.h index 5a066b9d..9dd6492 100644 --- a/chrome/credential_provider/gaiacp/reg_utils.h +++ b/chrome/credential_provider/gaiacp/reg_utils.h
@@ -53,6 +53,9 @@ // Gets token handles for all users created by this credential provider. HRESULT GetUserTokenHandles(std::map<base::string16, base::string16>* handles); +// Returns the root registry key that needs to be verified in unit tests. +const wchar_t* GetUsersRootKeyForTesting(); + } // namespace credential_provider #endif // CHROME_CREDENTIAL_PROVIDER_GAIACP_REG_UTILS_H_
diff --git a/chrome/credential_provider/gaiacp/scoped_user_profile.cc b/chrome/credential_provider/gaiacp/scoped_user_profile.cc index 29b09e3..ceed754 100644 --- a/chrome/credential_provider/gaiacp/scoped_user_profile.cc +++ b/chrome/credential_provider/gaiacp/scoped_user_profile.cc
@@ -23,7 +23,11 @@ namespace { // Registry key under HKCU to write account info into. +#if defined(GOOGLE_CHROME_BUILD) const wchar_t kRegAccountsPath[] = L"Software\\Google\\Accounts"; +#else +const wchar_t kRegAccountsPath[] = L"Software\\Chromium\\Accounts"; +#endif // defined(GOOGLE_CHROME_BUILD) std::string GetEncryptedRefreshToken( base::win::ScopedHandle::Handle logon_handle,
diff --git a/chrome/credential_provider/setup/setup_lib.cc b/chrome/credential_provider/setup/setup_lib.cc index a0e753e..af7abf3 100644 --- a/chrome/credential_provider/setup/setup_lib.cc +++ b/chrome/credential_provider/setup/setup_lib.cc
@@ -57,7 +57,7 @@ return base::FilePath(); } - dest_path = dest_path.Append(FILE_PATH_LITERAL("Google")) + dest_path = dest_path.Append(GetInstallParentDirectoryName()) .Append(FILE_PATH_LITERAL("Credential Provider")); if (!base::CreateDirectory(dest_path)) { @@ -379,4 +379,12 @@ *count = base::size(kFilenames); } +base::FilePath::StringType GetInstallParentDirectoryName() { +#if defined(GOOGLE_CHROME_BUILD) + return FILE_PATH_LITERAL("Google"); +#else + return FILE_PATH_LITERAL("Chromium"); +#endif +} + } // namespace credential_provider
diff --git a/chrome/credential_provider/setup/setup_lib.h b/chrome/credential_provider/setup/setup_lib.h index b578537..a202050c 100644 --- a/chrome/credential_provider/setup/setup_lib.h +++ b/chrome/credential_provider/setup/setup_lib.h
@@ -51,6 +51,9 @@ void GetInstalledFileBasenames(const base::FilePath::CharType* const** names, size_t* count); +// Gets the brand specific path in which to install GCPW. +base::FilePath::StringType GetInstallParentDirectoryName(); + } // namespace credential_provider #endif // CHROME_CREDENTIAL_PROVIDER_SETUP_SETUP_LIB_H_
diff --git a/chrome/credential_provider/test/gcp_setup_unittests.cc b/chrome/credential_provider/test/gcp_setup_unittests.cc index 64de979..77db864 100644 --- a/chrome/credential_provider/test/gcp_setup_unittests.cc +++ b/chrome/credential_provider/test/gcp_setup_unittests.cc
@@ -17,11 +17,13 @@ #include "base/files/scoped_temp_dir.h" #include "base/process/launch.h" #include "base/strings/string16.h" +#include "base/strings/stringprintf.h" #include "base/syslog_logging.h" #include "base/test/scoped_path_override.h" #include "base/test/test_reg_util_win.h" #include "base/win/registry.h" #include "build/build_config.h" +#include "chrome/credential_provider/gaiacp/gaia_credential_provider_i.h" #include "chrome/credential_provider/gaiacp/gcp_strings.h" #include "chrome/credential_provider/gaiacp/gcp_utils.h" #include "chrome/credential_provider/setup/setup_lib.h" @@ -39,13 +41,14 @@ void ExpectAllFilesToExist(bool exist, const base::string16& product_version); void ExpectCredentialProviderToBeRegistered( - bool registered, - const base::string16& product_version); + bool registered, + const base::string16& product_version); base::FilePath installed_path_for_version( const base::string16& product_version) { return scoped_temp_prog_dir_.GetPath() - .Append(FILE_PATH_LITERAL("Google\\Credential Provider")) + .Append(GetInstallParentDirectoryName()) + .Append(FILE_PATH_LITERAL("Credential Provider")) .Append(product_version); } @@ -118,10 +121,15 @@ void GcpSetupTest::ExpectCredentialProviderToBeRegistered( bool registered, const base::string16& product_version) { + wchar_t guid_in_wchar[64]; + StringFromGUID2(CLSID_GaiaCredentialProvider, guid_in_wchar, + base::size(guid_in_wchar)); + // Make sure COM object is registered. - base::string16 subkey( - L"CLSID\\{0B5BFDF0-4594-47AC-940A-CFC69ABC561C}\\InprocServer32"); - base::win::RegKey clsid_key(HKEY_CLASSES_ROOT, subkey.c_str(), KEY_READ); + base::string16 register_key_path = + base::StringPrintf(L"CLSID\\%ls\\InprocServer32", guid_in_wchar); + base::win::RegKey clsid_key(HKEY_CLASSES_ROOT, register_key_path.c_str(), + KEY_READ); EXPECT_EQ(registered, clsid_key.Valid()); if (registered) { @@ -132,12 +140,12 @@ EXPECT_EQ(path.value(), value); } + base::string16 cp_key_path = base::StringPrintf( + L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" + L"Authentication\\Credential Providers\\%ls", guid_in_wchar); + // Make sure credential provider is registered. - base::win::RegKey cp_key(HKEY_LOCAL_MACHINE, - L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" - L"Authentication\\Credential Providers\\" - L"{0B5BFDF0-4594-47AC-940A-CFC69ABC561C}", - KEY_READ); + base::win::RegKey cp_key(HKEY_LOCAL_MACHINE, cp_key_path.c_str(), KEY_READ); EXPECT_EQ(registered, cp_key.Valid()); // Make sure eventlog source is registered. @@ -228,8 +236,8 @@ FakeOSUserManager::UserInfo old_user_info = fake_os_user_manager()->GetUserInfo(kGaiaAccountName); - base::string16 old_password = fake_scoped_lsa_policy_factory() - ->private_data()[kLsaKeyGaiaPassword]; + base::string16 old_password = + fake_scoped_lsa_policy_factory()->private_data()[kLsaKeyGaiaPassword]; EXPECT_FALSE(old_password.empty()); logging::ResetEventSourceForTesting(); @@ -245,9 +253,9 @@ // Make sure kGaiaAccountName info and private data are unchanged. EXPECT_EQ(old_user_info, fake_os_user_manager()->GetUserInfo(kGaiaAccountName)); - EXPECT_EQ(old_password, - fake_scoped_lsa_policy_factory() - ->private_data()[kLsaKeyGaiaPassword]); + EXPECT_EQ( + old_password, + fake_scoped_lsa_policy_factory()->private_data()[kLsaKeyGaiaPassword]); } TEST_F(GcpSetupTest, DoInstallOverOldLockedInstall) {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 7acb691..0e870a2c 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2500,7 +2500,6 @@ "../browser/metrics/thread_watcher_android_unittest.cc", "../browser/metrics/thread_watcher_unittest.cc", "../browser/navigation_predictor/navigation_predictor_unittest.cc", - "../browser/net/chrome_accept_language_settings_unittest.cc", "../browser/net/chrome_network_delegate_unittest.cc", "../browser/net/dns_probe_runner_unittest.cc", "../browser/net/dns_probe_service_unittest.cc", @@ -3381,7 +3380,7 @@ "../browser/feature_engagement/new_tab/new_tab_tracker_unittest.cc", "../browser/feature_engagement/session_duration_updater_unittest.cc", "../browser/ui/in_product_help/active_tab_tracker_unittest.cc", - "../browser/ui/in_product_help/reopen_tab_iph_trigger_unittest.cc", + "../browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.cc", ] deps += [ "//components/feature_engagement/test:test_support" ] }
diff --git a/chrome/test/base/interactive_test_utils.h b/chrome/test/base/interactive_test_utils.h index eb0fdfd..96de5b8f 100644 --- a/chrome/test/base/interactive_test_utils.h +++ b/chrome/test/base/interactive_test_utils.h
@@ -92,6 +92,9 @@ // Makes focus shift to the given View without clicking it. void FocusView(const Browser* browser, ViewID vid); +// Wait until the view identified by |view_id| in |browser| gets focused. +void WaitUntilViewFocused(const Browser* browser, ViewID view_id); + // A collection of utilities that are used from interactive_ui_tests. These are // separated from ui_test_utils.h to ensure that browser_tests don't use them, // since they depend on focus which isn't possible for sharded test.
diff --git a/chrome/test/base/interactive_test_utils_aura.cc b/chrome/test/base/interactive_test_utils_aura.cc index 61f0d3ef6..50fec613 100644 --- a/chrome/test/base/interactive_test_utils_aura.cc +++ b/chrome/test/base/interactive_test_utils_aura.cc
@@ -4,10 +4,47 @@ #include "chrome/test/base/interactive_test_utils_aura.h" +#include "base/run_loop.h" #include "build/build_config.h" #include "chrome/test/base/interactive_test_utils.h" +#include "ui/aura/client/focus_change_observer.h" +#include "ui/aura/client/focus_client.h" #include "ui/aura/window.h" +namespace { + +class FocusWaiter : public aura::client::FocusChangeObserver { + public: + explicit FocusWaiter(aura::Window* window) : window_(window) { + aura::client::GetFocusClient(window_)->AddObserver(this); + } + + ~FocusWaiter() override { + aura::client::GetFocusClient(window_)->RemoveObserver(this); + } + + void WaitUntilFocus() { + if (window_->HasFocus()) + return; + run_loop_.Run(); + } + + private: + // aura::client::FocusChangeObserver: + void OnWindowFocused(aura::Window* gained_focus, + aura::Window* lost_focus) override { + if (gained_focus == window_) + run_loop_.QuitWhenIdle(); + } + + aura::Window* window_; + base::RunLoop run_loop_; + + DISALLOW_COPY_AND_ASSIGN(FocusWaiter); +}; + +} // namespace + namespace ui_test_utils { #if !defined(OS_WIN) @@ -30,4 +67,9 @@ return true; } +void WaitUntilWindowFocused(aura::Window* window) { + FocusWaiter waiter(window); + waiter.WaitUntilFocus(); +} + } // namespace ui_test_utils
diff --git a/chrome/test/base/interactive_test_utils_aura.h b/chrome/test/base/interactive_test_utils_aura.h index e157a56..75eae2f 100644 --- a/chrome/test/base/interactive_test_utils_aura.h +++ b/chrome/test/base/interactive_test_utils_aura.h
@@ -16,6 +16,9 @@ void HideNativeWindowAura(gfx::NativeWindow window); bool ShowAndFocusNativeWindowAura(gfx::NativeWindow window); +// Wait until |window| gets focused. +void WaitUntilWindowFocused(aura::Window* window); + } // namespace ui_test_utils #endif // CHROME_TEST_BASE_INTERACTIVE_TEST_UTILS_AURA_H_
diff --git a/chrome/test/base/interactive_test_utils_views.cc b/chrome/test/base/interactive_test_utils_views.cc index 46cbac5..19f773f3 100644 --- a/chrome/test/base/interactive_test_utils_views.cc +++ b/chrome/test/base/interactive_test_utils_views.cc
@@ -12,6 +12,45 @@ #include "ui/base/ui_features.h" #include "ui/views/focus/focus_manager.h" +#if defined(USE_AURA) +#include "chrome/test/base/interactive_test_utils_aura.h" +#endif + +namespace { + +class FocusWaiter : public views::FocusChangeListener { + public: + explicit FocusWaiter(views::View* view) : view_(view) { + view_->GetFocusManager()->AddFocusChangeListener(this); + } + ~FocusWaiter() override { + view_->GetFocusManager()->RemoveFocusChangeListener(this); + } + + void WaitUntilFocused() { + if (view_->HasFocus()) + return; + run_loop_.Run(); + } + + private: + // views::FocusChangeListener: + void OnWillChangeFocus(views::View* focused_before, + views::View* focused_now) override {} + void OnDidChangeFocus(views::View* focused_before, + views::View* focused_now) override { + if (focused_now == view_) + run_loop_.QuitWhenIdle(); + } + + views::View* view_; + base::RunLoop run_loop_; + + DISALLOW_COPY_AND_ASSIGN(FocusWaiter); +}; + +} // namespace + namespace ui_test_utils { bool IsViewFocused(const Browser* browser, ViewID vid) { @@ -50,4 +89,18 @@ return center; } +void WaitUntilViewFocused(const Browser* browser, ViewID vid) { +#if defined(USE_AURA) + BrowserWindow* browser_window = browser->window(); + DCHECK(browser_window); + gfx::NativeWindow window = browser_window->GetNativeWindow(); + DCHECK(window); + WaitUntilWindowFocused(window); +#endif + + FocusWaiter waiter( + BrowserView::GetBrowserViewForBrowser(browser)->GetViewByID(vid)); + waiter.WaitUntilFocused(); +} + } // namespace ui_test_utils
diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc index 4af45fe..7b9116b 100644 --- a/chrome/test/base/test_browser_window.cc +++ b/chrome/test/base/test_browser_window.cc
@@ -150,6 +150,11 @@ return content::KeyboardEventProcessingResult::NOT_HANDLED; } +bool TestBrowserWindow::HandleKeyboardEvent( + const content::NativeWebKeyboardEvent& event) { + return false; +} + bool TestBrowserWindow::IsBookmarkBarVisible() const { return false; }
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index 4d5e2b67..1584a2b 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h
@@ -99,8 +99,8 @@ void ShowAppMenu() override {} content::KeyboardEventProcessingResult PreHandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) override; - void HandleKeyboardEvent( - const content::NativeWebKeyboardEvent& event) override {} + bool HandleKeyboardEvent( + const content::NativeWebKeyboardEvent& event) override; bool IsBookmarkBarVisible() const override; bool IsBookmarkBarAnimating() const override; bool IsTabStripEditable() const override;
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index a84935c..cbf3749 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -237,6 +237,7 @@ 'LaunchDesktopTest.*', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2579 'ChromeDriverTest.testTakeElementScreenshot', + 'ChromeDriverTest.testTakeElementScreenshotInIframe', ] ) _ANDROID_NEGATIVE_FILTER['chrome_stable'] = ( @@ -248,6 +249,8 @@ 'ChromeDriverTest.testGetWindowHandles', 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly', 'ChromeDriverTest.testSwitchToWindow', + # Feature not yet supported in this version + 'ChromeDriverTest.testGenerateTestReport', ] ) _ANDROID_NEGATIVE_FILTER['chrome_beta'] = ( @@ -257,6 +260,8 @@ 'ChromeDriverTest.testGetWindowHandles', 'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly', 'ChromeDriverTest.testSwitchToWindow', + # Feature not yet supported in this version + 'ChromeDriverTest.testGenerateTestReport', ] ) _ANDROID_NEGATIVE_FILTER['chromium'] = (
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index a8382d28..fe8be1a9 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -176,6 +176,9 @@ # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2601 'BasicKeyboardInterfaceTest.testSelectionSelectBySymbol', + + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2611 + 'CorrectEventFiringTest.testClickAnElementThatDisappear', ] _OS_NEGATIVE_FILTER['android:chrome_stable'] = (
diff --git a/chrome/test/data/android/feed/background_styles.gcl.bin b/chrome/test/data/android/feed/background_styles.gcl.bin index ea02969..3ed6aae 100644 --- a/chrome/test/data/android/feed/background_styles.gcl.bin +++ b/chrome/test/data/android/feed/background_styles.gcl.bin Binary files differ
diff --git a/chrome/test/data/android/feed/feed_large.gcl.bin b/chrome/test/data/android/feed/feed_large.gcl.bin index 8e8462e..22c8360 100644 --- a/chrome/test/data/android/feed/feed_large.gcl.bin +++ b/chrome/test/data/android/feed/feed_large.gcl.bin Binary files differ
diff --git a/chrome/test/data/android/feed/feed_paging.gcl.bin b/chrome/test/data/android/feed/feed_paging.gcl.bin index 79212ba..cf78b1b0 100644 --- a/chrome/test/data/android/feed/feed_paging.gcl.bin +++ b/chrome/test/data/android/feed/feed_paging.gcl.bin Binary files differ
diff --git a/chrome/test/data/android/feed/feed_with_hero.gcl.bin b/chrome/test/data/android/feed/feed_with_hero.gcl.bin index 60ce43b..1a0e50ee 100644 --- a/chrome/test/data/android/feed/feed_with_hero.gcl.bin +++ b/chrome/test/data/android/feed/feed_with_hero.gcl.bin Binary files differ
diff --git a/chrome/test/data/android/feed/feed_with_overlay.gcl.bin b/chrome/test/data/android/feed/feed_with_overlay.gcl.bin index 62c7504..ded5371 100644 --- a/chrome/test/data/android/feed/feed_with_overlay.gcl.bin +++ b/chrome/test/data/android/feed/feed_with_overlay.gcl.bin Binary files differ
diff --git a/chrome/test/data/webui/print_preview/advanced_dialog_test.js b/chrome/test/data/webui/print_preview/advanced_dialog_test.js index ceb9c91..7db075e 100644 --- a/chrome/test/data/webui/print_preview/advanced_dialog_test.js +++ b/chrome/test/data/webui/print_preview/advanced_dialog_test.js
@@ -61,7 +61,7 @@ dialog.destination = destination; document.body.appendChild(dialog); - return test_util.eventToPromise('cr-dialog-open', dialog); + Polymer.dom.flush(); } /** @@ -99,93 +99,88 @@ // Tests that the search box does not appear when there is only one option, // and that the vendor item is correctly displayed. test(assert(TestNames.AdvancedSettings1Option), function() { - return setupDialog(1).then(() => verifyListWithItemCount(1)); + setupDialog(1); + verifyListWithItemCount(1); }); // Tests that the search box appears when there are two options, and that // the items are correctly displayed. test(assert(TestNames.AdvancedSettings2Options), function() { - return setupDialog(2).then(() => verifyListWithItemCount(2)); + setupDialog(2); + verifyListWithItemCount(2); }); // Tests that the advanced settings dialog correctly updates the settings // value for vendor items when the apply button is clicked. test(assert(TestNames.AdvancedSettingsApply), function() { - return setupDialog(3) - .then(() => { - setItemValues(); + setupDialog(3); + setItemValues(); - const buttons = dialog.shadowRoot.querySelectorAll('paper-button'); - assertEquals(2, buttons.length); - const whenDialogClose = test_util.eventToPromise('close', dialog); + const buttons = dialog.shadowRoot.querySelectorAll('paper-button'); + assertEquals(2, buttons.length); + const whenDialogClose = test_util.eventToPromise('close', dialog); - // Click apply button. - buttons[1].click(); - return whenDialogClose; - }) - .then(() => { - // Check that the setting has been set. - const setting = dialog.getSettingValue('vendorItems'); - assertEquals(6, setting.printArea); - assertEquals(1, setting.paperType); - assertEquals('XYZ', setting.watermark); - }); + // Click apply button. + buttons[1].click(); + return whenDialogClose.then(() => { + // Check that the setting has been set. + const setting = dialog.getSettingValue('vendorItems'); + assertEquals(6, setting.printArea); + assertEquals(1, setting.paperType); + assertEquals('XYZ', setting.watermark); + }); }); // Tests that the advanced settings dialog does not update the settings // value for vendor items when the close button is clicked. test(assert(TestNames.AdvancedSettingsClose), function() { - return setupDialog(3) - .then(() => { - setItemValues(); + setupDialog(3); + setItemValues(); - const buttons = dialog.shadowRoot.querySelectorAll('paper-button'); - assertEquals(2, buttons.length); - const whenDialogClose = test_util.eventToPromise('close', dialog); + const buttons = dialog.shadowRoot.querySelectorAll('paper-button'); + assertEquals(2, buttons.length); + const whenDialogClose = test_util.eventToPromise('close', dialog); - // Click close button. - buttons[0].click(); - return whenDialogClose; - }) - .then(() => { - // Check that the setting has not been set. - const setting = dialog.getSettingValue('vendorItems'); - assertEquals(undefined, setting.printArea); - assertEquals(undefined, setting.paperType); - assertEquals(undefined, setting.watermark); - }); + // Click close button. + buttons[0].click(); + return whenDialogClose.then(() => { + // Check that the setting has not been set. + const setting = dialog.getSettingValue('vendorItems'); + assertEquals(undefined, setting.printArea); + assertEquals(undefined, setting.paperType); + assertEquals(undefined, setting.watermark); + }); }); // Tests that the dialog correctly shows and hides settings based on the // value of the search query. test(assert(TestNames.AdvancedSettingsFilter), function() { - return setupDialog(3).then(() => { - const searchBox = dialog.$.searchBox; - const items = dialog.shadowRoot.querySelectorAll( - 'print-preview-advanced-settings-item'); - const noMatchHint = dialog.$$('.no-settings-match-hint'); + setupDialog(3); + const searchBox = dialog.$.searchBox; + const items = dialog.shadowRoot.querySelectorAll( + 'print-preview-advanced-settings-item'); + const noMatchHint = dialog.$$('.no-settings-match-hint'); - // Query is initialized to null. All items are shown and the hint is - // hidden. - items.forEach(item => assertFalse(item.hidden)); - assertTrue(noMatchHint.hidden); + // Query is initialized to null. All items are shown and the hint is + // hidden. + items.forEach(item => assertFalse(item.hidden)); + assertTrue(noMatchHint.hidden); - // Searching for Watermark should show only the watermark setting. - searchBox.searchQuery = /(Watermark)/i; - items.forEach((item, index) => assertEquals(index != 2, item.hidden)); - assertTrue(noMatchHint.hidden); + // Searching for Watermark should show only the watermark setting. + searchBox.searchQuery = /(Watermark)/i; + items.forEach((item, index) => assertEquals(index != 2, item.hidden)); + assertTrue(noMatchHint.hidden); - // Searching for A4 should show only the print area setting. - searchBox.searchQuery = /(A4)/i; - items.forEach((item, index) => assertEquals(index != 0, item.hidden)); - assertTrue(noMatchHint.hidden); + // Searching for A4 should show only the print area setting. + searchBox.searchQuery = /(A4)/i; + items.forEach((item, index) => assertEquals(index != 0, item.hidden)); + assertTrue(noMatchHint.hidden); - // Searching for WXYZ should show no settings and display the "no match" - // hint. - searchBox.searchQuery = /(WXYZ)/i; - items.forEach(item => assertTrue(item.hidden)); - assertFalse(noMatchHint.hidden); - }); + // Searching for WXYZ should show no settings and display the "no match" + // hint. + searchBox.searchQuery = /(WXYZ)/i; + items.forEach(item => assertTrue(item.hidden)); + assertFalse(noMatchHint.hidden); }); });
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn index d1cb014d..5557577 100644 --- a/chromecast/BUILD.gn +++ b/chromecast/BUILD.gn
@@ -22,12 +22,6 @@ cast_test_extra_flags = "" } -config("playready_config") { - if (use_playready) { - defines = [ "PLAYREADY_CDM_AVAILABLE" ] - } -} - # Depends on all non-test targets that should be built by the Chromecast # internal build infrastructure. group("all") { @@ -577,22 +571,23 @@ buildflag_header("chromecast_buildflags") { header = "chromecast_buildflags.h" flags = [ + "DEFAULT_COMMAND_LINE_FLAGS=\"$default_command_line_flags\"", + "DISABLE_SECURE_FLAC_OPUS_DECODING=$disable_secure_flac_and_opus_decoding", "ENABLE_ASSISTANT=$enable_assistant", + "ENABLE_CAST_FRAGMENT=$enable_cast_fragment", + "ENABLE_CHROMECAST_EXTENSIONS=$enable_chromecast_extensions", + "ENABLE_HEADLESS_MUSIC_MODE=$enable_headless_music_mode", + "ENABLE_PLAYREADY=$enable_playready", "ENABLE_VOLUME_TABLES_ACCESS=$enable_volume_tables_access", "IS_ANDROID_THINGS=$is_android_things", + "IS_ANDROID_THINGS_NON_PUBLIC=$is_android_things_non_public", "IS_CAST_AUDIO_ONLY=$is_cast_audio_only", "IS_CAST_DESKTOP_BUILD=$is_cast_desktop_build", "IS_CAST_USING_CMA_BACKEND=$is_cast_using_cma_backend", - "SUPPORTS_MULTIZONE=$supports_multizone", - "ENABLE_HEADLESS_MUSIC_MODE=$enable_headless_music_mode", - "ENABLE_CHROMECAST_EXTENSIONS=$enable_chromecast_extensions", - "ENABLE_CAST_FRAGMENT=$enable_cast_fragment", - "IS_ANDROID_THINGS_NON_PUBLIC=$is_android_things_non_public", "IS_SINGLE_VOLUME=$is_single_volume", + "SUPPORTS_MULTIZONE=$supports_multizone", "USE_ANDROID_USER_AGENT=$use_android_user_agent", "USE_CHROMECAST_CDMS=$use_chromecast_cdms", - "DEFAULT_COMMAND_LINE_FLAGS=\"$default_command_line_flags\"", - "DISABLE_SECURE_FLAC_OPUS_DECODING=$disable_secure_flac_and_opus_decoding", ] }
diff --git a/chromecast/chromecast.gni b/chromecast/chromecast.gni index fef8c70..76fa24b0 100644 --- a/chromecast/chromecast.gni +++ b/chromecast/chromecast.gni
@@ -109,7 +109,7 @@ declare_args() { # Use Playready CDMs for internal non-desktop builds. - use_playready = !is_cast_desktop_build && chromecast_branding != "public" + enable_playready = !is_cast_desktop_build && chromecast_branding != "public" } # This is the release version, which takes the form <major>.<minor>. Internal
diff --git a/chromecast/common/media/BUILD.gn b/chromecast/common/media/BUILD.gn index 2b42534..30a78086 100644 --- a/chromecast/common/media/BUILD.gn +++ b/chromecast/common/media/BUILD.gn
@@ -13,14 +13,11 @@ ] deps = [ "//base", + "//chromecast:chromecast_buildflags", "//chromecast/media", "//chromecast/media/cdm", "//components/cdm/common", "//media", ] } - - if (use_playready) { - public_configs = [ "//chromecast:playready_config" ] - } }
diff --git a/chromecast/common/media/cast_media_drm_bridge_client.cc b/chromecast/common/media/cast_media_drm_bridge_client.cc index 334a677..b9b8969a 100644 --- a/chromecast/common/media/cast_media_drm_bridge_client.cc +++ b/chromecast/common/media/cast_media_drm_bridge_client.cc
@@ -15,18 +15,18 @@ void CastMediaDrmBridgeClient::AddKeySystemUUIDMappings(KeySystemUuidMap* map) { // Note: MediaDrmBridge adds the Widevine UUID mapping automatically. -#if defined(PLAYREADY_CDM_AVAILABLE) +#if BUILDFLAG(ENABLE_PLAYREADY) (*map)[kChromecastPlayreadyKeySystem] = playready_delegate_.GetUUID(); -#endif +#endif // BUILDFLAG(ENABLE_PLAYREADY) } ::media::MediaDrmBridgeDelegate* CastMediaDrmBridgeClient::GetMediaDrmBridgeDelegate( const ::media::UUID& scheme_uuid) { -#if defined(PLAYREADY_CDM_AVAILABLE) +#if BUILDFLAG(ENABLE_PLAYREADY) if (scheme_uuid == playready_delegate_.GetUUID()) return &playready_delegate_; -#endif +#endif // BUILDFLAG(ENABLE_PLAYREADY) if (scheme_uuid == widevine_delegate_.GetUUID()) return &widevine_delegate_;
diff --git a/chromecast/common/media/cast_media_drm_bridge_client.h b/chromecast/common/media/cast_media_drm_bridge_client.h index 69b381d..86c7d80 100644 --- a/chromecast/common/media/cast_media_drm_bridge_client.h +++ b/chromecast/common/media/cast_media_drm_bridge_client.h
@@ -8,6 +8,7 @@ #include <map> #include "base/macros.h" +#include "chromecast/chromecast_buildflags.h" #include "chromecast/media/cdm/playready_drm_delegate_android.h" #include "components/cdm/common/widevine_drm_delegate_android.h" #include "media/base/android/media_drm_bridge_client.h" @@ -26,9 +27,9 @@ ::media::MediaDrmBridgeDelegate* GetMediaDrmBridgeDelegate( const ::media::UUID& scheme_uuid) override; -#if defined(PLAYREADY_CDM_AVAILABLE) +#if BUILDFLAG(ENABLE_PLAYREADY) PlayreadyDrmDelegateAndroid playready_delegate_; -#endif +#endif // BUILDFLAG(ENABLE_PLAYREADY) cdm::WidevineDrmDelegateAndroid widevine_delegate_;
diff --git a/chromecast/media/base/BUILD.gn b/chromecast/media/base/BUILD.gn index 450a06d2..1acff20 100644 --- a/chromecast/media/base/BUILD.gn +++ b/chromecast/media/base/BUILD.gn
@@ -11,12 +11,9 @@ "key_systems_common.h", ] - if (use_playready) { - public_configs = [ "//chromecast:playready_config" ] - } - deps = [ "//base", + "//chromecast:chromecast_buildflags", "//chromecast/public/media", "//media", "//third_party/widevine/cdm:buildflags",
diff --git a/chromecast/media/base/key_systems_common.cc b/chromecast/media/base/key_systems_common.cc index 26e3414..3854184c 100644 --- a/chromecast/media/base/key_systems_common.cc +++ b/chromecast/media/base/key_systems_common.cc
@@ -16,9 +16,9 @@ namespace chromecast { namespace media { -#if defined(PLAYREADY_CDM_AVAILABLE) +#if BUILDFLAG(ENABLE_PLAYREADY) const char kChromecastPlayreadyKeySystem[] = "com.chromecast.playready"; -#endif // defined(PLAYREADY_CDM_AVAILABLE) +#endif // BUILDFLAG(ENABLE_PLAYREADY) CastKeySystem GetKeySystemByName(const std::string& key_system_name) { #if BUILDFLAG(ENABLE_WIDEVINE) @@ -27,11 +27,11 @@ } #endif // BUILDFLAG(ENABLE_WIDEVINE) -#if defined(PLAYREADY_CDM_AVAILABLE) +#if BUILDFLAG(ENABLE_PLAYREADY) if (key_system_name.compare(kChromecastPlayreadyKeySystem) == 0) { return KEY_SYSTEM_PLAYREADY; } -#endif // defined(PLAYREADY_CDM_AVAILABLE) +#endif // BUILDFLAG(ENABLE_PLAYREADY) if (::media::IsClearKey(key_system_name)) { return KEY_SYSTEM_CLEAR_KEY;
diff --git a/chromecast/media/base/key_systems_common.h b/chromecast/media/base/key_systems_common.h index 7e9c992..75baa1ad4 100644 --- a/chromecast/media/base/key_systems_common.h +++ b/chromecast/media/base/key_systems_common.h
@@ -7,14 +7,15 @@ #include <string> +#include "chromecast/chromecast_buildflags.h" #include "chromecast/public/media/cast_key_system.h" namespace chromecast { namespace media { -#if defined(PLAYREADY_CDM_AVAILABLE) +#if BUILDFLAG(ENABLE_PLAYREADY) extern const char kChromecastPlayreadyKeySystem[]; -#endif // defined(PLAYREADY_CDM_AVAILABLE) +#endif // BUILDFLAG(ENABLE_PLAYREADY) // Translates a key system string into a CastKeySystem, calling into the // platform for known key systems if needed.
diff --git a/chromecast/media/cdm/BUILD.gn b/chromecast/media/cdm/BUILD.gn index 5e524e9..543fd6d 100644 --- a/chromecast/media/cdm/BUILD.gn +++ b/chromecast/media/cdm/BUILD.gn
@@ -34,7 +34,7 @@ ] } - if (is_android && use_playready) { + if (is_android && enable_playready) { sources += [ "playready_drm_delegate_android.cc", "playready_drm_delegate_android.h",
diff --git a/chromecast/media/cma/pipeline/av_pipeline_impl.cc b/chromecast/media/cma/pipeline/av_pipeline_impl.cc index e104ca8..f5cf915 100644 --- a/chromecast/media/cma/pipeline/av_pipeline_impl.cc +++ b/chromecast/media/cma/pipeline/av_pipeline_impl.cc
@@ -19,6 +19,7 @@ #include "chromecast/media/cma/base/cma_logging.h" #include "chromecast/media/cma/base/coded_frame_provider.h" #include "chromecast/media/cma/base/decoder_buffer_base.h" +#include "chromecast/media/cma/pipeline/cdm_decryptor.h" #include "chromecast/media/cma/pipeline/decrypt_util.h" #include "chromecast/public/media/cast_decrypt_config.h" #include "media/base/audio_decoder_config.h" @@ -202,13 +203,6 @@ if (audio_config.IsValidConfig() || video_config.IsValidConfig()) OnUpdateConfig(buffer->stream_id(), audio_config, video_config); - if (!decryptor_) { - decryptor_ = CreateDecryptor(); - DCHECK(decryptor_); - decryptor_->Init(base::BindRepeating(&AvPipelineImpl::OnBufferDecrypted, - decrypt_weak_factory_.GetWeakPtr())); - } - pending_buffer_ = buffer; ProcessPendingBuffer(); } @@ -249,10 +243,24 @@ } DCHECK_NE(decrypt_context->GetKeySystem(), KEY_SYSTEM_NONE); + + if (!decryptor_) { + decryptor_ = CreateStreamDecryptor(decrypt_context->GetKeySystem()); + DCHECK(decryptor_); + decryptor_->Init(base::BindRepeating(&AvPipelineImpl::OnBufferDecrypted, + decrypt_weak_factory_.GetWeakPtr())); + } + pending_buffer_->set_decrypt_context(std::move(decrypt_context)); } - decryptor_->Decrypt(std::move(pending_buffer_)); + if (decryptor_) { + decryptor_->Decrypt(std::move(pending_buffer_)); + return; + } + + DCHECK(ready_buffers_.empty()); + PushReadyBuffer(std::move(pending_buffer_)); } void AvPipelineImpl::PushAllReadyBuffers() { @@ -431,5 +439,15 @@ } } +std::unique_ptr<StreamDecryptor> AvPipelineImpl::CreateStreamDecryptor( + CastKeySystem key_system) { + if (key_system == KEY_SYSTEM_CLEAR_KEY) { + // Clear Key only supports clear output. + return std::make_unique<CdmDecryptor>(true /* clear_buffer_needed */); + } + + return CreateDecryptor(); +} + } // namespace media } // namespace chromecast
diff --git a/chromecast/media/cma/pipeline/av_pipeline_impl.h b/chromecast/media/cma/pipeline/av_pipeline_impl.h index e5635b1..3d8e3c1d 100644 --- a/chromecast/media/cma/pipeline/av_pipeline_impl.h +++ b/chromecast/media/cma/pipeline/av_pipeline_impl.h
@@ -132,6 +132,9 @@ bool is_at_max_capacity); void UpdatePlayableFrames(); + std::unique_ptr<StreamDecryptor> CreateStreamDecryptor( + CastKeySystem key_system); + base::ThreadChecker thread_checker_; CmaBackend::Decoder* const decoder_;
diff --git a/chromecast/renderer/BUILD.gn b/chromecast/renderer/BUILD.gn index cd88cec..e0a433ea 100644 --- a/chromecast/renderer/BUILD.gn +++ b/chromecast/renderer/BUILD.gn
@@ -40,10 +40,6 @@ sources += [ "cast_content_renderer_client_simple.cc" ] } - if (use_playready) { - configs += [ "//chromecast:playready_config" ] - } - deps = [ "//base", "//chromecast:chromecast_buildflags",
diff --git a/chromecast/renderer/media/key_systems_cast.cc b/chromecast/renderer/media/key_systems_cast.cc index 0f1d2e1f..b38e089 100644 --- a/chromecast/renderer/media/key_systems_cast.cc +++ b/chromecast/renderer/media/key_systems_cast.cc
@@ -32,7 +32,7 @@ namespace media { namespace { -#if defined(PLAYREADY_CDM_AVAILABLE) +#if BUILDFLAG(ENABLE_PLAYREADY) class PlayReadyKeySystemProperties : public ::media::KeySystemProperties { public: PlayReadyKeySystemProperties(SupportedCodecs supported_non_secure_codecs, @@ -108,7 +108,7 @@ #endif // defined(OS_ANDROID) const bool persistent_license_support_; }; -#endif // PLAYREADY_CDM_AVAILABLE +#endif // BUILDFLAG(ENABLE_PLAYREADY) #if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) SupportedCodecs GetCastEmeSupportedCodecs() { @@ -152,10 +152,10 @@ // |codecs| may not be used if Widevine and Playready aren't supported. ANALYZER_ALLOW_UNUSED(codecs); -#if defined(PLAYREADY_CDM_AVAILABLE) +#if BUILDFLAG(ENABLE_PLAYREADY) key_systems_properties->emplace_back(new PlayReadyKeySystemProperties( codecs, codecs, enable_persistent_license_support)); -#endif // defined(PLAYREADY_CDM_AVAILABLE) +#endif // BUILDFLAG(ENABLE_PLAYREADY) #if BUILDFLAG(ENABLE_WIDEVINE) using Robustness = cdm::WidevineKeySystemProperties::Robustness; @@ -178,7 +178,7 @@ #endif // BUILDFLAG(ENABLE_WIDEVINE) } #elif defined(OS_ANDROID) -#if defined(PLAYREADY_CDM_AVAILABLE) +#if BUILDFLAG(ENABLE_PLAYREADY) void AddCastPlayreadyKeySystemAndroid( std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems_properties) { @@ -193,14 +193,14 @@ response.non_secure_codecs, response.secure_codecs, false /* persistent_license_support */)); } -#endif // defined(PLAYREADY_CDM_AVAILABLE) +#endif // BUILDFLAG(ENABLE_PLAYREADY) void AddCastAndroidKeySystems( std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems_properties) { -#if defined(PLAYREADY_CDM_AVAILABLE) +#if BUILDFLAG(ENABLE_PLAYREADY) AddCastPlayreadyKeySystemAndroid(key_systems_properties); -#endif // defined(PLAYREADY_CDM_AVAILABLE) +#endif // BUILDFLAG(ENABLE_PLAYREADY) #if BUILDFLAG(ENABLE_WIDEVINE) cdm::AddAndroidWidevine(key_systems_properties);
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index cf300519..2602fac1 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -549,6 +549,9 @@ // This makes it easier to test layout logic. const char kShowLoginDevOverlay[] = "show-login-dev-overlay"; +// Show Play Store in Demo Mode. +const char kShowPlayInDemoMode[] = "show-play-in-demo-mode"; + // Indicates that a stub implementation of CrosSettings that stores settings in // memory without signing should be used, treating current user as the owner. // This also modifies OwnerSettingsServiceChromeOS::HandlesSetting such that no @@ -713,5 +716,9 @@ kInstantTetheringBackgroundAdvertisementSupport); } +bool ShouldShowPlayStoreInDemoMode() { + return base::CommandLine::ForCurrentProcess()->HasSwitch(kShowPlayInDemoMode); +} + } // namespace switches } // namespace chromeos
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index 61755eb9..72d39c20 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -153,6 +153,7 @@ CHROMEOS_EXPORT extern const char kShowAndroidFilesInFilesApp[]; CHROMEOS_EXPORT extern const char kFilesAppDisableMyFilesNavigation[]; CHROMEOS_EXPORT extern const char kShowLoginDevOverlay[]; +CHROMEOS_EXPORT extern const char kShowPlayInDemoMode[]; CHROMEOS_EXPORT extern const char kStubCrosSettings[]; CHROMEOS_EXPORT extern const char kTestEncryptionMigrationUI[]; CHROMEOS_EXPORT extern const char kTetherStub[]; @@ -223,6 +224,10 @@ // background advertisement model CHROMEOS_EXPORT bool IsInstantTetheringBackgroundAdvertisingSupported(); +// Returns true if Play Store should be available in Demo Mode. +// TODO(michaelpg): Remove after M71 branch to re-enable Play Store by default. +CHROMEOS_EXPORT bool ShouldShowPlayStoreInDemoMode(); + } // namespace switches } // namespace chromeos
diff --git a/chromeos/components/tether/tether_host_fetcher_impl.cc b/chromeos/components/tether/tether_host_fetcher_impl.cc index de504841..6b24aa41 100644 --- a/chromeos/components/tether/tether_host_fetcher_impl.cc +++ b/chromeos/components/tether/tether_host_fetcher_impl.cc
@@ -15,39 +15,6 @@ namespace tether { -namespace { - -enum class TetherHostSource { - UNKNOWN, - MULTIDEVICE_SETUP_CLIENT, - DEVICE_SYNC_CLIENT, - REMOTE_DEVICE_PROVIDER -}; - -TetherHostSource GetTetherHostSourceBasedOnFlags() { - if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) && - base::FeatureList::IsEnabled( - chromeos::features::kEnableUnifiedMultiDeviceSetup)) { - return TetherHostSource::MULTIDEVICE_SETUP_CLIENT; - } - if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) && - !base::FeatureList::IsEnabled( - chromeos::features::kEnableUnifiedMultiDeviceSetup)) { - return TetherHostSource::DEVICE_SYNC_CLIENT; - } - if (!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) && - !base::FeatureList::IsEnabled( - chromeos::features::kEnableUnifiedMultiDeviceSetup)) { - return TetherHostSource::REMOTE_DEVICE_PROVIDER; - } - NOTREACHED() << "TetherHostFetcherImpl: Unexpected feature flag state of " - << "kMultiDeviceApi disabled and kEnableUnifiedMultiDeviceSetup " - << "enabled."; - return TetherHostSource::UNKNOWN; -} - -} // namespace - // static TetherHostFetcherImpl::Factory* TetherHostFetcherImpl::Factory::factory_instance_ = nullptr; @@ -89,35 +56,36 @@ device_sync_client_(device_sync_client), multidevice_setup_client_(multidevice_setup_client), weak_ptr_factory_(this) { - switch (GetTetherHostSourceBasedOnFlags()) { - case TetherHostSource::MULTIDEVICE_SETUP_CLIENT: - multidevice_setup_client_->AddObserver(this); - break; - case TetherHostSource::DEVICE_SYNC_CLIENT: - device_sync_client_->AddObserver(this); - break; - case TetherHostSource::REMOTE_DEVICE_PROVIDER: - remote_device_provider_->AddObserver(this); - break; - case TetherHostSource::UNKNOWN: - break; + if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) + device_sync_client_->AddObserver(this); + + if (base::FeatureList::IsEnabled( + chromeos::features::kEnableUnifiedMultiDeviceSetup)) { + multidevice_setup_client_->AddObserver(this); } + + if (!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) && + !base::FeatureList::IsEnabled( + chromeos::features::kEnableUnifiedMultiDeviceSetup)) { + remote_device_provider_->AddObserver(this); + } + CacheCurrentTetherHosts(); } TetherHostFetcherImpl::~TetherHostFetcherImpl() { - switch (GetTetherHostSourceBasedOnFlags()) { - case TetherHostSource::MULTIDEVICE_SETUP_CLIENT: - multidevice_setup_client_->RemoveObserver(this); - break; - case TetherHostSource::DEVICE_SYNC_CLIENT: - device_sync_client_->RemoveObserver(this); - break; - case TetherHostSource::REMOTE_DEVICE_PROVIDER: - remote_device_provider_->RemoveObserver(this); - break; - case TetherHostSource::UNKNOWN: - break; + if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) + device_sync_client_->RemoveObserver(this); + + if (base::FeatureList::IsEnabled( + chromeos::features::kEnableUnifiedMultiDeviceSetup)) { + multidevice_setup_client_->RemoveObserver(this); + } + + if (!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) && + !base::FeatureList::IsEnabled( + chromeos::features::kEnableUnifiedMultiDeviceSetup)) { + remote_device_provider_->RemoveObserver(this); } } @@ -157,6 +125,10 @@ CacheCurrentTetherHosts(); } +void TetherHostFetcherImpl::OnReady() { + CacheCurrentTetherHosts(); +} + void TetherHostFetcherImpl::CacheCurrentTetherHosts() { cryptauth::RemoteDeviceRefList updated_list = GenerateHostDeviceList(); if (updated_list == current_remote_device_list_) @@ -218,6 +190,63 @@ return host_list; } +bool TetherHostFetcherImpl::IsInLegacyHostMode() { + if (!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) || + !device_sync_client_->is_ready()) { + return false; + } + + bool has_supported_tether_host = false; + for (const cryptauth::RemoteDeviceRef& remote_device_ref : + device_sync_client_->GetSyncedDevices()) { + cryptauth::SoftwareFeatureState better_together_host_state = + remote_device_ref.GetSoftwareFeatureState( + cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST); + // If there's any valid Better Together host, don't support legacy mode. + if (better_together_host_state == + cryptauth::SoftwareFeatureState::kSupported || + better_together_host_state == + cryptauth::SoftwareFeatureState::kEnabled) { + return false; + } + + cryptauth::SoftwareFeatureState magic_tether_host_state = + remote_device_ref.GetSoftwareFeatureState( + cryptauth::SoftwareFeature::MAGIC_TETHER_HOST); + if (magic_tether_host_state == + cryptauth::SoftwareFeatureState::kSupported || + magic_tether_host_state == cryptauth::SoftwareFeatureState::kEnabled) { + has_supported_tether_host = true; + } + } + + return has_supported_tether_host; +} + +TetherHostFetcherImpl::TetherHostSource +TetherHostFetcherImpl::GetTetherHostSourceBasedOnFlags() { + if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) && + !base::FeatureList::IsEnabled( + chromeos::features::kEnableUnifiedMultiDeviceSetup)) { + return TetherHostSource::DEVICE_SYNC_CLIENT; + } + if (!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) && + !base::FeatureList::IsEnabled( + chromeos::features::kEnableUnifiedMultiDeviceSetup)) { + return TetherHostSource::REMOTE_DEVICE_PROVIDER; + } + if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) && + base::FeatureList::IsEnabled( + chromeos::features::kEnableUnifiedMultiDeviceSetup)) { + return IsInLegacyHostMode() ? TetherHostSource::DEVICE_SYNC_CLIENT + : TetherHostSource::MULTIDEVICE_SETUP_CLIENT; + } + NOTREACHED() << "TetherHostFetcherImpl: Unexpected feature flag state of " + << "kMultiDeviceApi disabled and kEnableUnifiedMultiDeviceSetup " + << "enabled."; + return TetherHostSource::UNKNOWN; +} + } // namespace tether } // namespace chromeos
diff --git a/chromeos/components/tether/tether_host_fetcher_impl.h b/chromeos/components/tether/tether_host_fetcher_impl.h index e8d9049..b1b07e3 100644 --- a/chromeos/components/tether/tether_host_fetcher_impl.h +++ b/chromeos/components/tether/tether_host_fetcher_impl.h
@@ -30,12 +30,11 @@ // Note: TetherHostFetcherImpl, and the Tether feature as a whole, is currently // in the middle of a migration from using RemoteDeviceProvider to // DeviceSyncClient and eventually to MultiDeviceSetupClient. Its constructor -// accepts all three objects, but expects only of one of them to be valid, and -// the others null. (This is controlled at a higher level by -// features::kMultiDeviceApi and features::kEnableUnifiedMultiDeviceSetup.). -// Once Tether has been fully migrated, RemoteDeviceProvider and eventually -// DeviceSyncClient will be ripped out of this class. See -// https://crbug.com/848956. +// accepts all three objects, but some may be null. (This is controlled at a +// higher level by features::kMultiDeviceApi and +// features::kEnableUnifiedMultiDeviceSetup.). Once Tether has been fully +// migrated, RemoteDeviceProvider and eventually DeviceSyncClient will be ripped +// out of this class. See https://crbug.com/848956. class TetherHostFetcherImpl : public TetherHostFetcher, public cryptauth::RemoteDeviceProvider::Observer, @@ -76,6 +75,7 @@ // device_sync::DeviceSyncClient::Observer: void OnNewDevicesSynced() override; + void OnReady() override; // multidevice_setup::MultiDeviceSetupClient::Observer: void OnHostStatusChanged( @@ -94,8 +94,22 @@ multidevice_setup_client_); private: + enum class TetherHostSource { + UNKNOWN, + MULTIDEVICE_SETUP_CLIENT, + DEVICE_SYNC_CLIENT, + REMOTE_DEVICE_PROVIDER + }; + void CacheCurrentTetherHosts(); cryptauth::RemoteDeviceRefList GenerateHostDeviceList(); + TetherHostSource GetTetherHostSourceBasedOnFlags(); + // This returns true if there is no BETTER_TOGETHER_HOST supported or enabled, + // but there *are* MAGIC_TETHER_HOSTs supported or enabled. This can only + // happen if the user's phone has not yet fully updated to the new multidevice + // world. + // TODO(crbug.com/894585): Remove this legacy special case after M71. + bool IsInLegacyHostMode(); cryptauth::RemoteDeviceProvider* remote_device_provider_; device_sync::DeviceSyncClient* device_sync_client_;
diff --git a/chromeos/components/tether/tether_host_fetcher_impl_unittest.cc b/chromeos/components/tether/tether_host_fetcher_impl_unittest.cc index ccbd10c..f0d1c64a 100644 --- a/chromeos/components/tether/tether_host_fetcher_impl_unittest.cc +++ b/chromeos/components/tether/tether_host_fetcher_impl_unittest.cc
@@ -122,13 +122,15 @@ tether_host_source == TetherHostSource::REMOTE_DEVICE_PROVIDER ? fake_remote_device_provider_.get() : nullptr, - tether_host_source == TetherHostSource::DEVICE_SYNC_CLIENT + tether_host_source == TetherHostSource::DEVICE_SYNC_CLIENT || + tether_host_source == TetherHostSource::MULTIDEVICE_SETUP_CLIENT ? fake_device_sync_client_.get() : nullptr, tether_host_source == TetherHostSource::MULTIDEVICE_SETUP_CLIENT ? fake_multidevice_setup_client_.get() : nullptr); + fake_device_sync_client_->NotifyReady(); test_observer_ = std::make_unique<TestObserver>(); tether_host_fetcher_->AddObserver(test_observer_.get()); } @@ -175,6 +177,9 @@ // Mark the first device enabled instead of supported. list[0].software_features[cryptauth::SoftwareFeature::MAGIC_TETHER_HOST] = cryptauth::SoftwareFeatureState::kEnabled; + list[0] + .software_features[cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST] = + cryptauth::SoftwareFeatureState::kEnabled; return list; } @@ -259,8 +264,17 @@ EXPECT_EQ(2u, test_observer_->num_updates()); } - void TestSingleTetherHost() { + void TestSingleTetherHost(bool use_legacy_mode = false) { InitializeTest(); + if (use_legacy_mode) { + test_remote_device_list_[0] + .software_features[cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST] = + cryptauth::SoftwareFeatureState::kNotSupported; + test_remote_device_ref_list_ = + CreateTestRemoteDeviceRefList(test_remote_device_list_); + SetSyncedDevices(test_remote_device_list_); + NotifyNewDevicesSynced(); + } VerifySingleTetherHost(test_remote_device_ref_list_[0].GetDeviceId(), test_remote_device_ref_list_[0]); @@ -291,7 +305,7 @@ base::nullopt); } - void TestFetchAllTetherHosts() { + void TestFetchAllTetherHosts(bool use_legacy_mode = false) { InitializeTest(); // Create a list of test devices, only some of which are valid tether hosts. @@ -302,6 +316,11 @@ test_remote_device_list_[4] .software_features[cryptauth::SoftwareFeature::MAGIC_TETHER_HOST] = cryptauth::SoftwareFeatureState::kNotSupported; + if (use_legacy_mode) { + test_remote_device_list_[0] + .software_features[cryptauth::SoftwareFeature::BETTER_TOGETHER_HOST] = + cryptauth::SoftwareFeatureState::kNotSupported; + } SetSyncedDevices(test_remote_device_list_); NotifyNewDevicesSynced(); @@ -309,9 +328,12 @@ cryptauth::RemoteDeviceRefList expected_host_device_list; switch (GetTetherHostSourceBasedOnFlags()) { case TetherHostSource::MULTIDEVICE_SETUP_CLIENT: - expected_host_device_list = - CreateTestRemoteDeviceRefList({test_remote_device_list_[0]}); - break; + if (!use_legacy_mode) { + expected_host_device_list = + CreateTestRemoteDeviceRefList({test_remote_device_list_[0]}); + break; + } + FALLTHROUGH; case TetherHostSource::DEVICE_SYNC_CLIENT: case TetherHostSource::REMOTE_DEVICE_PROVIDER: expected_host_device_list = CreateTestRemoteDeviceRefList( @@ -374,6 +396,11 @@ SetOnlyMultiDeviceApiFeatureEnabled(); TestFetchAllTetherHosts(); } +TEST_F(TetherHostFetcherImplTest, + TestFetchAllTetherHosts_MultideviceApiAndSetupEnabledInLegacyMode) { + SetMultiDeviceApiAndSetupFeaturesEnabled(); + TestFetchAllTetherHosts(true /* use_legacy_mode */); +} // TestSingleTetherHost TEST_F(TetherHostFetcherImplTest, TestSingleTetherHost) { @@ -389,6 +416,11 @@ SetOnlyMultiDeviceApiFeatureEnabled(); TestSingleTetherHost(); } +TEST_F(TetherHostFetcherImplTest, + TestSingleTetherHost_MultideviceApiAndSetupEnabledInLegacyMode) { + SetMultiDeviceApiAndSetupFeaturesEnabled(); + TestSingleTetherHost(true /* use_legacy_mode */); +} // TestSingleTetherHost_IdDoesNotCorrespondToDevice TEST_F(TetherHostFetcherImplTest,
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index 468b9c97..edf9a53e 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -385,14 +385,15 @@ main_thread_task_runner_->PostTask( FROM_HERE, base::BindOnce(&AssistantManagerServiceImpl::OnShowHtmlOnMainThread, - weak_factory_.GetWeakPtr(), html.str())); + weak_factory_.GetWeakPtr(), html.str(), /*fallback=*/"")); } -void AssistantManagerServiceImpl::OnShowHtml(const std::string& html) { +void AssistantManagerServiceImpl::OnShowHtml(const std::string& html, + const std::string& fallback) { main_thread_task_runner_->PostTask( FROM_HERE, base::BindOnce(&AssistantManagerServiceImpl::OnShowHtmlOnMainThread, - weak_factory_.GetWeakPtr(), html)); + weak_factory_.GetWeakPtr(), html, fallback)); } void AssistantManagerServiceImpl::OnShowSuggestions( @@ -440,6 +441,10 @@ notification_ptr->opaque_token = notification.opaque_token; notification_ptr->grouping_key = notification.grouping_key; notification_ptr->obfuscated_gaia_id = notification.obfuscated_gaia_id; + for (const auto& button : notification.buttons) { + notification_ptr->buttons.push_back(mojom::AssistantNotificationButton::New( + button.label, GURL(button.action_url))); + } main_thread_task_runner_->PostTask( FROM_HERE, @@ -898,9 +903,10 @@ } void AssistantManagerServiceImpl::OnShowHtmlOnMainThread( - const std::string& html) { + const std::string& html, + const std::string& fallback) { interaction_subscribers_.ForAllPtrs( - [&html](auto* ptr) { ptr->OnHtmlResponse(html); }); + [&html, &fallback](auto* ptr) { ptr->OnHtmlResponse(html, fallback); }); } void AssistantManagerServiceImpl::OnShowSuggestionsOnMainThread(
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.h b/chromeos/services/assistant/assistant_manager_service_impl.h index 0f1b391..0c0572ad 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.h +++ b/chromeos/services/assistant/assistant_manager_service_impl.h
@@ -102,7 +102,8 @@ // AssistantActionObserver overrides: void OnShowContextualQueryFallback() override; - void OnShowHtml(const std::string& html) override; + void OnShowHtml(const std::string& html, + const std::string& fallback) override; void OnShowSuggestions( const std::vector<action::Suggestion>& suggestions) override; void OnShowText(const std::string& text) override; @@ -164,7 +165,8 @@ void OnConversationTurnStartedOnMainThread(bool is_mic_open); void OnConversationTurnFinishedOnMainThread( assistant_client::ConversationStateListener::Resolution resolution); - void OnShowHtmlOnMainThread(const std::string& html); + void OnShowHtmlOnMainThread(const std::string& html, + const std::string& fallback); void OnShowSuggestionsOnMainThread( const std::vector<mojom::AssistantSuggestionPtr>& suggestions); void OnShowTextOnMainThread(const std::string& text);
diff --git a/chromeos/services/assistant/public/mojom/assistant.mojom b/chromeos/services/assistant/public/mojom/assistant.mojom index 6428e55..321e6e8 100644 --- a/chromeos/services/assistant/public/mojom/assistant.mojom +++ b/chromeos/services/assistant/public/mojom/assistant.mojom
@@ -45,9 +45,12 @@ AssistantNotificationSubscriber subscriber); // Retrieves a notification. A voiceless interaction will be sent to server to - // retrieve the notification payload, which can trigger other assistant's - // events such as OnTextResponse to show the result in the UI. The reteived - // notification will be removed from the UI. + // retrieve the notification of |action_index|, which can trigger other + // Assistant events such as OnTextResponse to show the result in the UI. The + // retrieved notification will be removed from the UI. + // |action_index| is the index of the tapped action. The main UI in the + // notification contains the top level action, which index is 0. The buttons + // have the additional actions, which are indexed starting from 1. RetrieveNotification(AssistantNotification notification, int32 action_index); // Dismisses a notification. @@ -76,8 +79,8 @@ // Assistant interaction has ended with the specified |resolution|. OnInteractionFinished(AssistantInteractionResolution resolution); - // Assistant got Html response from server. - OnHtmlResponse(string response); + // Assistant got Html response with fallback text from server. + OnHtmlResponse(string response, string fallback); // Assistant got suggestions response from server. OnSuggestionsResponse(array<AssistantSuggestion> response); @@ -184,6 +187,15 @@ url.mojom.Url action_url; }; +// Models a notification button. +struct AssistantNotificationButton { + // Display text of the button. + string label; + + // Optional URL to open when the tap action is invoked on the button. + url.mojom.Url action_url; +}; + // Models an Assistant notification. struct AssistantNotification { // Title of the notification. @@ -192,9 +204,13 @@ // Body text of the notification. string message; - // URL to open when the tap action is invoked on the notification. + // Optional URL to open when the tap action is invoked on the notification + // main UI. url.mojom.Url action_url; + // List of buttons in the notification. + array<AssistantNotificationButton> buttons; + // An id that uniquely identifies a notification. string notification_id;
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn index 49f65b3..9f292e6 100644 --- a/components/autofill_assistant/browser/BUILD.gn +++ b/components/autofill_assistant/browser/BUILD.gn
@@ -34,8 +34,6 @@ "actions/select_option_action.h", "actions/show_details_action.cc", "actions/show_details_action.h", - "actions/show_progress_bar_action.cc", - "actions/show_progress_bar_action.h", "actions/stop_action.cc", "actions/stop_action.h", "actions/tell_action.cc",
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h index 549a5ae..eaacb76 100644 --- a/components/autofill_assistant/browser/actions/action_delegate.h +++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -143,12 +143,6 @@ // Show contextual information. virtual void ShowDetails(const DetailsProto& details) = 0; - // Show the progress bar with |message| and set it at |progress|%. - virtual void ShowProgressBar(int progress, const std::string& message) = 0; - - // Hide the progress bar. - virtual void HideProgressBar(); - protected: ActionDelegate() = default; };
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h index 2d5dc6d..6a6f8559 100644 --- a/components/autofill_assistant/browser/actions/mock_action_delegate.h +++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -116,8 +116,6 @@ MOCK_METHOD1(StopCurrentScript, void(const std::string& message)); MOCK_METHOD0(HideDetails, void()); MOCK_METHOD1(ShowDetails, void(const DetailsProto& details)); - MOCK_METHOD2(ShowProgressBar, void(int progress, const std::string& message)); - MOCK_METHOD0(HideProgressBar, void()); }; } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/show_progress_bar_action.cc b/components/autofill_assistant/browser/actions/show_progress_bar_action.cc deleted file mode 100644 index 06ffc46..0000000 --- a/components/autofill_assistant/browser/actions/show_progress_bar_action.cc +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/autofill_assistant/browser/actions/show_progress_bar_action.h" - -#include "base/bind.h" -#include "base/callback.h" -#include "components/autofill_assistant/browser/actions/action_delegate.h" - -namespace autofill_assistant { - -ShowProgressBarAction::ShowProgressBarAction(const ActionProto& proto) - : Action(proto) { - DCHECK(proto_.has_show_progress_bar()); -} - -ShowProgressBarAction::~ShowProgressBarAction() {} - -void ShowProgressBarAction::ProcessAction(ActionDelegate* delegate, - ProcessActionCallback callback) { - int progress = - std::min(100, std::max(0, proto_.show_progress_bar().progress())); - if (proto_.show_progress_bar().done() || progress == 100) { - delegate->HideProgressBar(); - } else { - delegate->ShowProgressBar(progress, proto_.show_progress_bar().message()); - } - - processed_action_proto_ = std::make_unique<ProcessedActionProto>(); - UpdateProcessedAction(ACTION_APPLIED); - std::move(callback).Run(std::move(processed_action_proto_)); -} - -} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/show_progress_bar_action.h b/components/autofill_assistant/browser/actions/show_progress_bar_action.h deleted file mode 100644 index 4655a87..0000000 --- a/components/autofill_assistant/browser/actions/show_progress_bar_action.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SHOW_PROGRESS_BAR_ACTION_H_ -#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SHOW_PROGRESS_BAR_ACTION_H_ - -#include "components/autofill_assistant/browser/actions/action.h" - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" - -namespace autofill_assistant { -// An action to show the current progress. -class ShowProgressBarAction : public Action { - public: - explicit ShowProgressBarAction(const ActionProto& proto); - ~ShowProgressBarAction() override; - - // Overrides Action: - void ProcessAction(ActionDelegate* delegate, - ProcessActionCallback callback) override; - - private: - DISALLOW_COPY_AND_ASSIGN(ShowProgressBarAction); -}; - -} // namespace autofill_assistant -#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_SHOW_PROGRESS_BAR_ACTION_H_
diff --git a/components/autofill_assistant/browser/mock_ui_controller.h b/components/autofill_assistant/browser/mock_ui_controller.h index e7000b68..99abdfea 100644 --- a/components/autofill_assistant/browser/mock_ui_controller.h +++ b/components/autofill_assistant/browser/mock_ui_controller.h
@@ -47,8 +47,6 @@ callback)); MOCK_METHOD0(HideDetails, void()); MOCK_METHOD1(ShowDetails, void(const DetailsProto& details)); - MOCK_METHOD2(ShowProgressBar, void(int progress, const std::string& message)); - MOCK_METHOD0(HideProgressBar, void()); }; } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/protocol_utils.cc b/components/autofill_assistant/browser/protocol_utils.cc index a88f53b..fc576fa 100644 --- a/components/autofill_assistant/browser/protocol_utils.cc +++ b/components/autofill_assistant/browser/protocol_utils.cc
@@ -16,7 +16,6 @@ #include "components/autofill_assistant/browser/actions/reset_action.h" #include "components/autofill_assistant/browser/actions/select_option_action.h" #include "components/autofill_assistant/browser/actions/show_details_action.h" -#include "components/autofill_assistant/browser/actions/show_progress_bar_action.h" #include "components/autofill_assistant/browser/actions/stop_action.h" #include "components/autofill_assistant/browser/actions/tell_action.h" #include "components/autofill_assistant/browser/actions/unsupported_action.h" @@ -212,10 +211,6 @@ std::make_unique<GetPaymentInformationAction>(action)); break; } - case ActionProto::ActionInfoCase::kShowProgressBar: { - actions->emplace_back(std::make_unique<ShowProgressBarAction>(action)); - break; - } default: case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET: { DLOG(ERROR) << "Unknown or unsupported action with action_case="
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc index dd75825..56417d8 100644 --- a/components/autofill_assistant/browser/script_executor.cc +++ b/components/autofill_assistant/browser/script_executor.cc
@@ -137,14 +137,6 @@ delegate_->GetWebController()->FocusElement(selectors, std::move(callback)); } -void ScriptExecutor::ShowProgressBar(int progress, const std::string& message) { - delegate_->GetUiController()->ShowProgressBar(progress, message); -} - -void ScriptExecutor::HideProgressBar() { - delegate_->GetUiController()->HideProgressBar(); -} - void ScriptExecutor::SetFieldValue(const std::vector<std::string>& selectors, const std::string& value, base::OnceCallback<void(bool)> callback) {
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h index aff39ca..7b8c0ad 100644 --- a/components/autofill_assistant/browser/script_executor.h +++ b/components/autofill_assistant/browser/script_executor.h
@@ -97,8 +97,6 @@ void StopCurrentScript(const std::string& message) override; void HideDetails() override; void ShowDetails(const DetailsProto& details) override; - void ShowProgressBar(int progress, const std::string& message) override; - void HideProgressBar() override; private: void OnGetActions(bool result, const std::string& response);
diff --git a/components/autofill_assistant/browser/script_tracker.cc b/components/autofill_assistant/browser/script_tracker.cc index 3837fd7..f732d45 100644 --- a/components/autofill_assistant/browser/script_tracker.cc +++ b/components/autofill_assistant/browser/script_tracker.cc
@@ -90,11 +90,17 @@ ScriptExecutor::RunScriptCallback run_script_callback = base::BindOnce( &ScriptTracker::OnScriptRun, weak_ptr_factory_.GetWeakPtr(), script_path, std::move(callback)); - // Postpone running script until finishing preconditions check. + // Postpone running script until finishing the current round of preconditions + // check. if (!batch_element_checker_ && !must_recheck_) { executor_->Run(std::move(run_script_callback)); } else { pending_run_script_callback_ = std::move(run_script_callback); + // Do not recheck and retry when there is a script pending to run. Note + // that |batch_element_checker_| may take a long time to wait on retrying + // unsatisfied preconditions check without stop trying. + must_recheck_.Reset(); + batch_element_checker_->StopTrying(); } }
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 70ced1b..8dad0e3 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -199,7 +199,6 @@ UseCreditCardProto use_card = 28; UseAddressProto use_address = 29; UploadDomProto upload_dom = 18; - ShowProgressBarProto show_progress_bar = 24; HighlightElementProto highlight_element = 31; ShowDetailsProto show_details = 32; ResetProto reset = 34; @@ -348,20 +347,6 @@ optional ElementReferenceProto tree_root = 1; } -// Shows the progress bar. -message ShowProgressBarProto { - // Specifies whether the progress is done and should be removed. - optional bool done = 2; - - // Message to show on the progress bar while loading. - optional string message = 3; - - // Value between 0 and 100 indicating the current progress. Values above 100 - // will be capped to 100, values below 0 will be capped to 0 by the client. - // NOTE: Setting |progress| to 100 is an equivalent of setting |done| to true. - optional int32 progress = 6; -} - // Contain all arguments to perform a highlight element action. message HighlightElementProto { // The element to highlight.
diff --git a/components/autofill_assistant/browser/ui_controller.h b/components/autofill_assistant/browser/ui_controller.h index 9105c33..2c9f343 100644 --- a/components/autofill_assistant/browser/ui_controller.h +++ b/components/autofill_assistant/browser/ui_controller.h
@@ -72,12 +72,6 @@ // Show contextual information. virtual void ShowDetails(const DetailsProto& details) = 0; - // Show the progress bar with |message| and set it at |progress|%. - virtual void ShowProgressBar(int progress, const std::string& message) = 0; - - // Hide the progress bar. - virtual void HideProgressBar(); - protected: UiController() = default; };
diff --git a/components/chrome_cleaner/public/interfaces/chrome_prompt.mojom b/components/chrome_cleaner/public/interfaces/chrome_prompt.mojom index 741e0c8..f475fcdd 100644 --- a/components/chrome_cleaner/public/interfaces/chrome_prompt.mojom +++ b/components/chrome_cleaner/public/interfaces/chrome_prompt.mojom
@@ -59,6 +59,7 @@ [MinVersion=2] array<ExtensionId>? extension_ids) => (PromptAcceptance prompt_acceptance); + // Actually uninstalls the extensions. // Params: // - extension_ids: list of IDs of extensions that will be removed from // Chrome. If there are any invalid IDs, none are removed and false is
diff --git a/components/crash/content/browser/crash_metrics_reporter_android.cc b/components/crash/content/browser/crash_metrics_reporter_android.cc index 14394505..bf6d85a2 100644 --- a/components/crash/content/browser/crash_metrics_reporter_android.cc +++ b/components/crash/content/browser/crash_metrics_reporter_android.cc
@@ -147,9 +147,14 @@ const uint64_t vm_size_kb = info.blink_oom_metrics.current_vm_size_kb; const uint64_t blink_usage_kb = info.blink_oom_metrics.current_blink_usage_kb; - if (info.process_type == content::PROCESS_TYPE_GPU && app_foreground && - android_oom_kill) { - ReportCrashCount(ProcessedCrashCounts::kGpuForegroundOom, &reported_counts); + if (app_foreground && android_oom_kill) { + if (info.process_type == content::PROCESS_TYPE_GPU) { + ReportCrashCount(ProcessedCrashCounts::kGpuForegroundOom, + &reported_counts); + } else if (info.process_type == content::PROCESS_TYPE_UTILITY) { + ReportCrashCount(ProcessedCrashCounts::kUtilityForegroundOom, + &reported_counts); + } } if (info.process_type == content::PROCESS_TYPE_RENDERER && @@ -263,10 +268,15 @@ } if (has_valid_dump) { - ReportCrashCount(info.process_type == content::PROCESS_TYPE_GPU - ? ProcessedCrashCounts::kGpuCrashAll - : ProcessedCrashCounts::kRendererCrashAll, - &reported_counts); + if (info.process_type == content::PROCESS_TYPE_RENDERER) { + ReportCrashCount(ProcessedCrashCounts::kRendererCrashAll, + &reported_counts); + } else if (info.process_type == content::PROCESS_TYPE_GPU) { + ReportCrashCount(ProcessedCrashCounts::kGpuCrashAll, &reported_counts); + } else if (info.process_type == content::PROCESS_TYPE_UTILITY) { + ReportCrashCount(ProcessedCrashCounts::kUtilityCrashAll, + &reported_counts); + } } if (app_foreground && android_oom_kill &&
diff --git a/components/crash/content/browser/crash_metrics_reporter_android.h b/components/crash/content/browser/crash_metrics_reporter_android.h index e8311b6..f098ac2 100644 --- a/components/crash/content/browser/crash_metrics_reporter_android.h +++ b/components/crash/content/browser/crash_metrics_reporter_android.h
@@ -49,7 +49,9 @@ kRendererForegroundInvisibleWithModerateBindingOom = 14, kRendererForegroundVisibleAllocationFailure = 15, kRendererAllocationFailureAll = 16, - kMaxValue = kRendererAllocationFailureAll + kUtilityForegroundOom = 17, + kUtilityCrashAll = 18, + kMaxValue = kUtilityCrashAll }; using ReportedCrashTypeSet = base::flat_set<ProcessedCrashCounts>;
diff --git a/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc b/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc index f10bda7..6ab90298 100644 --- a/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc +++ b/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc
@@ -138,6 +138,51 @@ "GPU.GPUProcessDetailedExitStatus"); } +TEST_F(CrashMetricsReporterTest, UtilityProcessOOM) { + ChildExitObserver::TerminationInfo termination_info; + termination_info.process_host_id = 1; + termination_info.pid = base::kNullProcessHandle; + termination_info.process_type = content::PROCESS_TYPE_UTILITY; + termination_info.app_state = + base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES; + termination_info.normal_termination = false; + termination_info.binding_state = base::android::ChildBindingState::STRONG; + termination_info.was_killed_intentionally_by_browser = false; + termination_info.was_oom_protected_status = true; + termination_info.renderer_has_visible_clients = true; + + TestOomCrashProcessing( + termination_info, + {CrashMetricsReporter::ProcessedCrashCounts::kUtilityForegroundOom}, + nullptr); +} + +TEST_F(CrashMetricsReporterTest, UtilityProcessAll) { + ChildExitObserver::TerminationInfo termination_info; + termination_info.process_host_id = 1; + termination_info.pid = base::kNullProcessHandle; + termination_info.process_type = content::PROCESS_TYPE_UTILITY; + termination_info.app_state = + base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES; + termination_info.normal_termination = false; + termination_info.binding_state = base::android::ChildBindingState::STRONG; + termination_info.was_killed_intentionally_by_browser = false; + termination_info.was_oom_protected_status = true; + termination_info.renderer_has_visible_clients = true; + + CrashMetricsReporterObserver crash_dump_observer; + CrashMetricsReporter::GetInstance()->AddObserver(&crash_dump_observer); + + CrashMetricsReporter::GetInstance()->CrashDumpProcessed( + termination_info, + breakpad::CrashDumpManager::CrashDumpStatus::kValidDump); + crash_dump_observer.WaitForProcessed(); + + EXPECT_EQ(CrashMetricsReporter::ReportedCrashTypeSet( + {CrashMetricsReporter::ProcessedCrashCounts::kUtilityCrashAll}), + crash_dump_observer.recorded_crash_types()); +} + TEST_F(CrashMetricsReporterTest, RendererSubframeOOM) { ChildExitObserver::TerminationInfo termination_info; termination_info.process_host_id = 1;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc index 68d8f3c..21844b4b 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -48,7 +48,6 @@ #include "net/url_request/url_fetcher_delegate.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_context_getter.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #if defined(OS_ANDROID) @@ -208,8 +207,6 @@ } void DataReductionProxyConfig::InitializeOnIOThread( - const scoped_refptr<net::URLRequestContextGetter>& - basic_url_request_context_getter, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, NetworkPropertiesManager* manager) { DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h index 306cd78..22ab7af 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
@@ -37,7 +37,6 @@ namespace net { class ProxyServer; class URLRequest; -class URLRequestContextGetter; } // namespace net namespace data_reduction_proxy { @@ -95,13 +94,9 @@ ~DataReductionProxyConfig() override; // Performs initialization on the IO thread. - // |basic_url_request_context_getter| is the net::URLRequestContextGetter that - // disables the use of alternative protocols and proxies. - // |url_request_context_getter| is the default net::URLRequestContextGetter - // used for making URL requests. + // |url_loader_factory| is the network::URLLoaderFactory instance used for + // making URL requests. The requests disable the use of proxies. void InitializeOnIOThread( - const scoped_refptr<net::URLRequestContextGetter>& - basic_url_request_context_getter, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, NetworkPropertiesManager* manager);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc index 3999227..839987a 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -130,21 +130,20 @@ class TestResponder { public: void ExecuteCallback(SecureProxyCheckerCallback callback) { - callback.Run(response, status.error(), http_response_code); + callback.Run(response, net_error, http_response_code); } std::string response; - net::URLRequestStatus status; + net::Error net_error; int http_response_code; }; - // TODO(tonikitoo): Get rid of the use of net::URLRequestStatus altogether. void CheckSecureProxyCheckOnNetworkChange( network::mojom::ConnectionType connection_type, const std::string& response, bool is_captive_portal, int response_code, - net::URLRequestStatus status, + net::Error net_error, SecureProxyCheckFetchResult expected_fetch_result, const std::vector<net::ProxyServer>& expected_proxies_for_http) { base::HistogramTester histogram_tester; @@ -152,7 +151,7 @@ TestResponder responder; responder.response = response; - responder.status = status; + responder.net_error = net_error; responder.http_response_code = response_code; EXPECT_CALL(*mock_config(), SecureProxyCheck(_)) .Times(1) @@ -162,10 +161,9 @@ test_context_->RunUntilIdle(); EXPECT_EQ(expected_proxies_for_http, GetConfiguredProxiesForHttp()); - if (!status.is_success() && - status.error() != net::ERR_INTERNET_DISCONNECTED) { + if (net_error != net::OK && net_error != net::ERR_INTERNET_DISCONNECTED) { histogram_tester.ExpectUniqueSample("DataReductionProxy.ProbeURLNetError", - std::abs(status.error()), 1); + std::abs(net_error), 1); } else { histogram_tester.ExpectTotalCount("DataReductionProxy.ProbeURLNetError", 0); @@ -285,12 +283,13 @@ TEST_F(DataReductionProxyConfigTest, TestOnNetworkChanged) { RecreateContextWithMockConfig(); - const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK); const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI( "https://secure_origin.net:443", net::ProxyServer::SCHEME_HTTP); const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI( "insecure_origin.net:80", net::ProxyServer::SCHEME_HTTP); + int kInvalidResponseCode = -1; + SetProxiesForHttpOnCommandLine({kHttpsProxy, kHttpProxy}); ResetSettings(); @@ -302,35 +301,35 @@ // remains unrestricted. CheckSecureProxyCheckOnNetworkChange( network::mojom::ConnectionType::CONNECTION_WIFI, "OK", false, - net::HTTP_OK, kSuccess, SUCCEEDED_PROXY_ALREADY_ENABLED, + net::HTTP_OK, net::OK, SUCCEEDED_PROXY_ALREADY_ENABLED, {kHttpsProxy, kHttpProxy}); // Connection change triggers a secure proxy check that succeeds but captive // portal fails. Proxy is restricted. CheckSecureProxyCheckOnNetworkChange( network::mojom::ConnectionType::CONNECTION_WIFI, "OK", true, net::HTTP_OK, - kSuccess, SUCCEEDED_PROXY_ALREADY_ENABLED, + net::OK, SUCCEEDED_PROXY_ALREADY_ENABLED, std::vector<net::ProxyServer>(1, kHttpProxy)); // Connection change triggers a secure proxy check that fails. Proxy is // restricted. CheckSecureProxyCheckOnNetworkChange( network::mojom::ConnectionType::CONNECTION_WIFI, "Bad", false, - net::HTTP_OK, kSuccess, FAILED_PROXY_DISABLED, + net::HTTP_OK, net::OK, FAILED_PROXY_DISABLED, std::vector<net::ProxyServer>(1, kHttpProxy)); // Connection change triggers a secure proxy check that succeeds. Proxies // are unrestricted. CheckSecureProxyCheckOnNetworkChange( network::mojom::ConnectionType::CONNECTION_WIFI, "OK", false, - net::HTTP_OK, kSuccess, SUCCEEDED_PROXY_ENABLED, + net::HTTP_OK, net::OK, SUCCEEDED_PROXY_ENABLED, {kHttpsProxy, kHttpProxy}); // Connection change triggers a secure proxy check that fails. Proxy is // restricted. CheckSecureProxyCheckOnNetworkChange( network::mojom::ConnectionType::CONNECTION_WIFI, "Bad", true, - net::HTTP_OK, kSuccess, FAILED_PROXY_DISABLED, + net::HTTP_OK, net::OK, FAILED_PROXY_DISABLED, std::vector<net::ProxyServer>(1, kHttpProxy)); // Connection change triggers a secure proxy check that fails due to the @@ -338,23 +337,21 @@ // unrestricted. CheckSecureProxyCheckOnNetworkChange( network::mojom::ConnectionType::CONNECTION_WIFI, std::string(), false, - net::URLFetcher::RESPONSE_CODE_INVALID, - net::URLRequestStatus(net::URLRequestStatus::FAILED, - net::ERR_INTERNET_DISCONNECTED), + kInvalidResponseCode, net::ERR_INTERNET_DISCONNECTED, INTERNET_DISCONNECTED, std::vector<net::ProxyServer>(1, kHttpProxy)); // Connection change triggers a secure proxy check that fails. Proxy remains // restricted. CheckSecureProxyCheckOnNetworkChange( network::mojom::ConnectionType::CONNECTION_WIFI, "Bad", false, - net::HTTP_OK, kSuccess, FAILED_PROXY_ALREADY_DISABLED, + net::HTTP_OK, net::OK, FAILED_PROXY_ALREADY_DISABLED, std::vector<net::ProxyServer>(1, kHttpProxy)); // Connection change triggers a secure proxy check that succeeds. Proxy is // unrestricted. CheckSecureProxyCheckOnNetworkChange( network::mojom::ConnectionType::CONNECTION_WIFI, "OK", false, - net::HTTP_OK, kSuccess, SUCCEEDED_PROXY_ENABLED, + net::HTTP_OK, net::OK, SUCCEEDED_PROXY_ENABLED, {kHttpsProxy, kHttpProxy}); // Connection change triggers a secure proxy check that fails due to the @@ -362,23 +359,19 @@ // unrestricted. CheckSecureProxyCheckOnNetworkChange( network::mojom::ConnectionType::CONNECTION_WIFI, std::string(), false, - net::URLFetcher::RESPONSE_CODE_INVALID, - net::URLRequestStatus(net::URLRequestStatus::FAILED, - net::ERR_INTERNET_DISCONNECTED), + kInvalidResponseCode, net::ERR_INTERNET_DISCONNECTED, INTERNET_DISCONNECTED, {kHttpsProxy, kHttpProxy}); // Connection change triggers a secure proxy check that fails because of a // redirect response, e.g. by a captive portal. Proxy is restricted. CheckSecureProxyCheckOnNetworkChange( network::mojom::ConnectionType::CONNECTION_WIFI, "Bad", false, - net::HTTP_FOUND, - net::URLRequestStatus(net::URLRequestStatus::CANCELED, net::ERR_ABORTED), - FAILED_PROXY_DISABLED, std::vector<net::ProxyServer>(1, kHttpProxy)); + net::HTTP_FOUND, net::ERR_ABORTED, FAILED_PROXY_DISABLED, + std::vector<net::ProxyServer>(1, kHttpProxy)); } // Verifies that the warm up URL is fetched correctly. TEST_F(DataReductionProxyConfigTest, WarmupURL) { - const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK); const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI( "https://secure_origin.net:443", net::ProxyServer::SCHEME_HTTP); const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI( @@ -426,8 +419,7 @@ NetworkPropertiesManager network_properties_manager( base::DefaultClock::GetInstance(), test_context_->pref_service(), test_context_->task_runner()); - config.InitializeOnIOThread(test_context_->request_context_getter(), - test_context_->url_loader_factory(), + config.InitializeOnIOThread(test_context_->url_loader_factory(), &network_properties_manager); RunUntilIdle(); @@ -865,7 +857,6 @@ TEST_F(DataReductionProxyConfigTest, HandleWarmupFetcherResponse) { base::HistogramTester histogram_tester; - const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK); const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI( "https://origin.net:443", net::ProxyServer::SCHEME_HTTP); const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI( @@ -1015,7 +1006,6 @@ // as failed when the warmup fetched callback returns an invalid proxy. TEST_F(DataReductionProxyConfigTest, HandleWarmupFetcherResponse_InvalidProxyServer) { - const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK); const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI( "https://origin.net:443", net::ProxyServer::SCHEME_HTTP); const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI( @@ -1043,7 +1033,6 @@ // as failed when the warmup fetched callback returns a direct proxy. TEST_F(DataReductionProxyConfigTest, HandleWarmupFetcherResponse_DirectProxyServer) { - const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK); const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI( "https://origin.net:443", net::ProxyServer::SCHEME_HTTP); const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI( @@ -1071,7 +1060,6 @@ constexpr size_t kMaxWarmupURLFetchAttempts = 3; base::HistogramTester histogram_tester; - const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK); const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI( "https://origin.net:443", net::ProxyServer::SCHEME_HTTP); const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI( @@ -1210,7 +1198,6 @@ // Tests the behavior when warmup URL fetcher times out. TEST_F(DataReductionProxyConfigTest, HandleWarmupFetcherTimeout) { base::HistogramTester histogram_tester; - const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK); const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI( "https://origin.net:443", net::ProxyServer::SCHEME_HTTP); const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI( @@ -1268,7 +1255,6 @@ constexpr size_t kMaxWarmupURLFetchAttempts = 3; base::HistogramTester histogram_tester; - const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK); const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI( "https://origin.net:443", net::ProxyServer::SCHEME_HTTP); const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc index e1c378e..47b1dd45 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
@@ -39,58 +39,6 @@ namespace data_reduction_proxy { -// A |net::URLRequestContextGetter| which uses only vanilla HTTP/HTTPS for -// performing requests. This is used by the secure proxy check to prevent the -// use of SPDY and QUIC which may be used by the primary request contexts. -class BasicHTTPURLRequestContextGetter : public net::URLRequestContextGetter { - public: - BasicHTTPURLRequestContextGetter( - const std::string& user_agent, - const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner); - - // Overridden from net::URLRequestContextGetter: - net::URLRequestContext* GetURLRequestContext() override; - scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() - const override; - - private: - ~BasicHTTPURLRequestContextGetter() override; - - scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; - std::unique_ptr<net::HttpUserAgentSettings> user_agent_settings_; - std::unique_ptr<net::URLRequestContext> url_request_context_; - - DISALLOW_COPY_AND_ASSIGN(BasicHTTPURLRequestContextGetter); -}; - -BasicHTTPURLRequestContextGetter::BasicHTTPURLRequestContextGetter( - const std::string& user_agent, - const scoped_refptr<base::SingleThreadTaskRunner>& network_task_runner) - : network_task_runner_(network_task_runner), - user_agent_settings_( - new net::StaticHttpUserAgentSettings(std::string(), user_agent)) { -} - -net::URLRequestContext* -BasicHTTPURLRequestContextGetter::GetURLRequestContext() { - if (!url_request_context_) { - net::URLRequestContextBuilder builder; - builder.set_proxy_resolution_service(net::ProxyResolutionService::CreateDirect()); - builder.SetSpdyAndQuicEnabled(false, false); - url_request_context_ = builder.Build(); - } - - return url_request_context_.get(); -} - -scoped_refptr<base::SingleThreadTaskRunner> -BasicHTTPURLRequestContextGetter::GetNetworkTaskRunner() const { - return network_task_runner_; -} - -BasicHTTPURLRequestContextGetter::~BasicHTTPURLRequestContextGetter() { -} - DataReductionProxyIOData::DataReductionProxyIOData( Client client, PrefService* prefs, @@ -107,8 +55,6 @@ data_use_observer_(nullptr), enabled_(enabled), url_request_context_getter_(nullptr), - basic_url_request_context_getter_( - new BasicHTTPURLRequestContextGetter(user_agent, io_task_runner)), channel_(channel), effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN), weak_factory_(this) { @@ -212,8 +158,7 @@ auto url_loader_factory = network::SharedURLLoaderFactory::Create( std::move(url_loader_factory_info_)); - config_->InitializeOnIOThread(basic_url_request_context_getter_.get(), - url_loader_factory, + config_->InitializeOnIOThread(url_loader_factory, network_properties_manager_.get()); bypass_stats_->InitializeOnIOThread(); proxy_delegate_->InitializeOnIOThread(this);
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h index 7e7cde8..4564a4cb 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h
@@ -291,10 +291,6 @@ // The net::URLRequestContextGetter used for making URL requests. net::URLRequestContextGetter* url_request_context_getter_; - // A net::URLRequestContextGetter used for making secure proxy checks. It - // does not use alternate protocols. - scoped_refptr<net::URLRequestContextGetter> basic_url_request_context_getter_; - // The network::SharedURLLoaderFactoryInfo used for making URL requests. std::unique_ptr<network::SharedURLLoaderFactoryInfo> url_loader_factory_info_;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc index 8b21faa..2e6d3b84 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data_unittest.cc
@@ -110,14 +110,6 @@ false /* enabled */, std::string() /* user_agent */, std::string() /* channel */)); - // Check that the SimpleURLRequestContextGetter uses vanilla HTTP. - net::URLRequestContext* request_context = - io_data->basic_url_request_context_getter_->GetURLRequestContext(); - const net::HttpNetworkSession::Params* http_params = - request_context->GetNetworkSessionParams(); - EXPECT_FALSE(http_params->enable_http2); - EXPECT_FALSE(http_params->enable_quic); - // Check that io_data creates an interceptor. Such an interceptor is // thoroughly tested by DataReductionProxyInterceptoTest. std::unique_ptr<net::URLRequestInterceptor> interceptor =
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc index f3adcf4..d49586e1 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
@@ -518,7 +518,6 @@ pref_service.get(), task_runner, std::move(config), std::move(request_options), std::move(configurator), test_network_connection_tracker, true /* enabled */)); - io_data->SetSimpleURLRequestContextGetter(request_context_getter); if (use_test_config_client_) { test_context_flags |= USE_TEST_CONFIG_CLIENT;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h index 1f26741..1495d884 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h
@@ -247,11 +247,6 @@ proxy_delegate_ = std::move(proxy_delegate); } - void SetSimpleURLRequestContextGetter( - const scoped_refptr<net::URLRequestContextGetter> context_getter) { - basic_url_request_context_getter_ = context_getter; - } - base::WeakPtr<DataReductionProxyIOData> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
diff --git a/components/download/internal/common/download_db_cache.cc b/components/download/internal/common/download_db_cache.cc index 784a381..3778fc44 100644 --- a/components/download/internal/common/download_db_cache.cc +++ b/components/download/internal/common/download_db_cache.cc
@@ -7,7 +7,6 @@ #include "components/download/database/download_db.h" #include "components/download/database/download_db_conversions.h" #include "components/download/database/download_db_entry.h" -#include "components/download/database/in_progress/download_entry.h" #include "components/download/public/common/download_features.h" #include "components/download/public/common/download_stats.h" #include "components/download/public/common/download_utils.h" @@ -96,12 +95,12 @@ return UkmInfo(DownloadSource::UNKNOWN, GetUniqueDownloadId()); } -void CleanUpInProgressEntry(DownloadDBEntry& entry) { - if (!entry.download_info) +void CleanUpInProgressEntry(DownloadDBEntry* entry) { + if (!entry->download_info) return; base::Optional<InProgressInfo>& in_progress_info = - entry.download_info->in_progress_info; + entry->download_info->in_progress_info; if (!in_progress_info) return; @@ -129,15 +128,14 @@ DownloadDBCache::~DownloadDBCache() = default; -void DownloadDBCache::Initialize(const std::vector<DownloadEntry>& entries, - InitializeCallback callback) { +void DownloadDBCache::Initialize(InitializeCallback callback) { // TODO(qinmin): migrate all the data from InProgressCache into // |download_db_|. if (!initialized_) { RecordInProgressDBCount(kInitializationCount); - download_db_->Initialize(base::BindOnce( - &DownloadDBCache::OnDownloadDBInitialized, weak_factory_.GetWeakPtr(), - entries, std::move(callback))); + download_db_->Initialize( + base::BindOnce(&DownloadDBCache::OnDownloadDBInitialized, + weak_factory_.GetWeakPtr(), std::move(callback))); return; } @@ -230,12 +228,10 @@ } void DownloadDBCache::OnDownloadDBInitialized( - const std::vector<DownloadEntry>& entries, InitializeCallback callback, bool success) { if (success) { RecordInProgressDBCount(kInitializationSucceededCount); - MigrateFromInProgressCache(entries); download_db_->LoadEntries( base::BindOnce(&DownloadDBCache::OnDownloadDBEntriesLoaded, weak_factory_.GetWeakPtr(), std::move(callback))); @@ -253,8 +249,14 @@ initialized_ = success; RecordInProgressDBCount(success ? kLoadSucceededCount : kLoadFailedCount); for (auto& entry : *entries) { - CleanUpInProgressEntry(entry); - entries_[entry.download_info->guid] = entry; + // If the entry is from the metadata cache migration, just remove it from + // DB as the data is not being cleaned up properly. + if (entry.download_info->id < 0) { + RemoveEntry(entry.download_info->guid); + } else { + CleanUpInProgressEntry(&entry); + entries_[entry.download_info->guid] = entry; + } } std::move(callback).Run(success, std::move(entries)); } @@ -264,25 +266,4 @@ update_timer_.SetTaskRunner(task_runner); } -void DownloadDBCache::MigrateFromInProgressCache( - const std::vector<DownloadEntry>& entries) { - if (entries.empty()) - return; - RecordInProgressDBCount(kCacheMigrationCount); - std::vector<DownloadDBEntry> db_entries; - for (const auto& entry : entries) { - DCHECK(entries_.find(entry.guid) == entries_.end()); - db_entries.emplace_back( - DownloadDBConversions::DownloadDBEntryFromDownloadEntry(entry)); - } - download_db_->AddOrReplaceEntries( - db_entries, base::BindOnce(&DownloadDBCache::OnInProgressCacheMigrated, - weak_factory_.GetWeakPtr())); -} - -void DownloadDBCache::OnInProgressCacheMigrated(bool success) { - RecordInProgressDBCount(success ? kCacheMigrationSucceededCount - : kCacheMigrationFailedCount); -} - } // namespace download
diff --git a/components/download/internal/common/download_db_cache.h b/components/download/internal/common/download_db_cache.h index 36b3b38..f0aafcf 100644 --- a/components/download/internal/common/download_db_cache.h +++ b/components/download/internal/common/download_db_cache.h
@@ -21,7 +21,6 @@ class DownloadDB; struct DownloadDBEntry; -struct DownloadEntry; // Responsible for caching the metadata of all in progress downloads. class COMPONENTS_DOWNLOAD_EXPORT DownloadDBCache @@ -33,8 +32,7 @@ using InitializeCallback = base::OnceCallback<void(bool /* success */, std::unique_ptr<std::vector<DownloadDBEntry>>)>; - void Initialize(const std::vector<DownloadEntry>& entries, - InitializeCallback callback); + void Initialize(InitializeCallback callback); base::Optional<DownloadDBEntry> RetrieveEntry(const std::string& guid); void AddOrReplaceEntry(const DownloadDBEntry& entry); @@ -54,9 +52,7 @@ void OnDownloadRemoved(DownloadItem* download) override; // Called when the |download_db_| is initialized. - void OnDownloadDBInitialized(const std::vector<DownloadEntry>& entries, - InitializeCallback callback, - bool success); + void OnDownloadDBInitialized(InitializeCallback callback, bool success); // Called when all the download db entries are loaded. void OnDownloadDBEntriesLoaded( @@ -64,12 +60,6 @@ bool success, std::unique_ptr<std::vector<DownloadDBEntry>> entries); - // Migrate DownloadEntry from in-progress cache. - void MigrateFromInProgressCache(const std::vector<DownloadEntry>& entries); - - // Called when InProgressCache is migrated. - void OnInProgressCacheMigrated(bool success); - void SetTimerTaskRunnerForTesting( scoped_refptr<base::SequencedTaskRunner> task_runner);
diff --git a/components/download/internal/common/download_db_cache_unittest.cc b/components/download/internal/common/download_db_cache_unittest.cc index f656586d..34aa5c2 100644 --- a/components/download/internal/common/download_db_cache_unittest.cc +++ b/components/download/internal/common/download_db_cache_unittest.cc
@@ -34,6 +34,8 @@ DownloadDBEntry entry; DownloadInfo download_info; download_info.guid = base::GenerateGUID(); + static int id = 0; + download_info.id = ++id; entry.download_info = download_info; return entry; } @@ -44,44 +46,6 @@ "," + guid; } -std::unique_ptr<DownloadItem> CreateDownloadItem(const std::string& guid) { - std::unique_ptr<MockDownloadItem> item( - new ::testing::NiceMock<MockDownloadItem>()); - ON_CALL(*item, GetGuid()).WillByDefault(ReturnRefOfCopy(guid)); - ON_CALL(*item, GetUrlChain()) - .WillByDefault(ReturnRefOfCopy(std::vector<GURL>())); - ON_CALL(*item, GetReferrerUrl()).WillByDefault(ReturnRefOfCopy(GURL())); - ON_CALL(*item, GetSiteUrl()).WillByDefault(ReturnRefOfCopy(GURL())); - ON_CALL(*item, GetTabUrl()).WillByDefault(ReturnRefOfCopy(GURL())); - ON_CALL(*item, GetTabReferrerUrl()).WillByDefault(ReturnRefOfCopy(GURL())); - ON_CALL(*item, GetETag()).WillByDefault(ReturnRefOfCopy(std::string("etag"))); - ON_CALL(*item, GetLastModifiedTime()) - .WillByDefault(ReturnRefOfCopy(std::string("last-modified"))); - ON_CALL(*item, GetMimeType()).WillByDefault(Return("text/html")); - ON_CALL(*item, GetOriginalMimeType()).WillByDefault(Return("text/html")); - ON_CALL(*item, GetTotalBytes()).WillByDefault(Return(1000)); - ON_CALL(*item, GetFullPath()) - .WillByDefault(ReturnRefOfCopy(base::FilePath())); - ON_CALL(*item, GetTargetFilePath()) - .WillByDefault(ReturnRefOfCopy(base::FilePath())); - ON_CALL(*item, GetReceivedBytes()).WillByDefault(Return(1000)); - ON_CALL(*item, GetStartTime()).WillByDefault(Return(base::Time())); - ON_CALL(*item, GetEndTime()).WillByDefault(Return(base::Time())); - ON_CALL(*item, GetReceivedSlices()) - .WillByDefault( - ReturnRefOfCopy(std::vector<DownloadItem::ReceivedSlice>())); - ON_CALL(*item, GetHash()).WillByDefault(ReturnRefOfCopy(std::string("hash"))); - ON_CALL(*item, IsTransient()).WillByDefault(Return(false)); - ON_CALL(*item, GetDangerType()) - .WillByDefault(Return(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)); - ON_CALL(*item, GetLastReason()) - .WillByDefault(Return(DOWNLOAD_INTERRUPT_REASON_NONE)); - ON_CALL(*item, GetState()).WillByDefault(Return(DownloadItem::IN_PROGRESS)); - ON_CALL(*item, IsPaused()).WillByDefault(Return(false)); - ON_CALL(*item, GetBytesWasted()).WillByDefault(Return(10)); - return std::move(item); -} - } // namespace class DownloadDBCacheTest : public testing::Test { @@ -144,7 +108,6 @@ CreateDBCache(); std::vector<DownloadDBEntry> loaded_entries; db_cache_->Initialize( - std::vector<DownloadEntry>(), base::BindOnce(&DownloadDBCacheTest::InitCallback, base::Unretained(this), &loaded_entries)); db_->InitCallback(true); @@ -165,7 +128,6 @@ CreateDBCache(); std::vector<DownloadDBEntry> loaded_entries; db_cache_->Initialize( - std::vector<DownloadEntry>(), base::BindOnce(&DownloadDBCacheTest::InitCallback, base::Unretained(this), &loaded_entries)); db_->InitCallback(true); @@ -191,7 +153,6 @@ CreateDBCache(); std::vector<DownloadDBEntry> loaded_entries; db_cache_->Initialize( - std::vector<DownloadEntry>(), base::BindOnce(&DownloadDBCacheTest::InitCallback, base::Unretained(this), &loaded_entries)); db_->InitCallback(true); @@ -232,7 +193,6 @@ CreateDBCache(); std::vector<DownloadDBEntry> loaded_entries; db_cache_->Initialize( - std::vector<DownloadEntry>(), base::BindOnce(&DownloadDBCacheTest::InitCallback, base::Unretained(this), &loaded_entries)); db_->InitCallback(true); @@ -262,7 +222,6 @@ CreateDBCache(); std::vector<DownloadDBEntry> loaded_entries; db_cache_->Initialize( - std::vector<DownloadEntry>(), base::BindOnce(&DownloadDBCacheTest::InitCallback, base::Unretained(this), &loaded_entries)); db_->InitCallback(true); @@ -292,7 +251,6 @@ CreateDBCache(); std::vector<DownloadDBEntry> loaded_entries; db_cache_->Initialize( - std::vector<DownloadEntry>(), base::BindOnce(&DownloadDBCacheTest::InitCallback, base::Unretained(this), &loaded_entries)); db_->InitCallback(true); @@ -318,51 +276,4 @@ ASSERT_EQ(remaining, loaded_entries[0]); } -// Tests that Migrating a DownloadEntry from InProgressCache should store -// a DownloadDBEntry in the DownloadDB. -TEST_F(DownloadDBCacheTest, MigrateFromInProgressCache) { - CreateDBCache(); - std::vector<DownloadEntry> download_entries; - download_entries.emplace_back( - "guid1", "foo.com", DownloadSource::DRAG_AND_DROP, true, - DownloadUrlParameters::RequestHeadersType(), 100); - download_entries.emplace_back( - "guid2", "foobar.com", DownloadSource::UNKNOWN, false, - DownloadUrlParameters::RequestHeadersType(), 200); - - std::vector<DownloadDBEntry> loaded_entries; - db_cache_->Initialize( - download_entries, - base::BindOnce(&DownloadDBCacheTest::InitCallback, base::Unretained(this), - &loaded_entries)); - db_->InitCallback(true); - db_->UpdateCallback(true); - db_->LoadCallback(true); - ASSERT_FALSE(loaded_entries.empty()); - - std::unique_ptr<DownloadItem> item = CreateDownloadItem("guid1"); - OnDownloadUpdated(item.get()); - - ASSERT_EQ(task_runner_->GetPendingTaskCount(), 1u); - ASSERT_GT(task_runner_->NextPendingTaskDelay(), base::TimeDelta()); - task_runner_->FastForwardUntilNoTasksRemain(); - db_->UpdateCallback(true); - - DownloadDBEntry entry1 = CreateDownloadDBEntryFromItem( - *item, UkmInfo(DownloadSource::DRAG_AND_DROP, 100), true, - DownloadUrlParameters::RequestHeadersType()); - DownloadDBEntry entry2 = - DownloadDBConversions::DownloadDBEntryFromDownloadEntry( - download_entries[1]); - - DownloadDB* download_db = GetDownloadDB(); - download_db->LoadEntries(base::BindOnce(&DownloadDBCacheTest::InitCallback, - base::Unretained(this), - &loaded_entries)); - db_->LoadCallback(true); - ASSERT_EQ(loaded_entries.size(), 2u); - ASSERT_TRUE(entry1 == loaded_entries[0]); - ASSERT_TRUE(entry2 == loaded_entries[1]); -} - } // namespace download
diff --git a/components/download/internal/common/in_progress_download_manager.cc b/components/download/internal/common/in_progress_download_manager.cc index 1666c2d..51e5c904 100644 --- a/components/download/internal/common/in_progress_download_manager.cc +++ b/components/download/internal/common/in_progress_download_manager.cc
@@ -36,15 +36,14 @@ if (!entry.download_info) return nullptr; - // DownloadDBEntry migrated from in-progress cache doesn't have Ids. - if (!entry.download_info->id) + // DownloadDBEntry migrated from in-progress cache has negative Ids. + if (entry.download_info->id < 0) return nullptr; base::Optional<InProgressInfo> in_progress_info = entry.download_info->in_progress_info; if (!in_progress_info) return nullptr; - return std::make_unique<DownloadItemImpl>( delegate, entry.download_info->guid, entry.download_info->id, in_progress_info->current_path, in_progress_info->target_path, @@ -494,7 +493,6 @@ DownloadNamespace::NAMESPACE_BROWSER_DOWNLOAD, metadata_cache_dir)); download_db_cache_->Initialize( - download_metadata_cache_->GetAllEntries(), base::BindOnce(&InProgressDownloadManager::OnInitialized, weak_factory_.GetWeakPtr())); }
diff --git a/components/embedder_support/android/delegate/web_contents_delegate_android.cc b/components/embedder_support/android/delegate/web_contents_delegate_android.cc index cfc076b..40067ec 100644 --- a/components/embedder_support/android/delegate/web_contents_delegate_android.cc +++ b/components/embedder_support/android/delegate/web_contents_delegate_android.cc
@@ -304,7 +304,7 @@ Java_WebContentsDelegateAndroid_onUpdateUrl(env, obj, java_url); } -void WebContentsDelegateAndroid::HandleKeyboardEvent( +bool WebContentsDelegateAndroid::HandleKeyboardEvent( WebContents* source, const content::NativeWebKeyboardEvent& event) { const JavaRef<jobject>& key_event = event.os_event; @@ -312,9 +312,10 @@ JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); if (obj.is_null()) - return; + return true; Java_WebContentsDelegateAndroid_handleKeyboardEvent(env, obj, key_event); } + return true; } bool WebContentsDelegateAndroid::TakeFocus(WebContents* source, bool reverse) {
diff --git a/components/embedder_support/android/delegate/web_contents_delegate_android.h b/components/embedder_support/android/delegate/web_contents_delegate_android.h index 8a48fab..fbb08794 100644 --- a/components/embedder_support/android/delegate/web_contents_delegate_android.h +++ b/components/embedder_support/android/delegate/web_contents_delegate_android.h
@@ -97,7 +97,7 @@ int32_t line_no, const base::string16& source_id) override; void UpdateTargetURL(content::WebContents* source, const GURL& url) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; bool TakeFocus(content::WebContents* source, bool reverse) override;
diff --git a/components/feed/content/feed_offline_host.cc b/components/feed/content/feed_offline_host.cc index e3bebb6..ff8616f1 100644 --- a/components/feed/content/feed_offline_host.cc +++ b/components/feed/content/feed_offline_host.cc
@@ -11,6 +11,7 @@ #include "base/metrics/histogram_macros.h" #include "base/threading/thread_task_runner_handle.h" #include "components/feed/core/feed_scheduler_host.h" +#include "components/offline_pages/core/client_namespace_constants.h" #include "components/offline_pages/core/prefetch/prefetch_service.h" #include "url/gurl.h" @@ -53,12 +54,26 @@ void OnGetPages(std::string feed_url, const std::vector<OfflinePageItem>& pages) { if (!pages.empty()) { - OfflinePageItem newest = + OfflinePageItem best = *std::max_element(pages.begin(), pages.end(), [](auto lhs, auto rhs) { - return lhs.creation_time < rhs.creation_time; + // Prefer prefetched articles over any other. They are typically of + // higher quality. + bool leftIsPrefetch = lhs.client_id.name_space == + offline_pages::kSuggestedArticlesNamespace; + bool rightIsPrefetch = rhs.client_id.name_space == + offline_pages::kSuggestedArticlesNamespace; + if (leftIsPrefetch != rightIsPrefetch) { + // Only one is prefetch, if that is |rhs|, then they're in the + // correct order. + return rightIsPrefetch; + } else { + // Newer articles are also better, but not as important as being + // prefetched. + return lhs.creation_time < rhs.creation_time; + } }); urls_.push_back(feed_url); - on_each_result_.Run(std::move(feed_url), newest.offline_id); + on_each_result_.Run(feed_url, best.offline_id); } }
diff --git a/components/feed/content/feed_offline_host_unittest.cc b/components/feed/content/feed_offline_host_unittest.cc index 5a7da1e5..6d03c13 100644 --- a/components/feed/content/feed_offline_host_unittest.cc +++ b/components/feed/content/feed_offline_host_unittest.cc
@@ -15,6 +15,7 @@ #include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "components/feed/core/content_metadata.h" +#include "components/offline_pages/core/client_namespace_constants.h" #include "components/offline_pages/core/offline_page_item.h" #include "components/offline_pages/core/offline_page_types.h" #include "components/offline_pages/core/prefetch/stub_prefetch_service.h" @@ -52,12 +53,14 @@ void AddOfflinedPage(const std::string& url, const std::string& original_url, int64_t offline_id, - base::Time creation_time) { + base::Time creation_time, + std::string name_space) { OfflinePageItem item; item.url = GURL(url); item.original_url = GURL(original_url); item.offline_id = offline_id; item.creation_time = creation_time; + item.client_id = offline_pages::ClientId(name_space, ""); url_to_offline_page_item_.emplace(url, item); if (!original_url.empty()) { url_to_offline_page_item_.emplace(original_url, item); @@ -65,7 +68,7 @@ } void AddOfflinedPage(const std::string& url, int64_t offline_id) { - AddOfflinedPage(url, "", offline_id, base::Time()); + AddOfflinedPage(url, "", offline_id, base::Time(), ""); } MOCK_METHOD1(AddObserver, void(Observer*)); @@ -233,7 +236,7 @@ } TEST_F(FeedOfflineHostTest, GetOfflineIdOriginalUrl) { - offline_page_model()->AddOfflinedPage(kUrl1, kUrl2, 4, base::Time()); + offline_page_model()->AddOfflinedPage(kUrl1, kUrl2, 4, base::Time(), ""); std::vector<std::string> actual; host()->GetOfflineStatus({kUrl2}, base::BindOnce(&CopyStatus, &actual)); @@ -246,7 +249,7 @@ } TEST_F(FeedOfflineHostTest, GetOfflineIdRequestUrl) { - offline_page_model()->AddOfflinedPage(kUrl2, kUrl1, 4, base::Time()); + offline_page_model()->AddOfflinedPage(kUrl2, kUrl1, 4, base::Time(), ""); std::vector<std::string> actual; host()->GetOfflineStatus({kUrl2}, base::BindOnce(&CopyStatus, &actual)); @@ -259,9 +262,9 @@ } TEST_F(FeedOfflineHostTest, GetOfflineIdNewer) { - offline_page_model()->AddOfflinedPage(kUrl1, "", 4, base::Time()); + offline_page_model()->AddOfflinedPage(kUrl1, "", 4, base::Time(), ""); offline_page_model()->AddOfflinedPage( - kUrl1, "", 5, base::Time() + base::TimeDelta::FromHours(1)); + kUrl1, "", 5, base::Time() + base::TimeDelta::FromHours(1), ""); std::vector<std::string> actual; host()->GetOfflineStatus({kUrl1}, base::BindOnce(&CopyStatus, &actual)); @@ -272,6 +275,23 @@ EXPECT_EQ(host()->GetOfflineId(kUrl1).value(), 5); } +TEST_F(FeedOfflineHostTest, GetOfflineIdNamespace) { + // Even though id of 5 is newer, id of 4 will be chosen because it has the + // preferred namespace. + offline_page_model()->AddOfflinedPage( + kUrl1, "", 4, base::Time(), offline_pages::kSuggestedArticlesNamespace); + offline_page_model()->AddOfflinedPage( + kUrl1, "", 5, base::Time() + base::TimeDelta::FromHours(1), ""); + + std::vector<std::string> actual; + host()->GetOfflineStatus({kUrl1}, base::BindOnce(&CopyStatus, &actual)); + RunUntilIdle(); + + EXPECT_EQ(1U, actual.size()); + EXPECT_EQ(kUrl1, actual[0]); + EXPECT_EQ(host()->GetOfflineId(kUrl1).value(), 4); +} + TEST_F(FeedOfflineHostTest, GetCurrentArticleSuggestions) { std::vector<PrefetchSuggestion> actual; host()->GetCurrentArticleSuggestions(
diff --git a/components/guest_view/browser/guest_view_base.cc b/components/guest_view/browser/guest_view_base.cc index 2c02354e..6d796a7 100644 --- a/components/guest_view/browser/guest_view_base.cc +++ b/components/guest_view/browser/guest_view_base.cc
@@ -632,15 +632,15 @@ embedder_web_contents()->GetDelegate()->ContentsZoomChange(zoom_in); } -void GuestViewBase::HandleKeyboardEvent( +bool GuestViewBase::HandleKeyboardEvent( WebContents* source, const content::NativeWebKeyboardEvent& event) { if (!attached()) - return; + return false; // Send the keyboard events back to the embedder to reprocess them. - embedder_web_contents()->GetDelegate()-> - HandleKeyboardEvent(embedder_web_contents(), event); + return embedder_web_contents()->GetDelegate()->HandleKeyboardEvent( + embedder_web_contents(), event); } void GuestViewBase::LoadingStateChanged(WebContents* source,
diff --git a/components/guest_view/browser/guest_view_base.h b/components/guest_view/browser/guest_view_base.h index 0fb2510..64410d68 100644 --- a/components/guest_view/browser/guest_view_base.h +++ b/components/guest_view/browser/guest_view_base.h
@@ -220,7 +220,7 @@ virtual void OnRenderFrameHostDeleted(int process_id, int routing_id); // WebContentsDelegate implementation. - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; bool PreHandleGestureEvent(content::WebContents* source,
diff --git a/components/image_fetcher/core/BUILD.gn b/components/image_fetcher/core/BUILD.gn index aaf75d16..374aa67 100644 --- a/components/image_fetcher/core/BUILD.gn +++ b/components/image_fetcher/core/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "cached_image_fetcher.cc", "cached_image_fetcher.h", + "cached_image_fetcher_service.cc", + "cached_image_fetcher_service.h", "image_data_fetcher.cc", "image_data_fetcher.h", "image_decoder.h", @@ -22,6 +24,7 @@ public_deps = [ "//base", "//components/data_use_measurement/core", + "//components/keyed_service/core", "//net", "//services/network/public/cpp", "//ui/gfx",
diff --git a/components/image_fetcher/core/DEPS b/components/image_fetcher/core/DEPS index ab5ae2fd..030417a3 100644 --- a/components/image_fetcher/core/DEPS +++ b/components/image_fetcher/core/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/keyed_service", "+components/leveldb_proto", "+components/prefs", "+ui/gfx/codec",
diff --git a/components/image_fetcher/core/cached_image_fetcher.cc b/components/image_fetcher/core/cached_image_fetcher.cc index 437b066..9811a518 100644 --- a/components/image_fetcher/core/cached_image_fetcher.cc +++ b/components/image_fetcher/core/cached_image_fetcher.cc
@@ -7,6 +7,8 @@ #include <utility> #include "base/bind.h" +#include "base/metrics/histogram_macros.h" +#include "base/timer/elapsed_timer.h" #include "components/image_fetcher/core/image_decoder.h" #include "components/image_fetcher/core/request_metadata.h" #include "components/image_fetcher/core/storage/image_cache.h" @@ -19,6 +21,13 @@ namespace { +// Tracks the various forms of timing events. +enum class LoadTimeType { + kLoadFromCache = 0, + kLoadFromNetwork = 1, + kLoadFromNetworkAfterCacheHit = 2 +}; + void DataCallbackIfPresent(ImageDataFetcherCallback data_callback, const std::string& image_data, const image_fetcher::RequestMetadata& metadata) { @@ -51,13 +60,36 @@ std::vector<gfx::PNGCodec::Comment>(), dest); } +void ReportLoadTime(LoadTimeType type, base::Time start_time) { + base::TimeDelta time_delta = base::Time::Now() - start_time; + switch (type) { + case LoadTimeType::kLoadFromCache: + UMA_HISTOGRAM_TIMES("CachedImageFetcher.ImageLoadFromCacheTime", + time_delta); + break; + case LoadTimeType::kLoadFromNetwork: + UMA_HISTOGRAM_TIMES("CachedImageFetcher.ImageLoadFromNetworkTime", + time_delta); + break; + case LoadTimeType::kLoadFromNetworkAfterCacheHit: + UMA_HISTOGRAM_TIMES( + "CachedImageFetcher.ImageLoadFromNetworkAfterCacheHit", time_delta); + break; + } +} + } // namespace +// static +void CachedImageFetcher::ReportEvent(CachedImageFetcherEvent event) { + UMA_HISTOGRAM_ENUMERATION("CachedImageFetcher.Events", event); +} + CachedImageFetcher::CachedImageFetcher( std::unique_ptr<ImageFetcher> image_fetcher, - std::unique_ptr<ImageCache> image_cache) + scoped_refptr<ImageCache> image_cache) : image_fetcher_(std::move(image_fetcher)), - image_cache_(std::move(image_cache)), + image_cache_(image_cache), weak_ptr_factory_(this) { DCHECK(image_fetcher_); DCHECK(image_cache_); @@ -94,12 +126,15 @@ image_cache_->LoadImage( image_url.spec(), base::BindOnce(&CachedImageFetcher::OnImageFetchedFromCache, - weak_ptr_factory_.GetWeakPtr(), id, image_url, - std::move(data_callback), std::move(image_callback), - traffic_annotation)); + weak_ptr_factory_.GetWeakPtr(), base::Time::Now(), id, + image_url, std::move(data_callback), + std::move(image_callback), traffic_annotation)); + + ReportEvent(CachedImageFetcherEvent::kImageRequest); } void CachedImageFetcher::OnImageFetchedFromCache( + base::Time start_time, const std::string& id, const GURL& image_url, ImageDataFetcherCallback data_callback, @@ -108,21 +143,28 @@ std::string image_data) { if (image_data.empty()) { // Fetching from the DB failed, start a network fetch. - FetchImageFromNetwork(id, image_url, std::move(data_callback), - std::move(image_callback), traffic_annotation); + FetchImageFromNetwork(/* cache_hit */ false, start_time, id, image_url, + std::move(data_callback), std::move(image_callback), + traffic_annotation); + + ReportEvent(CachedImageFetcherEvent::kCacheMiss); } else { + DataCallbackIfPresent(std::move(data_callback), image_data, + RequestMetadata()); // TODO(wylieb): On Android, do this in-process. GetImageDecoder()->DecodeImage( image_data, desired_image_frame_size_, base::BindRepeating(&CachedImageFetcher::OnImageDecodedFromCache, - weak_ptr_factory_.GetWeakPtr(), id, image_url, - base::Passed(std::move(data_callback)), + weak_ptr_factory_.GetWeakPtr(), start_time, id, + image_url, base::Passed(std::move(data_callback)), base::Passed(std::move(image_callback)), traffic_annotation, image_data)); + ReportEvent(CachedImageFetcherEvent::kCacheHit); } } void CachedImageFetcher::OnImageDecodedFromCache( + base::Time start_time, const std::string& id, const GURL& image_url, ImageDataFetcherCallback data_callback, @@ -131,19 +173,22 @@ const std::string& image_data, const gfx::Image& image) { if (image.IsEmpty()) { - FetchImageFromNetwork(id, image_url, std::move(data_callback), - std::move(image_callback), traffic_annotation); - // Decoding error, delete image from cache. - image_cache_->DeleteImage(image_url.spec()); + // Upon failure, fetch from the network. + FetchImageFromNetwork(/* cache_hit */ true, start_time, id, image_url, + std::move(data_callback), std::move(image_callback), + traffic_annotation); + + ReportEvent(CachedImageFetcherEvent::kCacheDecodingError); } else { - DataCallbackIfPresent(std::move(data_callback), image_data, - RequestMetadata()); ImageCallbackIfPresent(std::move(image_callback), id, image, RequestMetadata()); + ReportLoadTime(LoadTimeType::kLoadFromCache, start_time); } } void CachedImageFetcher::FetchImageFromNetwork( + bool cache_hit, + base::Time start_time, const std::string& id, const GURL& image_url, ImageDataFetcherCallback data_callback, @@ -153,16 +198,20 @@ // the image cache, and the image will be returned to the caller. image_fetcher_->FetchImageAndData( id, image_url, - base::BindOnce(&CachedImageFetcher::OnImageDataFetchedFromNetwork, + base::BindOnce(&CachedImageFetcher::DecodeDataForCaching, weak_ptr_factory_.GetWeakPtr(), std::move(data_callback), image_url), base::BindOnce(&CachedImageFetcher::OnImageFetchedFromNetwork, - weak_ptr_factory_.GetWeakPtr(), std::move(image_callback)), + weak_ptr_factory_.GetWeakPtr(), cache_hit, start_time, + std::move(image_callback), image_url), traffic_annotation); } void CachedImageFetcher::OnImageFetchedFromNetwork( + bool cache_hit, + base::Time start_time, ImageFetcherCallback image_callback, + const GURL& image_url, const std::string& id, const gfx::Image& image, const RequestMetadata& request_metadata) { @@ -170,9 +219,19 @@ // caller. ImageCallbackIfPresent(std::move(image_callback), id, image, request_metadata); + + // Report failure if the image is empty. + if (image.IsEmpty()) { + ReportEvent(CachedImageFetcherEvent::kFailure); + } + + // Report to different histograms depending upon if there was a cache hit. + ReportLoadTime(cache_hit ? LoadTimeType::kLoadFromNetworkAfterCacheHit + : LoadTimeType::kLoadFromNetwork, + start_time); } -void CachedImageFetcher::OnImageDataFetchedFromNetwork( +void CachedImageFetcher::DecodeDataForCaching( ImageDataFetcherCallback data_callback, const GURL& image_url, const std::string& image_data, @@ -180,14 +239,19 @@ DataCallbackIfPresent(std::move(data_callback), image_data, request_metadata); GetImageDecoder()->DecodeImage( image_data, /* Decoding for cache shouldn't specify size */ gfx::Size(), - base::BindRepeating(&CachedImageFetcher::OnImageDecodedFromNetwork, + base::BindRepeating(&CachedImageFetcher::EncodeDataAndCache, weak_ptr_factory_.GetWeakPtr(), image_url)); } -void CachedImageFetcher::OnImageDecodedFromNetwork(const GURL& image_url, - const gfx::Image& image) { +void CachedImageFetcher::EncodeDataAndCache(const GURL& image_url, + const gfx::Image& image) { std::vector<unsigned char> encoded_data; - if (!EncodeSkBitmapToPNG(*image.ToSkBitmap(), &encoded_data)) { + // If the image is empty, or there's a problem encoding the image, don't save + // it. + if (image.IsEmpty() || + !EncodeSkBitmapToPNG(*image.ToSkBitmap(), &encoded_data)) { + ReportEvent(CachedImageFetcherEvent::kTranscodingError); + image_cache_->DeleteImage(image_url.spec()); return; }
diff --git a/components/image_fetcher/core/cached_image_fetcher.h b/components/image_fetcher/core/cached_image_fetcher.h index 1b3ebe0..1ce56c40 100644 --- a/components/image_fetcher/core/cached_image_fetcher.h +++ b/components/image_fetcher/core/cached_image_fetcher.h
@@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "base/containers/flat_map.h" #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" #include "components/image_fetcher/core/image_decoder.h" @@ -29,14 +30,31 @@ class ImageFetcher; struct RequestMetadata; +// Enum for the result of the fetch, reported through UMA Present in enums.xml +// as CachedImageFetcherEvent. New values should be added at the end and things +// should not be renumbered. +enum class CachedImageFetcherEvent { + kImageRequest = 0, + kCacheHit = 1, + kCacheMiss = 2, + kCacheDecodingError = 3, + kTranscodingError = 4, + kFailure = 5, + kMaxValue = kFailure, +}; + // TODO(wylieb): Transcode the image once it's downloaded. // TODO(wylieb): Consider creating a struct to encapsulate the request. // CachedImageFetcher takes care of fetching images from the network and caching // them. class CachedImageFetcher : public ImageFetcher { public: + // Report CachedImageFetcher events, used by sub-systems to report events (as + // well as CachedImageFetcher). + static void ReportEvent(CachedImageFetcherEvent event); + CachedImageFetcher(std::unique_ptr<ImageFetcher> image_fetcher, - std::unique_ptr<ImageCache> image_cache); + scoped_refptr<ImageCache> image_cache); ~CachedImageFetcher() override; // ImageFetcher: @@ -55,6 +73,7 @@ private: // Cache void OnImageFetchedFromCache( + base::Time start_time, const std::string& id, const GURL& image_url, ImageDataFetcherCallback image_data_callback, @@ -62,6 +81,7 @@ const net::NetworkTrafficAnnotationTag& traffic_annotation, std::string image_data); void OnImageDecodedFromCache( + base::Time start_time, const std::string& id, const GURL& image_url, ImageDataFetcherCallback image_data_callback, @@ -72,25 +92,31 @@ // Network void FetchImageFromNetwork( + bool cache_hit, + base::Time start_time, const std::string& id, const GURL& image_url, ImageDataFetcherCallback image_data_callback, ImageFetcherCallback image_callback, const net::NetworkTrafficAnnotationTag& traffic_annotation); - void OnImageFetchedFromNetwork(ImageFetcherCallback image_callback, + void OnImageFetchedFromNetwork(bool cache_hit, + base::Time start_time, + ImageFetcherCallback image_callback, + const GURL& image_url, const std::string& id, const gfx::Image& image, const RequestMetadata& request_metadata); - void OnImageDataFetchedFromNetwork( - ImageDataFetcherCallback image_data_callback, - const GURL& image_url, - const std::string& image_data, - const RequestMetadata& request_metadata); - void OnImageDecodedFromNetwork(const GURL& image_url, - const gfx::Image& image); + void DecodeDataForCaching(ImageDataFetcherCallback image_data_callback, + const GURL& image_url, + const std::string& image_data, + const RequestMetadata& request_metadata); + void EncodeDataAndCache(const GURL& image_url, const gfx::Image& image); + // ImageFetcher has some state that's stored, so it's owned by + // CachedImageFetcher. std::unique_ptr<ImageFetcher> image_fetcher_; - std::unique_ptr<ImageCache> image_cache_; + + scoped_refptr<ImageCache> image_cache_; gfx::Size desired_image_frame_size_;
diff --git a/components/image_fetcher/core/cached_image_fetcher_service.cc b/components/image_fetcher/core/cached_image_fetcher_service.cc new file mode 100644 index 0000000..af3d9d7 --- /dev/null +++ b/components/image_fetcher/core/cached_image_fetcher_service.cc
@@ -0,0 +1,37 @@ +// Copyright 2018 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/image_fetcher/core/cached_image_fetcher_service.h" + +#include <utility> + +#include "base/time/clock.h" +#include "components/image_fetcher/core/cached_image_fetcher.h" +#include "components/image_fetcher/core/image_decoder.h" +#include "components/image_fetcher/core/image_fetcher_impl.h" +#include "components/image_fetcher/core/storage/image_cache.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" + +namespace image_fetcher { + +CachedImageFetcherService::CachedImageFetcherService( + CreateImageDecoderCallback create_image_decoder_fn, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + scoped_refptr<ImageCache> image_cache) + : create_image_decoder_callback_(create_image_decoder_fn), + url_loader_factory_(url_loader_factory), + image_cache_(image_cache) {} + +CachedImageFetcherService::~CachedImageFetcherService() = default; + +// TODO(wylieb): Store CachedImageFetcher once it's stateless. +std::unique_ptr<CachedImageFetcher> +CachedImageFetcherService::CreateCachedImageFetcher() { + return std::make_unique<CachedImageFetcher>( + std::make_unique<ImageFetcherImpl>(create_image_decoder_callback_.Run(), + url_loader_factory_), + image_cache_); +} + +} // namespace image_fetcher
diff --git a/components/image_fetcher/core/cached_image_fetcher_service.h b/components/image_fetcher/core/cached_image_fetcher_service.h new file mode 100644 index 0000000..e337ebdf --- /dev/null +++ b/components/image_fetcher/core/cached_image_fetcher_service.h
@@ -0,0 +1,52 @@ +// Copyright 2018 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_IMAGE_FETCHER_CORE_CACHED_IMAGE_FETCHER_SERVICE_H_ +#define COMPONENTS_IMAGE_FETCHER_CORE_CACHED_IMAGE_FETCHER_SERVICE_H_ + +#include <memory> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "components/keyed_service/core/keyed_service.h" + +namespace network { +class SharedURLLoaderFactory; +} // namespace network + +namespace image_fetcher { + +class CachedImageFetcher; +class ImageCache; +class ImageDecoder; + +using CreateImageDecoderCallback = + base::RepeatingCallback<std::unique_ptr<ImageDecoder>()>; + +// Keyed service responsible for managing the lifetime of CachedImageFetcher. +// Persists the ImageCache, and uses it to create instances of the +// CachedImageFethcer. +class CachedImageFetcherService : public KeyedService { + public: + explicit CachedImageFetcherService( + CreateImageDecoderCallback create_image_decoder_callback, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + scoped_refptr<ImageCache> image_cache); + ~CachedImageFetcherService() override; + + // Create an instance of CachedImageFetcher based on the ImageCache. + std::unique_ptr<CachedImageFetcher> CreateCachedImageFetcher(); + + private: + CreateImageDecoderCallback create_image_decoder_callback_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; + scoped_refptr<ImageCache> image_cache_; + + DISALLOW_COPY_AND_ASSIGN(CachedImageFetcherService); +}; + +} // namespace image_fetcher + +#endif // COMPONENTS_IMAGE_FETCHER_CORE_CACHED_IMAGE_FETCHER_SERVICE_H_
diff --git a/components/image_fetcher/core/cached_image_fetcher_unittest.cc b/components/image_fetcher/core/cached_image_fetcher_unittest.cc index 76bc141..683b4be0 100644 --- a/components/image_fetcher/core/cached_image_fetcher_unittest.cc +++ b/components/image_fetcher/core/cached_image_fetcher_unittest.cc
@@ -12,6 +12,8 @@ #include "base/bind.h" #include "base/files/scoped_temp_dir.h" +#include "base/memory/ref_counted.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" #include "base/test/scoped_task_environment.h" #include "base/test/simple_test_clock.h" @@ -46,6 +48,15 @@ const GURL kImageUrl = GURL("http://gstatic.img.com/foo.jpg"); constexpr char kImageData[] = "data"; +const char kCachedImageFetcherEventHistogramName[] = + "CachedImageFetcher.Events"; +const char kCacheLoadHistogramName[] = + "CachedImageFetcher.ImageLoadFromCacheTime"; +const char kNetworkLoadHistogramName[] = + "CachedImageFetcher.ImageLoadFromNetworkTime"; +const char kNetworkLoadAfterCacheHitHistogram[] = + "CachedImageFetcher.ImageLoadFromNetworkAfterCacheHit"; + } // namespace class ComponentizedCachedImageFetcherTest : public testing::Test { @@ -72,10 +83,9 @@ data_dir_.GetPath(), base::SequencedTaskRunnerHandle::Get()); ImageCache::RegisterProfilePrefs(test_prefs_.registry()); - auto image_cache = std::make_unique<ImageCache>( + image_cache_ = base::MakeRefCounted<ImageCache>( std::move(data_store), std::move(metadata_store), &test_prefs_, &clock_, base::SequencedTaskRunnerHandle::Get()); - image_cache_ = image_cache.get(); image_cache_->SaveImage(kImageUrl.spec(), kImageData); RunUntilIdle(); @@ -93,7 +103,7 @@ cached_image_fetcher_ = std::make_unique<CachedImageFetcher>( std::make_unique<image_fetcher::ImageFetcherImpl>(std::move(decoder), shared_factory_), - std::move(image_cache)); + image_cache_); RunUntilIdle(); } @@ -103,11 +113,12 @@ CachedImageFetcher* cached_image_fetcher() { return cached_image_fetcher_.get(); } - ImageCache* image_cache() { return image_cache_; } + scoped_refptr<ImageCache> image_cache() { return image_cache_; } FakeImageDecoder* image_decoder() { return fake_image_decoder_; } network::TestURLLoaderFactory* test_url_loader_factory() { return &test_url_loader_factory_; } + base::HistogramTester& histogram_tester() { return histogram_tester_; } MOCK_METHOD1(OnImageLoaded, void(std::string)); @@ -117,7 +128,7 @@ scoped_refptr<network::SharedURLLoaderFactory> shared_factory_; FakeImageDecoder* fake_image_decoder_; - ImageCache* image_cache_; + scoped_refptr<ImageCache> image_cache_; base::SimpleTestClock clock_; TestingPrefServiceSimple test_prefs_; base::ScopedTempDir data_dir_; @@ -125,6 +136,7 @@ std::map<std::string, CachedImageMetadataProto> metadata_store_; base::test::ScopedTaskEnvironment scoped_task_environment_; + base::HistogramTester histogram_tester_; DISALLOW_COPY_AND_ASSIGN(ComponentizedCachedImageFetcherTest); }; @@ -158,6 +170,13 @@ TRAFFIC_ANNOTATION_FOR_TESTS); RunUntilIdle(); + + histogram_tester().ExpectTotalCount(kCacheLoadHistogramName, 1); + histogram_tester().ExpectBucketCount(kCachedImageFetcherEventHistogramName, + CachedImageFetcherEvent::kImageRequest, + 1); + histogram_tester().ExpectBucketCount(kCachedImageFetcherEventHistogramName, + CachedImageFetcherEvent::kCacheHit, 1); } TEST_F(ComponentizedCachedImageFetcherTest, FetchImagePopulatesCache) { @@ -175,6 +194,14 @@ TRAFFIC_ANNOTATION_FOR_TESTS); RunUntilIdle(); + + histogram_tester().ExpectTotalCount(kNetworkLoadHistogramName, 1); + histogram_tester().ExpectBucketCount(kCachedImageFetcherEventHistogramName, + CachedImageFetcherEvent::kImageRequest, + 1); + histogram_tester().ExpectBucketCount(kCachedImageFetcherEventHistogramName, + CachedImageFetcherEvent::kCacheMiss, + 1); } // Make sure the image data is in the database. { @@ -202,30 +229,26 @@ } } -TEST_F(ComponentizedCachedImageFetcherTest, DecodingErrorWillDeleteCache) { +TEST_F(ComponentizedCachedImageFetcherTest, FetchDecodingErrorDeletesCache) { // Save the image in the database. image_cache()->SaveImage(kImageUrl.spec(), kImageData); RunUntilIdle(); - { - // Set decoding always error. - image_decoder()->SetDecodingValid(false); - base::MockCallback<ImageFetcherCallback> image_callback; - cached_image_fetcher()->FetchImage(kImageUrl.spec(), kImageUrl, - image_callback.Get(), - TRAFFIC_ANNOTATION_FOR_TESTS); + image_decoder()->SetDecodingValid(false); + base::MockCallback<ImageDataFetcherCallback> data_callback; + base::MockCallback<ImageFetcherCallback> image_callback; + EXPECT_CALL(data_callback, Run(NonEmptyString(), _)); + EXPECT_CALL(image_callback, Run(kImageUrl.spec(), EmptyImage(), _)); + test_url_loader_factory()->AddResponse(kImageUrl.spec(), kImageData); + cached_image_fetcher()->FetchImageAndData( + kImageUrl.spec(), kImageUrl, data_callback.Get(), image_callback.Get(), + TRAFFIC_ANNOTATION_FOR_TESTS); + RunUntilIdle(); - RunUntilIdle(); - } - // Make sure the image data was deleted from database. - { - EXPECT_CALL(*this, OnImageLoaded(std::string())); - image_cache()->LoadImage( - kImageUrl.spec(), - base::BindOnce(&ComponentizedCachedImageFetcherTest::OnImageLoaded, - base::Unretained(this))); - RunUntilIdle(); - } + histogram_tester().ExpectTotalCount(kNetworkLoadAfterCacheHitHistogram, 1); + histogram_tester().ExpectBucketCount( + kCachedImageFetcherEventHistogramName, + CachedImageFetcherEvent::kTranscodingError, 1); } } // namespace image_fetcher
diff --git a/components/image_fetcher/core/storage/image_cache.h b/components/image_fetcher/core/storage/image_cache.h index de06d32..431fb1c 100644 --- a/components/image_fetcher/core/storage/image_cache.h +++ b/components/image_fetcher/core/storage/image_cache.h
@@ -7,7 +7,9 @@ #include <memory> #include <string> +#include <vector> +#include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "components/image_fetcher/core/storage/image_store_types.h" @@ -21,12 +23,13 @@ namespace image_fetcher { +class ImageCache; class ImageDataStore; class ImageMetadataStore; // Persist image meta/data via the given implementations of ImageDataStore and // ImageMetadataStore. -class ImageCache { +class ImageCache : public base::RefCounted<ImageCache> { public: static void RegisterProfilePrefs(PrefRegistrySimple* registry); @@ -35,7 +38,6 @@ PrefService* pref_service, base::Clock* clock, scoped_refptr<base::SequencedTaskRunner> task_runner); - ~ImageCache(); // Adds or updates the image data for the |url|. If the class hasn't been // initialized yet, the call is queued. @@ -50,6 +52,8 @@ private: friend class ImageCacheTest; + friend class base::RefCounted<ImageCache>; + ~ImageCache(); // Queue or start |request| depending if the cache is initialized. void QueueOrStartRequest(base::OnceClosure request);
diff --git a/components/image_fetcher/core/storage/image_cache_unittest.cc b/components/image_fetcher/core/storage/image_cache_unittest.cc index 7e5fbd7f..289c3ce5 100644 --- a/components/image_fetcher/core/storage/image_cache_unittest.cc +++ b/components/image_fetcher/core/storage/image_cache_unittest.cc
@@ -4,6 +4,9 @@ #include "components/image_fetcher/core/storage/image_cache.h" +#include <map> +#include <utility> + #include "base/files/scoped_temp_dir.h" #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" @@ -49,7 +52,7 @@ data_store_ = data_store.get(); ImageCache::RegisterProfilePrefs(test_prefs_.registry()); - image_cache_ = std::make_unique<ImageCache>( + image_cache_ = base::MakeRefCounted<ImageCache>( std::move(data_store), std::move(metadata_store), &test_prefs_, &clock_, base::SequencedTaskRunnerHandle::Get()); } @@ -116,7 +119,7 @@ MOCK_METHOD1(DataCallback, void(std::string)); private: - std::unique_ptr<ImageCache> image_cache_; + scoped_refptr<ImageCache> image_cache_; ImageMetadataStoreLevelDB* metadata_store_; ImageDataStoreDisk* data_store_; base::SimpleTestClock clock_;
diff --git a/components/metrics/call_stack_profile_metrics_provider.cc b/components/metrics/call_stack_profile_metrics_provider.cc index 36a7090..3334a8c 100644 --- a/components/metrics/call_stack_profile_metrics_provider.cc +++ b/components/metrics/call_stack_profile_metrics_provider.cc
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/no_destructor.h" #include "base/synchronization/lock.h" +#include "base/thread_annotations.h" #include "base/time/time.h" #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h" @@ -115,31 +116,32 @@ // Returns true if collection is enabled for a given profile based on its // |profile_start_time|. The |lock_| must be held prior to calling this // method. - bool IsCollectionEnabledForProfile(base::TimeTicks profile_start_time) const; + bool IsCollectionEnabledForProfile(base::TimeTicks profile_start_time) const + EXCLUSIVE_LOCKS_REQUIRED(lock_); // Whether there is spare capacity to store an additional profile. // The |lock_| must be held prior to calling this method. - bool HasSpareCapacity() const; + bool HasSpareCapacity() const EXCLUSIVE_LOCKS_REQUIRED(lock_); mutable base::Lock lock_; // If true, profiles provided to MaybeCollect*Profile should be collected. // Otherwise they will be ignored. - bool collection_enabled_; + bool collection_enabled_ GUARDED_BY(lock_); // The last time collection was disabled. Used to determine if collection was // disabled at any point since a profile was started. - base::TimeTicks last_collection_disable_time_; + base::TimeTicks last_collection_disable_time_ GUARDED_BY(lock_); // The last time collection was enabled. Used to determine if collection was // enabled at any point since a profile was started. - base::TimeTicks last_collection_enable_time_; + base::TimeTicks last_collection_enable_time_ GUARDED_BY(lock_); // The set of completed unserialized profiles that should be reported. - std::vector<SampledProfile> unserialized_profiles_; + std::vector<SampledProfile> unserialized_profiles_ GUARDED_BY(lock_); // The set of completed serialized profiles that should be reported. - std::vector<std::string> serialized_profiles_; + std::vector<std::string> serialized_profiles_ GUARDED_BY(lock_); DISALLOW_COPY_AND_ASSIGN(PendingProfiles); };
diff --git a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc index 7690cd7..ea14865 100644 --- a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc +++ b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc
@@ -254,7 +254,7 @@ for (auto& suggestion : suggestions) { urls.push_back(SuggestionToPrefetchURL(std::move(suggestion))); } - AddCandidatePrefetchURLs(kNTPSuggestionsNamespace, urls); + AddCandidatePrefetchURLs(kSuggestedArticlesNamespace, urls); } void PrefetchDispatcherImpl::StopBackgroundTask() {
diff --git a/components/omnibox/browser/omnibox_client.h b/components/omnibox/browser/omnibox_client.h index 018d609..50e7f6a 100644 --- a/components/omnibox/browser/omnibox_client.h +++ b/components/omnibox/browser/omnibox_client.h
@@ -170,6 +170,9 @@ // Discards the state for all pending and transient navigations. virtual void DiscardNonCommittedNavigations() {} + // Opens and shows a new incognito browser window. + virtual void NewIncognitoWindow() {} + // Presents translation prompt for current tab web contents. virtual void PromptPageTranslation() {} };
diff --git a/components/omnibox/browser/omnibox_pedal_implementations.cc b/components/omnibox/browser/omnibox_pedal_implementations.cc index f78276b..a650fc6 100644 --- a/components/omnibox/browser/omnibox_pedal_implementations.cc +++ b/components/omnibox/browser/omnibox_pedal_implementations.cc
@@ -149,6 +149,26 @@ // ============================================================================= +class OmniboxPedalLaunchIncognito : public OmniboxPedalCommon { + public: + OmniboxPedalLaunchIncognito() + : OmniboxPedalCommon( + LabelStrings( + IDS_OMNIBOX_PEDAL_LAUNCH_INCOGNITO_HINT, + IDS_OMNIBOX_PEDAL_LAUNCH_INCOGNITO_HINT_SHORT, + IDS_OMNIBOX_PEDAL_LAUNCH_INCOGNITO_SUGGESTION_CONTENTS), + GURL(), + { + "what is incognito", "what's incognito mode", + }) {} + + void Execute(ExecutionContext& context) const override { + context.client_.NewIncognitoWindow(); + } +}; + +// ============================================================================= + class OmniboxPedalTranslate : public OmniboxPedalCommon { public: OmniboxPedalTranslate() @@ -182,6 +202,7 @@ add(new OmniboxPedalManagePasswords()); add(new OmniboxPedalChangeHomePage()); add(new OmniboxPedalUpdateCreditCard()); + add(new OmniboxPedalLaunchIncognito()); add(new OmniboxPedalTranslate()); return pedals; }
diff --git a/components/omnibox_strings.grdp b/components/omnibox_strings.grdp index 63156fec..42bd0a13 100644 --- a/components/omnibox_strings.grdp +++ b/components/omnibox_strings.grdp
@@ -128,6 +128,16 @@ Update credit card autofill info in Chrome settings </message> + <message name="IDS_OMNIBOX_PEDAL_LAUNCH_INCOGNITO_HINT" desc="The button text contents to suggest pedal action, launch incognito."> + Open Incognito Window + </message> + <message name="IDS_OMNIBOX_PEDAL_LAUNCH_INCOGNITO_HINT_SHORT" desc="The short one-word button text contents to suggest pedal action, launch incognito."> + Open + </message> + <message name="IDS_OMNIBOX_PEDAL_LAUNCH_INCOGNITO_SUGGESTION_CONTENTS" desc="The suggestion content text to suggest pedal action, launch incognito."> + Open new Chrome incognito window + </message> + <message name="IDS_OMNIBOX_PEDAL_TRANSLATE_HINT" desc="The button text contents to suggest pedal action, translate."> Translate Page </message>
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc index b3619af8..d9263e9c 100644 --- a/components/plugins/renderer/webview_plugin.cc +++ b/components/plugins/renderer/webview_plugin.cc
@@ -311,11 +311,6 @@ return true; } -blink::WebLayerTreeView* -WebViewPlugin::WebViewHelper::InitializeLayerTreeView() { - return nullptr; -} - void WebViewPlugin::WebViewHelper::DidInvalidateRect(const WebRect& rect) { if (plugin_->container_) plugin_->container_->InvalidateRect(rect);
diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h index 652eea6..470e115 100644 --- a/components/plugins/renderer/webview_plugin.h +++ b/components/plugins/renderer/webview_plugin.h
@@ -172,10 +172,9 @@ blink::WebDragOperationsMask, const SkBitmap&, const blink::WebPoint&) override; - // TODO(ojan): Remove this override and have this class use a non-null - // layerTreeView. + // TODO(ojan): Remove this override and have this class give a + // LayerTreeView to the WebWidget. Or stop making this a WebView? bool AllowsBrokenNullLayerTreeView() const override; - blink::WebLayerTreeView* InitializeLayerTreeView() override; void DidInvalidateRect(const blink::WebRect&) override; void DidChangeCursor(const blink::WebCursorInfo& cursor) override; void ScheduleAnimation() override;
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc index 71731e9..c888622 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -638,9 +638,6 @@ public: // blink::WebWidgetClient implementation. bool AllowsBrokenNullLayerTreeView() const override { return true; } - blink::WebLayerTreeView* InitializeLayerTreeView() override { - return nullptr; - } }; HeaderAndFooterClient frame_client; @@ -730,10 +727,9 @@ private: // blink::WebViewClient: void DidStopLoading() override; - // TODO(ojan): Remove this override and have this class use a non-null - // layerTreeView. + // TODO(ojan): Remove this override and have this class give a LayerTreeView + // to the WebWidget. bool AllowsBrokenNullLayerTreeView() const override; - blink::WebLayerTreeView* InitializeLayerTreeView() override; WebWidgetClient* WidgetClient() override { return this; } // blink::WebLocalFrameClient: @@ -891,11 +887,6 @@ return true; } -blink::WebLayerTreeView* -PrepareFrameAndViewForPrint::InitializeLayerTreeView() { - return nullptr; -} - void PrepareFrameAndViewForPrint::DidStopLoading() { DCHECK(!on_ready_.is_null()); // Don't call callback here, because it can delete |this| and WebView that is
diff --git a/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc b/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc index 7ce24ab..36b2c05 100644 --- a/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc +++ b/components/safe_browsing/browser/safe_browsing_url_checker_impl.cc
@@ -331,6 +331,8 @@ return safe_browsing::SB_THREAT_TYPE_URL_PHISHING; if (url == kChromeUISafeBrowsingMatchUnwantedUrl) return safe_browsing::SB_THREAT_TYPE_URL_UNWANTED; + if (url == kChromeUISafeBrowsingMatchBillingUrl) + return safe_browsing::SB_THREAT_TYPE_BILLING; return safe_browsing::SB_THREAT_TYPE_SAFE; }
diff --git a/components/safe_browsing/web_ui/constants.cc b/components/safe_browsing/web_ui/constants.cc index 2518ac80..08f3363 100644 --- a/components/safe_browsing/web_ui/constants.cc +++ b/components/safe_browsing/web_ui/constants.cc
@@ -10,6 +10,8 @@ const char kChromeUISafeBrowsingHost[] = "safe-browsing"; const char kSbUnderConstruction[] = "The safe browsing page is under construction."; +const char kChromeUISafeBrowsingMatchBillingUrl[] = + "chrome://safe-browsing/match?type=billing"; const char kChromeUISafeBrowsingMatchMalwareUrl[] = "chrome://safe-browsing/match?type=malware"; const char kChromeUISafeBrowsingMatchPhishingUrl[] =
diff --git a/components/safe_browsing/web_ui/constants.h b/components/safe_browsing/web_ui/constants.h index fc1cf9be..6b54de01 100644 --- a/components/safe_browsing/web_ui/constants.h +++ b/components/safe_browsing/web_ui/constants.h
@@ -10,6 +10,7 @@ extern const char kChromeUISafeBrowsingURL[]; extern const char kChromeUISafeBrowsingHost[]; extern const char kSbUnderConstruction[]; +extern const char kChromeUISafeBrowsingMatchBillingUrl[]; extern const char kChromeUISafeBrowsingMatchMalwareUrl[]; extern const char kChromeUISafeBrowsingMatchPhishingUrl[]; extern const char kChromeUISafeBrowsingMatchUnwantedUrl[];
diff --git a/components/security_interstitials/core/safe_browsing_loud_error_ui.cc b/components/security_interstitials/core/safe_browsing_loud_error_ui.cc index 8b7d2d9..a795a923 100644 --- a/components/security_interstitials/core/safe_browsing_loud_error_ui.cc +++ b/components/security_interstitials/core/safe_browsing_loud_error_ui.cc
@@ -311,7 +311,6 @@ base::DictionaryValue* load_time_data) { load_time_data->SetBoolean("phishing", false); load_time_data->SetBoolean("overridable", true); - load_time_data->SetBoolean("hide_primary_button", false); load_time_data->SetString("heading", l10n_util::GetStringUTF16(IDS_BILLING_HEADING));
diff --git a/components/sync/engine_impl/model_type_registry.cc b/components/sync/engine_impl/model_type_registry.cc index 3f192ce..0389c538 100644 --- a/components/sync/engine_impl/model_type_registry.cc +++ b/components/sync/engine_impl/model_type_registry.cc
@@ -9,6 +9,7 @@ #include <utility> #include "base/bind.h" +#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/observer_list.h" #include "base/threading/sequenced_task_runner_handle.h" @@ -126,7 +127,9 @@ if (do_migration) { // TODO(crbug.com/658002): Store a pref before attempting migration // indicating that it was attempted so we can avoid failure loops. - if (uss_migrator_.Run(type, user_share_, worker_ptr)) { + int migrated_entity_count = 0; + if (uss_migrator_.Run(type, user_share_, worker_ptr, + &migrated_entity_count)) { // TODO(wychen): enum uma should be strongly typed. crbug.com/661401 UMA_HISTOGRAM_ENUMERATION("Sync.USSMigrationSuccess", ModelTypeToHistogramInt(type), @@ -141,6 +144,12 @@ ModelTypeToHistogramInt(type), static_cast<int>(MODEL_TYPE_COUNT)); } + + // Note that a partial failure may still contribute to the counts histogram. + base::UmaHistogramCounts100000( + std::string("Sync.USSMigrationEntityCount.") + + ModelTypeToHistogramSuffix(type), + migrated_entity_count); } // We want to check that we haven't accidentally enabled both the non-blocking
diff --git a/components/sync/engine_impl/model_type_registry_unittest.cc b/components/sync/engine_impl/model_type_registry_unittest.cc index f2aa337..ba2d712 100644 --- a/components/sync/engine_impl/model_type_registry_unittest.cc +++ b/components/sync/engine_impl/model_type_registry_unittest.cc
@@ -92,7 +92,8 @@ private: bool MigrateDirectory(ModelType type, UserShare* user_share, - ModelTypeWorker* worker) { + ModelTypeWorker* worker, + int* migrated_entity_count) { migration_attempted_ = true; return true; }
diff --git a/components/sync/engine_impl/uss_migrator.cc b/components/sync/engine_impl/uss_migrator.cc index 9e1e69b..057268f 100644 --- a/components/sync/engine_impl/uss_migrator.cc +++ b/components/sync/engine_impl/uss_migrator.cc
@@ -84,18 +84,11 @@ } } -} // namespace - -bool MigrateDirectoryData(ModelType type, - UserShare* user_share, - ModelTypeWorker* worker) { - return MigrateDirectoryDataWithBatchSize(type, user_share, worker, 64); -} - bool MigrateDirectoryDataWithBatchSize(ModelType type, + int batch_size, UserShare* user_share, ModelTypeWorker* worker, - int batch_size) { + int* cumulative_migrated_entity_count) { DCHECK_NE(PASSWORDS, type); ReadTransaction trans(FROM_HERE, user_share); @@ -143,6 +136,7 @@ } } + *cumulative_migrated_entity_count += entity_ptrs.size(); worker->ProcessGetUpdatesResponse(progress, context, entity_ptrs, nullptr); } @@ -150,4 +144,25 @@ return true; } +} // namespace + +bool MigrateDirectoryData(ModelType type, + UserShare* user_share, + ModelTypeWorker* worker, + int* migrated_entity_count) { + *migrated_entity_count = 0; + return MigrateDirectoryDataWithBatchSize(type, 64, user_share, worker, + migrated_entity_count); +} + +bool MigrateDirectoryDataWithBatchSizeForTesting( + ModelType type, + int batch_size, + UserShare* user_share, + ModelTypeWorker* worker, + int* cumulative_migrated_entity_count) { + return MigrateDirectoryDataWithBatchSize(type, batch_size, user_share, worker, + cumulative_migrated_entity_count); +} + } // namespace syncer
diff --git a/components/sync/engine_impl/uss_migrator.h b/components/sync/engine_impl/uss_migrator.h index 84a6fd2d..ee9e81e 100644 --- a/components/sync/engine_impl/uss_migrator.h +++ b/components/sync/engine_impl/uss_migrator.h
@@ -13,21 +13,25 @@ class ModelTypeWorker; struct UserShare; -using UssMigrator = - base::Callback<bool(ModelType, UserShare*, ModelTypeWorker*)>; +using UssMigrator = base::RepeatingCallback< + bool(ModelType, UserShare*, ModelTypeWorker*, int*)>; // Pulls all the data for |type| out of the directory and sends it to |worker| // as the result of an initial GetUpdates. Returns whether migration succeeded. +// |user_share|, |worker| and |migrated_entity_count| must not be null. bool MigrateDirectoryData(ModelType type, UserShare* user_share, - ModelTypeWorker* worker); + ModelTypeWorker* worker, + int* migrated_entity_count); // A version of the above with |batch_size| as a parameter so it can be lowered // for unit testing. -bool MigrateDirectoryDataWithBatchSize(ModelType type, - UserShare* user_share, - ModelTypeWorker* worker, - int batch_size); +bool MigrateDirectoryDataWithBatchSizeForTesting( + ModelType type, + int batch_size, + UserShare* user_share, + ModelTypeWorker* worker, + int* cumulative_migrated_entity_count); } // namespace syncer
diff --git a/components/sync/engine_impl/uss_migrator_unittest.cc b/components/sync/engine_impl/uss_migrator_unittest.cc index ba54e7f9..936f855 100644 --- a/components/sync/engine_impl/uss_migrator_unittest.cc +++ b/components/sync/engine_impl/uss_migrator_unittest.cc
@@ -117,14 +117,17 @@ SetProgressMarkerToken(kToken1); int64_t metahandle = InsertEntity(kTag1, kValue1); base::Time ctime = GetCtimeForEntity(metahandle); + int migrated_entity_count; - ASSERT_TRUE(MigrateDirectoryData(kModelType, user_share(), worker())); + ASSERT_TRUE(MigrateDirectoryData(kModelType, user_share(), worker(), + &migrated_entity_count)); // No nudge should happen in the happy case. EXPECT_EQ(0, nudge_handler()->GetNumInitialDownloadNudges()); // One update with one entity in it. EXPECT_EQ(1U, processor()->GetNumUpdateResponses()); EXPECT_EQ(1U, processor()->GetNthUpdateResponse(0).size()); + EXPECT_EQ(1, migrated_entity_count); const sync_pb::ModelTypeState& state = processor()->GetNthUpdateState(0); EXPECT_EQ(kToken1, state.progress_marker().token()); @@ -144,16 +147,20 @@ } TEST_F(UssMigratorTest, MigrateMultiple) { + int migrated_entity_count; + CreateTypeRoot(); SetProgressMarkerToken(kToken1); InsertEntity(kTag1, kValue1); InsertEntity(kTag2, kValue2); InsertEntity(kTag3, kValue3); - ASSERT_TRUE(MigrateDirectoryData(kModelType, user_share(), worker())); + ASSERT_TRUE(MigrateDirectoryData(kModelType, user_share(), worker(), + &migrated_entity_count)); EXPECT_EQ(1U, processor()->GetNumUpdateResponses()); EXPECT_EQ(3U, processor()->GetNthUpdateResponse(0).size()); + EXPECT_EQ(3, migrated_entity_count); UpdateResponseDataList updates = processor()->GetNthUpdateResponse(0); EXPECT_EQ(kTag1, updates.at(0).entity.value().specifics.preference().name()); @@ -162,17 +169,25 @@ } TEST_F(UssMigratorTest, MigrateMultipleBatches) { + // Some arbitrary number of entities that represents entities migrated in + // previous calls to MigrateDirectoryDataWithBatchSizeForTesting(). + const int kPreviouslyMigratedEntityCount = 13; + CreateTypeRoot(); SetProgressMarkerToken(kToken1); InsertEntity(kTag1, kValue1); InsertEntity(kTag2, kValue2); InsertEntity(kTag3, kValue3); - ASSERT_TRUE( - MigrateDirectoryDataWithBatchSize(kModelType, user_share(), worker(), 2)); + int cumulative_migrated_entity_count = kPreviouslyMigratedEntityCount; + ASSERT_TRUE(MigrateDirectoryDataWithBatchSizeForTesting( + kModelType, 2, user_share(), worker(), + &cumulative_migrated_entity_count)); EXPECT_EQ(1U, processor()->GetNumUpdateResponses()); EXPECT_EQ(3U, processor()->GetNthUpdateResponse(0).size()); + EXPECT_EQ(kPreviouslyMigratedEntityCount + 3, + cumulative_migrated_entity_count); UpdateResponseDataList updates = processor()->GetNthUpdateResponse(0); EXPECT_EQ(kTag1, updates.at(0).entity.value().specifics.preference().name()); @@ -181,33 +196,45 @@ } TEST_F(UssMigratorTest, MigrateIgnoresTombstone) { + int migrated_entity_count; + CreateTypeRoot(); SetProgressMarkerToken(kToken1); DeleteEntity(kTag1); - ASSERT_TRUE(MigrateDirectoryData(kModelType, user_share(), worker())); + ASSERT_TRUE(MigrateDirectoryData(kModelType, user_share(), worker(), + &migrated_entity_count)); EXPECT_EQ(0, nudge_handler()->GetNumInitialDownloadNudges()); EXPECT_EQ(1U, processor()->GetNumUpdateResponses()); EXPECT_EQ(0U, processor()->GetNthUpdateResponse(0).size()); + EXPECT_EQ(0, migrated_entity_count); } TEST_F(UssMigratorTest, MigrateZero) { + int migrated_entity_count; + CreateTypeRoot(); SetProgressMarkerToken(kToken1); - ASSERT_TRUE(MigrateDirectoryData(kModelType, user_share(), worker())); + ASSERT_TRUE(MigrateDirectoryData(kModelType, user_share(), worker(), + &migrated_entity_count)); EXPECT_EQ(0, nudge_handler()->GetNumInitialDownloadNudges()); EXPECT_EQ(1U, processor()->GetNumUpdateResponses()); EXPECT_EQ(0U, processor()->GetNthUpdateResponse(0).size()); + EXPECT_EQ(0, migrated_entity_count); } TEST_F(UssMigratorTest, MissingTypeRoot) { + int migrated_entity_count; + EXPECT_EQ(0, nudge_handler()->GetNumInitialDownloadNudges()); - ASSERT_FALSE(MigrateDirectoryData(kModelType, user_share(), worker())); + ASSERT_FALSE(MigrateDirectoryData(kModelType, user_share(), worker(), + &migrated_entity_count)); EXPECT_EQ(1, nudge_handler()->GetNumInitialDownloadNudges()); EXPECT_EQ(0U, processor()->GetNumUpdateResponses()); + EXPECT_EQ(0, migrated_entity_count); } } // namespace syncer
diff --git a/components/ui_devtools/dom_agent.cc b/components/ui_devtools/dom_agent.cc index 203c1be..c12800a 100644 --- a/components/ui_devtools/dom_agent.cc +++ b/components/ui_devtools/dom_agent.cc
@@ -5,6 +5,8 @@ #include "components/ui_devtools/dom_agent.h" #include <memory> +#include <string> +#include <utility> #include "components/ui_devtools/devtools_server.h" #include "components/ui_devtools/root_element.h" @@ -12,7 +14,9 @@ namespace ui_devtools { -using namespace ui_devtools::protocol; +using ui_devtools::protocol::Array; +using ui_devtools::protocol::DOM::Node; +using ui_devtools::protocol::Response; DOMAgent::DOMAgent() {} @@ -25,7 +29,7 @@ return Response::OK(); } -Response DOMAgent::getDocument(std::unique_ptr<DOM::Node>* out_root) { +Response DOMAgent::getDocument(std::unique_ptr<Node>* out_root) { *out_root = BuildInitialTree(); return Response::OK(); } @@ -45,17 +49,28 @@ node_id_to_ui_element_[child->node_id()] = child; return; } - // If tree is being built, don't add child to dom tree again. - if (is_building_tree_) - return; + DCHECK(node_id_to_ui_element_.count(parent->node_id())); + auto* current_parent = parent; + while (current_parent) { + if (current_parent->is_updating()) { + // One of the parents is updating, so no need to update here. + return; + } + current_parent = current_parent->parent(); + } + + child->set_is_updating(true); + const auto& children = parent->children(); auto iter = std::find(children.begin(), children.end(), child); int prev_node_id = (iter == children.end() - 1) ? 0 : (*std::next(iter))->node_id(); frontend()->childNodeInserted(parent->node_id(), prev_node_id, BuildTreeForUIElement(child)); + + child->set_is_updating(false); } void DOMAgent::OnUIElementReordered(UIElement* parent, UIElement* child) { @@ -107,27 +122,26 @@ // TODO(mhashmi): Make ids reusable -std::unique_ptr<DOM::Node> DOMAgent::BuildNode( +std::unique_ptr<Node> DOMAgent::BuildNode( const std::string& name, std::unique_ptr<Array<std::string>> attributes, - std::unique_ptr<Array<DOM::Node>> children, + std::unique_ptr<Array<Node>> children, int node_ids) { constexpr int kDomElementNodeType = 1; - std::unique_ptr<DOM::Node> node = DOM::Node::create() - .setNodeId(node_ids) - .setBackendNodeId(node_ids) - .setNodeName(name) - .setNodeType(kDomElementNodeType) - .setAttributes(std::move(attributes)) - .build(); + std::unique_ptr<Node> node = Node::create() + .setNodeId(node_ids) + .setBackendNodeId(node_ids) + .setNodeName(name) + .setNodeType(kDomElementNodeType) + .setAttributes(std::move(attributes)) + .build(); node->setChildNodeCount(static_cast<int>(children->length())); node->setChildren(std::move(children)); return node; } -std::unique_ptr<DOM::Node> DOMAgent::BuildDomNodeFromUIElement( - UIElement* root) { - std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); +std::unique_ptr<Node> DOMAgent::BuildDomNodeFromUIElement(UIElement* root) { + std::unique_ptr<Array<Node>> children = Array<Node>::create(); for (auto* it : root->children()) children->addItem(BuildDomNodeFromUIElement(it)); @@ -135,19 +149,19 @@ std::move(children), root->node_id()); } -std::unique_ptr<DOM::Node> DOMAgent::BuildInitialTree() { - is_building_tree_ = true; - std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); +std::unique_ptr<Node> DOMAgent::BuildInitialTree() { + std::unique_ptr<Array<Node>> children = Array<Node>::create(); element_root_ = std::make_unique<RootElement>(this); + element_root_->set_is_updating(true); for (auto* child : CreateChildrenForRoot()) { children->addItem(BuildTreeForUIElement(child)); element_root_->AddChild(child); } - std::unique_ptr<DOM::Node> root_node = + std::unique_ptr<Node> root_node = BuildNode("root", nullptr, std::move(children), element_root_->node_id()); - is_building_tree_ = false; + element_root_->set_is_updating(false); return root_node; } @@ -164,7 +178,6 @@ } void DOMAgent::Reset() { - is_building_tree_ = false; element_root_.reset(); node_id_to_ui_element_.clear(); observers_.Clear();
diff --git a/components/ui_devtools/dom_agent.h b/components/ui_devtools/dom_agent.h index 3d36fae..f8135e35 100644 --- a/components/ui_devtools/dom_agent.h +++ b/components/ui_devtools/dom_agent.h
@@ -5,6 +5,11 @@ #ifndef COMPONENTS_UI_DEVTOOLS_DOM_AGENT_H_ #define COMPONENTS_UI_DEVTOOLS_DOM_AGENT_H_ +#include <memory> +#include <string> +#include <unordered_map> +#include <vector> + #include "base/observer_list.h" #include "components/ui_devtools/DOM.h" #include "components/ui_devtools/devtools_base_agent.h" @@ -44,7 +49,7 @@ void AddObserver(DOMAgentObserver* observer); void RemoveObserver(DOMAgentObserver* observer); UIElement* GetElementFromNodeId(int node_id) const; - UIElement* element_root() const { return element_root_.get(); }; + UIElement* element_root() const { return element_root_.get(); } // Returns parent id of the element with id |node_id|. Returns 0 if parent // does not exist. @@ -72,7 +77,6 @@ void RemoveDomNode(UIElement* ui_element); void Reset(); - bool is_building_tree_ = false; std::unique_ptr<UIElement> element_root_; std::unordered_map<int, UIElement*> node_id_to_ui_element_;
diff --git a/components/ui_devtools/string_util.h b/components/ui_devtools/string_util.h index 2d5004f..50995dc 100644 --- a/components/ui_devtools/string_util.h +++ b/components/ui_devtools/string_util.h
@@ -74,6 +74,19 @@ static std::unique_ptr<Value> parseJSON(const String& string); }; +// A read-only sequence of uninterpreted bytes with reference-counted storage. +// Though the templates for generating the protocol bindings reference +// this type, thus far it's not used in the Chrome layer, so we provide no +// implementation here and rely on the linker optimizing it away. If this +// changes, look to content/browser/devtools/protocol_string{.h,.cc} for +// inspiration. +class Binary { + public: + const uint8_t* data() const; + size_t size() const; + String toBase64() const; + static Binary fromBase64(const String& base64, bool* success); +}; } // namespace protocol } // namespace ui_devtools
diff --git a/components/ui_devtools/ui_element.h b/components/ui_devtools/ui_element.h index c4fd3131..5d20b5c 100644 --- a/components/ui_devtools/ui_element.h +++ b/components/ui_devtools/ui_element.h
@@ -6,6 +6,8 @@ #define COMPONENTS_UI_DEVTOOLS_UI_ELEMENT_H_ #include <memory> +#include <string> +#include <utility> #include <vector> #include "base/macros.h" @@ -28,13 +30,15 @@ class UI_DEVTOOLS_EXPORT UIElement { public: virtual ~UIElement(); - int node_id() const { return node_id_; }; + int node_id() const { return node_id_; } std::string GetTypeName() const; - UIElement* parent() const { return parent_; }; - void set_parent(UIElement* parent) { parent_ = parent; }; - UIElementDelegate* delegate() const { return delegate_; }; - UIElementType type() const { return type_; }; - const std::vector<UIElement*>& children() const { return children_; }; + UIElement* parent() const { return parent_; } + void set_parent(UIElement* parent) { parent_ = parent; } + UIElementDelegate* delegate() const { return delegate_; } + UIElementType type() const { return type_; } + const std::vector<UIElement*>& children() const { return children_; } + bool is_updating() const { return is_updating_; } + void set_is_updating(bool is_updating) { is_updating_ = is_updating; } // |child| is inserted in front of |before|. If |before| is null, it // is inserted at the end. Parent takes ownership of the added child. @@ -70,7 +74,7 @@ template <typename BackingT, typename T> static BackingT* GetBackingElement(const UIElement* element) { return T::From(element); - }; + } protected: UIElement(const UIElementType type, @@ -83,6 +87,7 @@ std::vector<UIElement*> children_; UIElement* parent_; UIElementDelegate* delegate_; + bool is_updating_ = false; DISALLOW_COPY_AND_ASSIGN(UIElement); };
diff --git a/components/ui_devtools/views/dom_agent_aura.cc b/components/ui_devtools/views/dom_agent_aura.cc index d147fb6..626c8a5e 100644 --- a/components/ui_devtools/views/dom_agent_aura.cc +++ b/components/ui_devtools/views/dom_agent_aura.cc
@@ -5,6 +5,8 @@ #include "components/ui_devtools/views/dom_agent_aura.h" #include <memory> +#include <utility> +#include <vector> #include "components/ui_devtools/devtools_server.h" #include "components/ui_devtools/root_element.h" @@ -22,7 +24,8 @@ namespace ui_devtools { namespace { -using namespace ui_devtools::protocol; +using ui_devtools::protocol::DOM::Node; +using ui_devtools::protocol::Array; // TODO(mhashmi): Make ids reusable views::Widget* GetWidgetFromWindow(gfx::NativeWindow window) { @@ -52,7 +55,7 @@ return children; } -std::unique_ptr<DOM::Node> DOMAgentAura::BuildTreeForUIElement( +std::unique_ptr<Node> DOMAgentAura::BuildTreeForUIElement( UIElement* ui_element) { if (ui_element->type() == UIElementType::WINDOW) { return BuildTreeForWindow( @@ -70,10 +73,10 @@ return nullptr; } -std::unique_ptr<DOM::Node> DOMAgentAura::BuildTreeForWindow( +std::unique_ptr<Node> DOMAgentAura::BuildTreeForWindow( UIElement* window_element_root, aura::Window* window) { - std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); + std::unique_ptr<Array<Node>> children = Array<Node>::create(); views::Widget* widget = GetWidgetFromWindow(window); if (widget) { UIElement* widget_element = @@ -89,16 +92,16 @@ children->addItem(BuildTreeForWindow(window_element, child)); window_element_root->AddChild(window_element); } - std::unique_ptr<DOM::Node> node = + std::unique_ptr<Node> node = BuildNode("Window", window_element_root->GetAttributes(), std::move(children), window_element_root->node_id()); return node; } -std::unique_ptr<DOM::Node> DOMAgentAura::BuildTreeForRootWidget( +std::unique_ptr<Node> DOMAgentAura::BuildTreeForRootWidget( UIElement* widget_element, views::Widget* widget) { - std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); + std::unique_ptr<Array<Node>> children = Array<Node>::create(); UIElement* view_element = new ViewElement(widget->GetRootView(), this, widget_element); @@ -106,24 +109,35 @@ children->addItem(BuildTreeForView(view_element, widget->GetRootView())); widget_element->AddChild(view_element); - std::unique_ptr<DOM::Node> node = + std::unique_ptr<Node> node = BuildNode("Widget", widget_element->GetAttributes(), std::move(children), widget_element->node_id()); return node; } -std::unique_ptr<DOM::Node> DOMAgentAura::BuildTreeForView( - UIElement* view_element, - views::View* view) { - std::unique_ptr<Array<DOM::Node>> children = Array<DOM::Node>::create(); +std::unique_ptr<Node> DOMAgentAura::BuildTreeForView(UIElement* view_element, + views::View* view) { + std::unique_ptr<Array<Node>> children = Array<Node>::create(); for (auto* child : view->GetChildrenInZOrder()) { - UIElement* view_element_child = new ViewElement(child, this, view_element); + // When building the subtree, a particular view could be visited multiple + // times because for each view of the subtree, we would call + // BuildTreeForView(..) on that view which causes the subtree with that view + // as root being visited again. Here we check if we already constructed the + // ViewElement and skip true. + UIElement* view_element_child = nullptr; + auto id = + view_element->FindUIElementIdForBackendElement<views::View>(child); + if (id > 0) { + view_element_child = GetElementFromNodeId(id); + } else { + view_element_child = new ViewElement(child, this, view_element); + view_element->AddChild(view_element_child); + } children->addItem(BuildTreeForView(view_element_child, child)); - view_element->AddChild(view_element_child); } - std::unique_ptr<DOM::Node> node = + std::unique_ptr<Node> node = BuildNode("View", view_element->GetAttributes(), std::move(children), view_element->node_id()); return node;
diff --git a/components/url_formatter/idn_spoof_checker.cc b/components/url_formatter/idn_spoof_checker.cc index ad4ccfd..5bdc6f5 100644 --- a/components/url_formatter/idn_spoof_checker.cc +++ b/components/url_formatter/idn_spoof_checker.cc
@@ -236,7 +236,8 @@ // - {U+050D (ԍ), U+100c (ဌ)} => g // - {U+0D1F (ട), U+0E23 (ร), U+0EA3 (ຣ), U+0EAE (ຮ)} => s // - U+1042 (၂) => j - // - {U+0437 (з), U+0499 (ҙ), U+04E1 (ӡ), U+10D5 (ვ), U+1012 (ဒ)} => 3 + // - {U+0437 (з), U+0499 (ҙ), U+04E1 (ӡ), U+1012 (ဒ), U+10D5 (ვ), + // U+10DE (პ)} => 3 // - {U+0E1A (บ), U+0E9A (ບ)} => u extra_confusable_mapper_.reset(icu::Transliterator::createFromRules( UNICODE_STRING_SIMPLE("ExtraConf"), @@ -247,7 +248,7 @@ "[мӎ] > m; [єҽҿၔ] > e; ґ > r; [ғӻ] > f;" "[ҫင] > c; ұ > y; [χҳӽӿ] > x;" "ԃ > d; [ԍဌ] > g; [ടรຣຮ] > s; ၂ > j;" - "[зҙӡვဒ] > 3; [บບ] > u"), + "[зҙӡဒვპ] > 3; [บບ] > u"), UTRANS_FORWARD, parse_error, status)); DCHECK(U_SUCCESS(status)) << "Spoofchecker initalization failed due to an error: "
diff --git a/components/url_formatter/url_formatter_unittest.cc b/components/url_formatter/url_formatter_unittest.cc index 32bb24f..361eb3ec 100644 --- a/components/url_formatter/url_formatter_unittest.cc +++ b/components/url_formatter/url_formatter_unittest.cc
@@ -552,14 +552,19 @@ L"12\x04e1" L"4567890.com", false}, + // 12ဒ4567890.com + {"xn--124567890-6s6a.com", + L"12\x1012" + L"4567890.com", + false}, // 12ვ4567890.com {"xn--124567890-we8a.com", L"12\x10D5" L"4567890.com", false}, - // 12ဒ4567890.com - {"xn--124567890-6s6a.com", - L"12\x1012" + // 12პ4567890.com + {"xn--124567890-hh8a.com", + L"12\x10DE" L"4567890.com", false}, // 123Ꮞ567890.com
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index d695eb2..06122b22a 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn
@@ -90,6 +90,7 @@ "quads/debug_border_draw_quad.h", "quads/draw_quad.cc", "quads/draw_quad.h", + "quads/frame_deadline.cc", "quads/frame_deadline.h", "quads/largest_draw_quad.cc", "quads/largest_draw_quad.h",
diff --git a/components/viz/common/quads/frame_deadline.cc b/components/viz/common/quads/frame_deadline.cc new file mode 100644 index 0000000..f5f5619b --- /dev/null +++ b/components/viz/common/quads/frame_deadline.cc
@@ -0,0 +1,43 @@ +// Copyright 2018 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/viz/common/quads/frame_deadline.h" + +#include <cinttypes> + +#include "base/strings/string_number_conversions.h" +#include "base/strings/stringprintf.h" + +namespace viz { + +base::TimeTicks FrameDeadline::ToWallTime( + base::Optional<uint32_t> default_deadline_in_frames) const { + uint32_t deadline_in_frames = deadline_in_frames_; + if (use_default_lower_bound_deadline_) { + deadline_in_frames = + std::max(deadline_in_frames, default_deadline_in_frames.value_or( + std::numeric_limits<uint32_t>::max())); + } + return frame_start_time_ + deadline_in_frames * frame_interval_; +} + +std::string FrameDeadline::ToString() const { + const base::TimeDelta start_time_delta = + frame_start_time_ - base::TimeTicks(); + return base::StringPrintf( + "FrameDeadline(start time: %" PRId64 + " ms, deadline in frames: %s, frame interval: %" PRId64 " ms)", + start_time_delta.InMilliseconds(), + use_default_lower_bound_deadline_ + ? "unresolved" + : base::UintToString(deadline_in_frames_).c_str(), + frame_interval_.InMilliseconds()); +} + +std::ostream& operator<<(std::ostream& out, + const FrameDeadline& frame_deadline) { + return out << frame_deadline.ToString(); +} + +} // namespace viz
diff --git a/components/viz/common/quads/frame_deadline.h b/components/viz/common/quads/frame_deadline.h index faa992f..eef30ed 100644 --- a/components/viz/common/quads/frame_deadline.h +++ b/components/viz/common/quads/frame_deadline.h
@@ -8,9 +8,20 @@ #include "components/viz/common/viz_common_export.h" #include "base/time/time.h" +#include "components/viz/common/frame_sinks/begin_frame_args.h" namespace viz { +// FrameDeadline is a class that represents a CompositorFrame's deadline for +// activation. The deadline consists of three components: start time, deadline +// in frames, and frame interval. All three components are stored individually +// in this class in order to allow resolution of this deadline that incorporates +// a system default deadline in the Viz service. In particular, the computation +// to translate FrameDeadline into wall time is: +// if use system default lower bound deadline: +// start time + max(deadline in frames, default deadline) * frame interval +// else: +// start time + deadline in frames * frame interval class VIZ_COMMON_EXPORT FrameDeadline { public: FrameDeadline() = default; @@ -27,6 +38,12 @@ FrameDeadline& operator=(const FrameDeadline& other) = default; + // Converts this FrameDeadline object into a wall time given a system default + // deadline in frames. + base::TimeTicks ToWallTime( + base::Optional<uint32_t> default_deadline_in_frames = + base::nullopt) const; + bool operator==(const FrameDeadline& other) const { return other.frame_start_time_ == frame_start_time_ && other.deadline_in_frames_ == deadline_in_frames_ && @@ -49,13 +66,18 @@ return use_default_lower_bound_deadline_; } + std::string ToString() const; + private: base::TimeTicks frame_start_time_; uint32_t deadline_in_frames_ = 0u; - base::TimeDelta frame_interval_; + base::TimeDelta frame_interval_ = BeginFrameArgs::DefaultInterval(); bool use_default_lower_bound_deadline_ = true; }; +VIZ_COMMON_EXPORT std::ostream& operator<<(std::ostream& out, + const FrameDeadline& frame_deadline); + } // namespace viz #endif // COMPONENTS_VIZ_COMMON_QUADS_FRAME_DEADLINE_H_
diff --git a/components/viz/service/frame_sinks/surface_synchronization_unittest.cc b/components/viz/service/frame_sinks/surface_synchronization_unittest.cc index ad341cfd..28f2d7e 100644 --- a/components/viz/service/frame_sinks/surface_synchronization_unittest.cc +++ b/components/viz/service/frame_sinks/surface_synchronization_unittest.cc
@@ -2756,12 +2756,20 @@ // |child_id2| Surface should not activate because |child_id1| was never // added as a dependency by a parent. - child_support1().SubmitCompositorFrame(child_id2.local_surface_id(), - MakeDefaultCompositorFrame()); + child_support1().SubmitCompositorFrame( + child_id2.local_surface_id(), + MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(), + std::vector<TransferableResource>(), + MakeDeadline(1u))); Surface* child_surface2 = GetSurfaceForId(child_id2); ASSERT_NE(nullptr, child_surface2); EXPECT_TRUE(child_surface2->HasPendingFrame()); EXPECT_FALSE(child_surface2->HasActiveFrame()); + EXPECT_TRUE(child_surface2->has_deadline()); + + FrameDeadline deadline = MakeDefaultDeadline(); + base::TimeTicks deadline_wall_time = deadline.ToWallTime(); + EXPECT_EQ(deadline_wall_time, child_surface2->deadline_for_testing()); // The parent finally embeds a child surface that hasn't arrived which // activates |child_id2|'s Surface in order for the child to make forward @@ -2970,7 +2978,6 @@ EXPECT_TRUE(child_surface2->HasActiveFrame()); EXPECT_FALSE(child_surface2->has_deadline()); - // This failed before the latest change. EXPECT_TRUE(child_surface2->HasDependentFrame()); }
diff --git a/components/viz/service/surfaces/surface.cc b/components/viz/service/surfaces/surface.cc index bc9c06b0..ded72a2 100644 --- a/components/viz/service/surfaces/surface.cc +++ b/components/viz/service/surfaces/surface.cc
@@ -508,9 +508,13 @@ const FrameDeadline& deadline = current_frame.metadata.deadline; uint32_t deadline_in_frames = deadline.deadline_in_frames(); + bool block_activation = + block_activation_on_parent_ && !seen_first_surface_dependency_; + // If no default deadline is available then all deadlines are treated as // effectively infinite deadlines. - if (!default_deadline || deadline.use_default_lower_bound_deadline()) { + if (!default_deadline || deadline.use_default_lower_bound_deadline() || + block_activation) { deadline_in_frames = std::max( deadline_in_frames, default_deadline.value_or(std::numeric_limits<uint32_t>::max()));
diff --git a/components/viz/service/surfaces/surface.h b/components/viz/service/surfaces/surface.h index ba53c4dc..e8c1afe2 100644 --- a/components/viz/service/surfaces/surface.h +++ b/components/viz/service/surfaces/surface.h
@@ -105,6 +105,10 @@ bool has_deadline() const { return deadline_ && deadline_->has_deadline(); } + base::Optional<base::TimeTicks> deadline_for_testing() const { + return deadline_->deadline_for_testing(); + } + // Inherits the same deadline as the one specified by |surface|. A deadline // may be set further out in order to avoid doing unnecessary work while a // parent surface is blocked on dependencies. A deadline may be shortened
diff --git a/components/viz/service/surfaces/surface_dependency_deadline.cc b/components/viz/service/surfaces/surface_dependency_deadline.cc index bb5faca..65d8abe 100644 --- a/components/viz/service/surfaces/surface_dependency_deadline.cc +++ b/components/viz/service/surfaces/surface_dependency_deadline.cc
@@ -31,8 +31,7 @@ bool SurfaceDependencyDeadline::Set(const FrameDeadline& frame_deadline) { CancelInternal(false); start_time_ = frame_deadline.frame_start_time(); - deadline_ = start_time_ + frame_deadline.deadline_in_frames() * - frame_deadline.frame_interval(); + deadline_ = frame_deadline.ToWallTime(); begin_frame_source_->AddObserver(this); return has_deadline(); }
diff --git a/content/browser/frame_host/interstitial_page_impl.cc b/content/browser/frame_host/interstitial_page_impl.cc index f206f1e..95d70ed7 100644 --- a/content/browser/frame_host/interstitial_page_impl.cc +++ b/content/browser/frame_host/interstitial_page_impl.cc
@@ -594,10 +594,9 @@ return false; } -void InterstitialPageImpl::HandleKeyboardEvent( - const NativeWebKeyboardEvent& event) { - if (enabled()) - render_widget_host_delegate_->HandleKeyboardEvent(event); +bool InterstitialPageImpl::HandleKeyboardEvent( + const NativeWebKeyboardEvent& event) { + return enabled() && render_widget_host_delegate_->HandleKeyboardEvent(event); } WebContents* InterstitialPageImpl::web_contents() const {
diff --git a/content/browser/frame_host/interstitial_page_impl.h b/content/browser/frame_host/interstitial_page_impl.h index 1bd73270..486a40e 100644 --- a/content/browser/frame_host/interstitial_page_impl.h +++ b/content/browser/frame_host/interstitial_page_impl.h
@@ -174,7 +174,7 @@ KeyboardEventProcessingResult PreHandleKeyboardEvent( const NativeWebKeyboardEvent& event) override; bool PreHandleMouseEvent(const blink::WebMouseEvent& event) override; - void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override; + bool HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override; TextInputManager* GetTextInputManager() override; RenderWidgetHostInputEventRouter* GetInputEventRouter() override; BrowserAccessibilityManager* GetRootBrowserAccessibilityManager() override;
diff --git a/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc b/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc index e94cc9b..3b1b3dc 100644 --- a/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc +++ b/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc
@@ -70,7 +70,7 @@ std::string event_name = WebInputEvent::GetName(type); - if (latency.source_event_type() == ui::KEY_PRESS) + if (latency.source_event_type() == ui::SourceEventType::KEY_PRESS) event_name = "KeyPress"; std::string default_action_status = @@ -112,7 +112,7 @@ active_multi_finger_gesture_ = touch_event.touches_length != 1; } - if (latency->source_event_type() == ui::KEY_PRESS) { + if (latency->source_event_type() == ui::SourceEventType::KEY_PRESS) { DCHECK(event.GetType() == WebInputEvent::kChar || event.GetType() == WebInputEvent::kRawKeyDown); }
diff --git a/content/browser/renderer_host/render_widget_host_delegate.cc b/content/browser/renderer_host/render_widget_host_delegate.cc index af242bb..419a683 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.cc +++ b/content/browser/renderer_host/render_widget_host_delegate.cc
@@ -35,6 +35,11 @@ return false; } +bool RenderWidgetHostDelegate::HandleKeyboardEvent( + const NativeWebKeyboardEvent& event) { + return false; +} + bool RenderWidgetHostDelegate::ShouldIgnoreInputEvents() { return false; }
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h index 70130160..ae9853a66 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.h +++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -110,7 +110,7 @@ // Callback to inform the browser that the renderer did not process the // specified events. This gives an opportunity to the browser to process the // event (used for keyboard shortcuts). - virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {} + virtual bool HandleKeyboardEvent(const NativeWebKeyboardEvent& event); // Callback to inform the browser that the renderer did not process the // specified mouse wheel event. Returns true if the browser has handled
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index 16e04ce..cc830dff 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -596,9 +596,10 @@ : KeyboardEventProcessingResult::NOT_HANDLED; } - void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override { + bool HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override { unhandled_keyboard_event_type_ = event.GetType(); unhandled_keyboard_event_called_ = true; + return true; } bool HandleWheelEvent(const blink::WebMouseWheelEvent& event) override {
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index c553ee7..b881bf4 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2232,13 +2232,12 @@ : KeyboardEventProcessingResult::NOT_HANDLED; } -void WebContentsImpl::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { +bool WebContentsImpl::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { if (browser_plugin_embedder_ && browser_plugin_embedder_->HandleKeyboardEvent(event)) { - return; + return true; } - if (delegate_) - delegate_->HandleKeyboardEvent(this, event); + return delegate_ && delegate_->HandleKeyboardEvent(this, event); } bool WebContentsImpl::HandleWheelEvent(
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 82c7539e..ab486b8d 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -717,7 +717,7 @@ KeyboardEventProcessingResult PreHandleKeyboardEvent( const NativeWebKeyboardEvent& event) override; - void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override; + bool HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override; bool HandleWheelEvent(const blink::WebMouseWheelEvent& event) override; bool PreHandleGestureEvent(const blink::WebGestureEvent& event) override; BrowserAccessibilityManager* GetRootBrowserAccessibilityManager() override;
diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc index a216418..8f9eb56 100644 --- a/content/public/browser/web_contents_delegate.cc +++ b/content/public/browser/web_contents_delegate.cc
@@ -94,6 +94,12 @@ return KeyboardEventProcessingResult::NOT_HANDLED; } +bool WebContentsDelegate::HandleKeyboardEvent( + WebContents* source, + const NativeWebKeyboardEvent& event) { + return false; +} + bool WebContentsDelegate::PreHandleGestureEvent( WebContents* source, const blink::WebGestureEvent& event) {
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index df6045d..b26e4ea 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h
@@ -253,9 +253,11 @@ const NativeWebKeyboardEvent& event); // Allows delegates to handle unhandled keyboard messages coming back from - // the renderer. - virtual void HandleKeyboardEvent(WebContents* source, - const NativeWebKeyboardEvent& event) {} + // the renderer. Returns true if the event was handled, false otherwise. A + // true value means no more processing should happen on the event. The default + // return value is false + virtual bool HandleKeyboardEvent(WebContents* source, + const NativeWebKeyboardEvent& event); // Allows delegates to handle gesture events before sending to the renderer. // Returns true if the |event| was handled and thus shouldn't be processed
diff --git a/content/renderer/input/input_event_prediction.cc b/content/renderer/input/input_event_prediction.cc index 5b0579d3..3efc8b4 100644 --- a/content/renderer/input/input_event_prediction.cc +++ b/content/renderer/input/input_event_prediction.cc
@@ -26,28 +26,43 @@ constexpr char kInputEventPredictorTypeLsq[] = "lsq"; constexpr char kInputEventPredictorTypeKalman[] = "kalman"; +constexpr uint32_t kPredictEventCount = 3; +constexpr base::TimeDelta kPredictionInterval = + base::TimeDelta::FromMilliseconds(8); + } // namespace -InputEventPrediction::InputEventPrediction() { - std::string predictor_type = GetFieldTrialParamValueByFeature( - features::kResamplingInputEvents, kPredictor); - if (predictor_type == kInputEventPredictorTypeLsq) - selected_predictor_type_ = PredictorType::kLsq; - else if (predictor_type == kInputEventPredictorTypeKalman) - selected_predictor_type_ = PredictorType::kKalman; - else - selected_predictor_type_ = PredictorType::kEmpty; - - mouse_predictor_ = CreatePredictor(); +InputEventPrediction::InputEventPrediction(bool enable_resampling) + : enable_resampling_(enable_resampling) { + SetUpPredictorType(); } InputEventPrediction::~InputEventPrediction() {} +void InputEventPrediction::SetUpPredictorType() { + // Resampling predictor type is set from field trial parameters. + // When resampling is disable, use kalman filter predictor for + // creating predicted events. + if (enable_resampling_) { + std::string predictor_type = GetFieldTrialParamValueByFeature( + features::kResamplingInputEvents, kPredictor); + if (predictor_type == kInputEventPredictorTypeLsq) + selected_predictor_type_ = PredictorType::kLsq; + else if (predictor_type == kInputEventPredictorTypeKalman) + selected_predictor_type_ = PredictorType::kKalman; + else + selected_predictor_type_ = PredictorType::kEmpty; + } else { + selected_predictor_type_ = PredictorType::kKalman; + } + + mouse_predictor_ = CreatePredictor(); +} + void InputEventPrediction::HandleEvents( - const blink::WebCoalescedInputEvent& coalesced_event, - base::TimeTicks frame_time, - blink::WebInputEvent* event) { - switch (event->GetType()) { + blink::WebCoalescedInputEvent& coalesced_event, + base::TimeTicks frame_time) { + switch (coalesced_event.Event().GetType()) { case WebInputEvent::kMouseMove: case WebInputEvent::kTouchMove: case WebInputEvent::kPointerMove: { @@ -55,7 +70,20 @@ for (size_t i = 0; i < coalesced_size; i++) UpdatePrediction(coalesced_event.CoalescedEvent(i)); - ApplyResampling(frame_time, event); + if (enable_resampling_) + ApplyResampling(frame_time, coalesced_event.EventPointer()); + + base::TimeTicks predict_time = + enable_resampling_ + ? coalesced_event.EventPointer()->TimeStamp() + + kPredictionInterval + : std::max(frame_time, + coalesced_event.EventPointer()->TimeStamp()); + for (uint32_t i = 0; i < kPredictEventCount; i++) { + if (!AddPredictedEvent(predict_time, coalesced_event)) + break; + predict_time += kPredictionInterval; + } break; } case WebInputEvent::kTouchScrollStarted: @@ -63,7 +91,7 @@ pointer_id_predictor_map_.clear(); break; default: - ResetPredictor(*event); + ResetPredictor(coalesced_event.Event()); } } @@ -104,14 +132,14 @@ if (event->GetType() == WebInputEvent::kTouchMove) { WebTouchEvent* touch_event = static_cast<WebTouchEvent*>(event); for (unsigned i = 0; i < touch_event->touches_length; ++i) { - if (ResampleSinglePointer(frame_time, &touch_event->touches[i])) + if (GetPointerPrediction(frame_time, &touch_event->touches[i])) event->SetTimeStamp(frame_time); } } else if (event->GetType() == WebInputEvent::kMouseMove) { - if (ResampleSinglePointer(frame_time, static_cast<WebMouseEvent*>(event))) + if (GetPointerPrediction(frame_time, static_cast<WebMouseEvent*>(event))) event->SetTimeStamp(frame_time); } else if (event->GetType() == WebInputEvent::kPointerMove) { - if (ResampleSinglePointer(frame_time, static_cast<WebPointerEvent*>(event))) + if (GetPointerPrediction(frame_time, static_cast<WebPointerEvent*>(event))) event->SetTimeStamp(frame_time); } } @@ -132,6 +160,35 @@ } } +bool InputEventPrediction::AddPredictedEvent( + base::TimeTicks predict_time, + blink::WebCoalescedInputEvent& coalesced_event) { + ui::WebScopedInputEvent predicted_event = + ui::WebInputEventTraits::Clone(coalesced_event.Event()); + bool success = false; + if (predicted_event->GetType() == WebInputEvent::kTouchMove) { + WebTouchEvent& touch_event = static_cast<WebTouchEvent&>(*predicted_event); + success = true; + for (unsigned i = 0; i < touch_event.touches_length; ++i) { + if (!GetPointerPrediction(predict_time, &touch_event.touches[i])) + success = false; + } + } else if (predicted_event->GetType() == WebInputEvent::kMouseMove) { + if (GetPointerPrediction(predict_time, + &static_cast<WebMouseEvent&>(*predicted_event))) + success = true; + } else if (predicted_event->GetType() == WebInputEvent::kPointerMove) { + if (GetPointerPrediction(predict_time, + &static_cast<WebPointerEvent&>(*predicted_event))) + success = true; + } + if (success) { + predicted_event->SetTimeStamp(predict_time); + coalesced_event.AddPredictedEvent(*predicted_event); + } + return success; +} + void InputEventPrediction::UpdateSinglePointer( const WebPointerProperties& event, base::TimeTicks event_time) { @@ -152,12 +209,12 @@ } } -bool InputEventPrediction::ResampleSinglePointer(base::TimeTicks frame_time, - WebPointerProperties* event) { +bool InputEventPrediction::GetPointerPrediction(base::TimeTicks predict_time, + WebPointerProperties* event) { ui::InputPredictor::InputData predict_result; if (event->pointer_type == WebPointerProperties::PointerType::kMouse) { if (mouse_predictor_->HasPrediction() && - mouse_predictor_->GeneratePrediction(frame_time, &predict_result)) { + mouse_predictor_->GeneratePrediction(predict_time, &predict_result)) { event->SetPositionInWidget(predict_result.pos); return true; } @@ -168,7 +225,7 @@ auto predictor = pointer_id_predictor_map_.find(event->id); if (predictor != pointer_id_predictor_map_.end() && predictor->second->HasPrediction() && - predictor->second->GeneratePrediction(frame_time, &predict_result)) { + predictor->second->GeneratePrediction(predict_time, &predict_result)) { event->SetPositionInWidget(predict_result.pos); return true; }
diff --git a/content/renderer/input/input_event_prediction.h b/content/renderer/input/input_event_prediction.h index 3bcc9ae3..3059a28 100644 --- a/content/renderer/input/input_event_prediction.h +++ b/content/renderer/input/input_event_prediction.h
@@ -21,22 +21,35 @@ // This class stores prediction of all active pointers. class CONTENT_EXPORT InputEventPrediction { public: - InputEventPrediction(); + // enable_resampling is true when kResamplingInputEvents is enabled. + explicit InputEventPrediction(bool enable_resampling); ~InputEventPrediction(); - void HandleEvents(const blink::WebCoalescedInputEvent& coalesced_event, - base::TimeTicks frame_time, - blink::WebInputEvent* event); + // Handle Resampling/Prediction of WebInputEvents. This function is mainly + // doing three things: + // 1. Maintain/Updates predictor using current CoalescedEvents vector. + // 2. When enable_resampling is true, change coalesced_event->EventPointer()'s + // coordinates to the position at frame time. + // 3. Generates 3 predicted events when prediction is available, add the + // PredictedEvent to coalesced_event. + void HandleEvents(blink::WebCoalescedInputEvent& coalesced_event, + base::TimeTicks frame_time); // Initialize predictor for different pointer. std::unique_ptr<ui::InputPredictor> CreatePredictor() const; private: friend class InputEventPredictionTest; + FRIEND_TEST_ALL_PREFIXES(PredictedEventTest, ResamplingDisabled); + FRIEND_TEST_ALL_PREFIXES(InputEventPredictionTest, PredictorType); enum class PredictorType { kEmpty, kLsq, kKalman }; - // The following three function is for handling multiple TouchPoints in a + // Set predictor type from field parameters of kResamplingInputEvent flag if + // it's enable. Otherwise use Kalman filter predictor. + void SetUpPredictorType(); + + // The following functions are for handling multiple TouchPoints in a // WebTouchEvent. They should be more neat when WebTouchEvent is elimated. // Cast events from WebInputEvent to WebPointerProperties. Call // UpdateSinglePointer for each pointer. @@ -44,17 +57,22 @@ // Cast events from WebInputEvent to WebPointerProperties. Call // ResamplingSinglePointer for each poitner. void ApplyResampling(base::TimeTicks frame_time, WebInputEvent* event); - // Cast events from WebInputEvent to WebPointerProperties. Call - // ResetSinglePredictor for each pointer. + // Reset predictor for each pointer in WebInputEvent by ResetSinglePredictor. void ResetPredictor(const WebInputEvent& event); + // Add predicted event to WebCoalescedInputEvent if prediction is available. + bool AddPredictedEvent(base::TimeTicks predict_time, + blink::WebCoalescedInputEvent& coalesced_event); + // Get single predictor based on event id and type, and update the predictor // with new events coords. void UpdateSinglePointer(const WebPointerProperties& event, base::TimeTicks time); - // Get single predictor based on event id and type, apply resampling event - // coordinates. - bool ResampleSinglePointer(base::TimeTicks time, WebPointerProperties* event); + // Get prediction result of a single predictor based on the predict_time, + // and apply predicted result to the event. Return false if no prediction + // available. + bool GetPointerPrediction(base::TimeTicks predict_time, + WebPointerProperties* event); // Get single predictor based on event id and type. For mouse, reset the // predictor, for other pointer type, remove it from mapping. void ResetSinglePredictor(const WebPointerProperties& event); @@ -67,6 +85,8 @@ // predictor. PredictorType selected_predictor_type_; + bool enable_resampling_ = false; + DISALLOW_COPY_AND_ASSIGN(InputEventPrediction); };
diff --git a/content/renderer/input/input_event_prediction_unittest.cc b/content/renderer/input/input_event_prediction_unittest.cc index 04ef067..36a0162 100644 --- a/content/renderer/input/input_event_prediction_unittest.cc +++ b/content/renderer/input/input_event_prediction_unittest.cc
@@ -4,7 +4,12 @@ #include "content/renderer/input/input_event_prediction.h" +#include "base/metrics/field_trial_param_associator.h" +#include "base/metrics/field_trial_params.h" +#include "base/test/scoped_feature_list.h" #include "content/common/input/synthetic_web_input_event_builders.h" + +#include "content/public/common/content_features.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/events/base_event_utils.h" #include "ui/events/blink/prediction/empty_predictor.h" @@ -14,12 +19,15 @@ using blink::WebPointerProperties; using blink::WebTouchEvent; +namespace {} // namespace + namespace content { class InputEventPredictionTest : public testing::Test { public: InputEventPredictionTest() { - event_predictor_ = std::make_unique<InputEventPrediction>(); + event_predictor_ = + std::make_unique<InputEventPrediction>(true /* enable_resampling */); } int GetPredictorMapSize() const { @@ -49,16 +57,66 @@ void HandleEvents(const WebInputEvent& event) { blink::WebCoalescedInputEvent coalesced_event(event); event_predictor_->HandleEvents(coalesced_event, - WebInputEvent::GetStaticTimeStampForTests(), - coalesced_event.EventPointer()); + WebInputEvent::GetStaticTimeStampForTests()); + } + + void ConfigureFieldTrial(const std::string& predictor_type) { + const std::string kTrialName = "TestTrial"; + const std::string kGroupName = "TestGroup"; + + field_trial_list_.reset(); + field_trial_list_.reset(new base::FieldTrialList(nullptr)); + scoped_refptr<base::FieldTrial> trial = + base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName); + base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting(); + + std::map<std::string, std::string> params; + params["predictor"] = predictor_type; + base::FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams( + kTrialName, kGroupName, params); + + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); + feature_list->RegisterFieldTrialOverride( + features::kResamplingInputEvents.name, + base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get()); + base::FeatureList::ClearInstanceForTesting(); + scoped_feature_list_.InitWithFeatureList(std::move(feature_list)); + + EXPECT_EQ(params["predictor"], + GetFieldTrialParamValueByFeature(features::kResamplingInputEvents, + "predictor")); } protected: std::unique_ptr<InputEventPrediction> event_predictor_; + base::test::ScopedFeatureList scoped_feature_list_; + std::unique_ptr<base::FieldTrialList> field_trial_list_; + DISALLOW_COPY_AND_ASSIGN(InputEventPredictionTest); }; +TEST_F(InputEventPredictionTest, PredictorType) { + EXPECT_TRUE(event_predictor_->enable_resampling_); + EXPECT_EQ(event_predictor_->selected_predictor_type_, + InputEventPrediction::PredictorType::kEmpty); + + ConfigureFieldTrial("empty"); + event_predictor_->SetUpPredictorType(); + EXPECT_EQ(event_predictor_->selected_predictor_type_, + InputEventPrediction::PredictorType::kEmpty); + + ConfigureFieldTrial("kalman"); + event_predictor_->SetUpPredictorType(); + EXPECT_EQ(event_predictor_->selected_predictor_type_, + InputEventPrediction::PredictorType::kKalman); + + ConfigureFieldTrial("lsq"); + event_predictor_->SetUpPredictorType(); + EXPECT_EQ(event_predictor_->selected_predictor_type_, + InputEventPrediction::PredictorType::kLsq); +} + TEST_F(InputEventPredictionTest, MouseEvent) { WebMouseEvent mouse_move = SyntheticWebMouseEventBuilder::Build( WebInputEvent::kMouseMove, 10, 10, 0); @@ -210,4 +268,46 @@ EXPECT_EQ(GetPredictorMapSize(), 0); } +class PredictedEventTest : public InputEventPredictionTest { + public: + PredictedEventTest() { + event_predictor_ = + std::make_unique<InputEventPrediction>(false /* enable_resampling */); + } +}; + +TEST_F(PredictedEventTest, ResamplingDisabled) { + // When resampling is disable, use kalman filter predictor to generate + // predicted event. + EXPECT_FALSE(event_predictor_->enable_resampling_); + EXPECT_EQ(event_predictor_->selected_predictor_type_, + InputEventPrediction::PredictorType::kKalman); + + // Send 3 mouse move to get kalman predictor ready. + WebMouseEvent mouse_move = SyntheticWebMouseEventBuilder::Build( + WebInputEvent::kMouseMove, 10, 10, 0); + HandleEvents(mouse_move); + mouse_move = + SyntheticWebMouseEventBuilder::Build(WebInputEvent::kMouseMove, 11, 9, 0); + HandleEvents(mouse_move); + + mouse_move = + SyntheticWebMouseEventBuilder::Build(WebInputEvent::kMouseMove, 12, 8, 0); + HandleEvents(mouse_move); + + // The 4th move event should generate predicted events. + mouse_move = + SyntheticWebMouseEventBuilder::Build(WebInputEvent::kMouseMove, 13, 7, 0); + blink::WebCoalescedInputEvent coalesced_event(mouse_move); + event_predictor_->HandleEvents(coalesced_event, ui::EventTimeForNow()); + + EXPECT_GT(coalesced_event.PredictedEventSize(), 0u); + + // Verify when resampling event is disabled, event coordinate doesn't change. + const WebMouseEvent& event = + static_cast<const blink::WebMouseEvent&>(coalesced_event.Event()); + EXPECT_EQ(event.PositionInWidget().x, 13); + EXPECT_EQ(event.PositionInWidget().y, 7); +} + } // namespace content
diff --git a/content/renderer/input/main_thread_event_queue.cc b/content/renderer/input/main_thread_event_queue.cc index 301dc04a..3727d6d 100644 --- a/content/renderer/input/main_thread_event_queue.cc +++ b/content/renderer/input/main_thread_event_queue.cc
@@ -236,10 +236,8 @@ use_raf_fallback_timer_(true) { raf_fallback_timer_.SetTaskRunner(main_task_runner); - event_predictor_ = - base::FeatureList::IsEnabled(features::kResamplingInputEvents) - ? std::make_unique<InputEventPrediction>() - : nullptr; + event_predictor_ = std::make_unique<InputEventPrediction>( + base::FeatureList::IsEnabled(features::kResamplingInputEvents)); } MainThreadEventQueue::~MainThreadEventQueue() {} @@ -586,8 +584,7 @@ base::TimeTicks frame_time) { if (item->IsWebInputEvent() && allow_raf_aligned_input_ && event_predictor_) { QueuedWebInputEvent* event = static_cast<QueuedWebInputEvent*>(item.get()); - event_predictor_->HandleEvents(event->coalesced_event(), frame_time, - &event->event()); + event_predictor_->HandleEvents(event->coalesced_event(), frame_time); } }
diff --git a/content/renderer/input/scoped_web_input_event_with_latency_info.cc b/content/renderer/input/scoped_web_input_event_with_latency_info.cc index b829c1a..47e6fd00 100644 --- a/content/renderer/input/scoped_web_input_event_with_latency_info.cc +++ b/content/renderer/input/scoped_web_input_event_with_latency_info.cc
@@ -53,4 +53,9 @@ return *event_; } +blink::WebCoalescedInputEvent& +ScopedWebInputEventWithLatencyInfo::coalesced_event() { + return *event_; +} + } // namespace content
diff --git a/content/renderer/input/scoped_web_input_event_with_latency_info.h b/content/renderer/input/scoped_web_input_event_with_latency_info.h index 590e902..f8d37654 100644 --- a/content/renderer/input/scoped_web_input_event_with_latency_info.h +++ b/content/renderer/input/scoped_web_input_event_with_latency_info.h
@@ -31,6 +31,7 @@ const blink::WebInputEvent& event() const; const blink::WebCoalescedInputEvent& coalesced_event() const; blink::WebInputEvent& event(); + blink::WebCoalescedInputEvent& coalesced_event(); const ui::LatencyInfo latencyInfo() const { return latency_; } void CoalesceWith(const ScopedWebInputEventWithLatencyInfo& other);
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 844fa67..70c10096 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -502,9 +502,12 @@ DCHECK(!webwidget_internal_); DCHECK_NE(routing_id_, MSG_ROUTING_NONE); + RenderThreadImpl* render_thread_impl = RenderThreadImpl::current(); + input_handler_ = std::make_unique<RenderWidgetInputHandler>(this, this); - RenderThreadImpl* render_thread_impl = RenderThreadImpl::current(); + LayerTreeView* layer_tree_view = InitializeLayerTreeView(); + web_widget->SetLayerTreeView(layer_tree_view); blink::scheduler::WebThreadScheduler* main_thread_scheduler = nullptr; if (render_thread_impl) @@ -1400,47 +1403,6 @@ /////////////////////////////////////////////////////////////////////////////// // WebWidgetClient -blink::WebLayerTreeView* RenderWidget::InitializeLayerTreeView() { - DCHECK(!host_closing_); - - layer_tree_view_ = std::make_unique<LayerTreeView>( - this, compositor_deps_->GetCompositorMainThreadTaskRunner(), - compositor_deps_->GetCompositorImplThreadTaskRunner(), - compositor_deps_->GetTaskGraphRunner(), - compositor_deps_->GetWebMainThreadScheduler()); - layer_tree_view_->Initialize( - GenerateLayerTreeSettings(compositor_deps_, for_oopif_, - screen_info_.rect.size(), - screen_info_.device_scale_factor), - compositor_deps_->CreateUkmRecorderFactory()); - - UpdateSurfaceAndScreenInfo(local_surface_id_from_parent_, - compositor_viewport_pixel_size_, screen_info_); - layer_tree_view_->SetRasterColorSpace( - screen_info_.color_space.GetRasterColorSpace()); - layer_tree_view_->SetContentSourceId(current_content_source_id_); - // For background pages and certain tests, we don't want to trigger - // LayerTreeFrameSink creation. - bool should_generate_frame_sink = - !compositor_never_visible_ && RenderThreadImpl::current(); - if (!should_generate_frame_sink) - layer_tree_view_->SetNeverVisible(); - - StartCompositor(); - DCHECK_NE(MSG_ROUTING_NONE, routing_id_); - layer_tree_view_->SetFrameSinkId( - viz::FrameSinkId(RenderThread::Get()->GetClientId(), routing_id_)); - - RenderThreadImpl* render_thread = RenderThreadImpl::current(); - if (render_thread) { - input_event_queue_ = new MainThreadEventQueue( - this, render_thread->GetWebMainThreadScheduler()->InputTaskRunner(), - render_thread->GetWebMainThreadScheduler(), should_generate_frame_sink); - } - - return layer_tree_view_.get(); -} - void RenderWidget::IntrinsicSizingInfoChanged( const blink::WebIntrinsicSizingInfo& sizing_info) { Send(new WidgetHostMsg_IntrinsicSizingInfoChanged(routing_id_, sizing_info)); @@ -1560,6 +1522,48 @@ SetPendingWindowRect(initial_rect_); } +LayerTreeView* RenderWidget::InitializeLayerTreeView() { + TRACE_EVENT0("blink", "RenderWidget::InitializeLayerTreeView"); + DCHECK(!host_closing_); + + layer_tree_view_ = std::make_unique<LayerTreeView>( + this, compositor_deps_->GetCompositorMainThreadTaskRunner(), + compositor_deps_->GetCompositorImplThreadTaskRunner(), + compositor_deps_->GetTaskGraphRunner(), + compositor_deps_->GetWebMainThreadScheduler()); + layer_tree_view_->Initialize( + GenerateLayerTreeSettings(compositor_deps_, for_oopif_, + screen_info_.rect.size(), + screen_info_.device_scale_factor), + compositor_deps_->CreateUkmRecorderFactory()); + + UpdateSurfaceAndScreenInfo(local_surface_id_from_parent_, + compositor_viewport_pixel_size_, screen_info_); + layer_tree_view_->SetRasterColorSpace( + screen_info_.color_space.GetRasterColorSpace()); + layer_tree_view_->SetContentSourceId(current_content_source_id_); + // For background pages and certain tests, we don't want to trigger + // LayerTreeFrameSink creation. + bool should_generate_frame_sink = + !compositor_never_visible_ && RenderThreadImpl::current(); + if (!should_generate_frame_sink) + layer_tree_view_->SetNeverVisible(); + + StartCompositor(); + DCHECK_NE(MSG_ROUTING_NONE, routing_id_); + layer_tree_view_->SetFrameSinkId( + viz::FrameSinkId(RenderThread::Get()->GetClientId(), routing_id_)); + + RenderThreadImpl* render_thread = RenderThreadImpl::current(); + if (render_thread) { + input_event_queue_ = base::MakeRefCounted<MainThreadEventQueue>( + this, render_thread->GetWebMainThreadScheduler()->InputTaskRunner(), + render_thread->GetWebMainThreadScheduler(), should_generate_frame_sink); + } + + return layer_tree_view_.get(); +} + void RenderWidget::DoDeferredClose() { WillCloseLayerTreeView(); Send(new WidgetHostMsg_Close(routing_id_));
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index cd85950..af9d4c3 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -301,7 +301,6 @@ const gfx::Rect& window_screen_rect) override; // blink::WebWidgetClient - blink::WebLayerTreeView* InitializeLayerTreeView() override; void IntrinsicSizingInfoChanged( const blink::WebIntrinsicSizingInfo&) override; void DidMeaningfulLayout(blink::WebMeaningfulLayout layout_type) override; @@ -561,6 +560,8 @@ static scoped_refptr<base::SingleThreadTaskRunner> GetCleanupTaskRunner(); + LayerTreeView* InitializeLayerTreeView(); + void DoDeferredClose(); void NotifyOnClose();
diff --git a/content/renderer/render_widget_fullscreen_pepper.cc b/content/renderer/render_widget_fullscreen_pepper.cc index ebb5925..738b93e 100644 --- a/content/renderer/render_widget_fullscreen_pepper.cc +++ b/content/renderer/render_widget_fullscreen_pepper.cc
@@ -137,6 +137,11 @@ virtual ~PepperWidget() {} // WebWidget API + void SetLayerTreeView(blink::WebLayerTreeView*) override { + // Does nothing, as the LayerTreeView can be accessed from the RenderWidget + // directly. + } + void Close() override { delete this; } WebSize Size() override { return size_; } @@ -341,8 +346,6 @@ layer_tree_view()->ClearRootLayer(); return; } - if (!layer_tree_view()) - InitializeLayerTreeView(); UpdateLayerBounds(); layer_->SetIsDrawable(true); layer_tree_view()->SetRootLayer(layer_);
diff --git a/content/renderer/render_widget_unittest.cc b/content/renderer/render_widget_unittest.cc index e610614..269f94d 100644 --- a/content/renderer/render_widget_unittest.cc +++ b/content/renderer/render_widget_unittest.cc
@@ -131,6 +131,7 @@ class StubWebWidget : public blink::WebWidget { public: + void SetLayerTreeView(blink::WebLayerTreeView*) override {} blink::WebURL GetURLForDebugTrace() override { return {}; } }; @@ -361,8 +362,6 @@ // Tests that if a RenderWidget is auto-resized, it requests a new // viz::LocalSurfaceId to be allocated on the impl thread. TEST_F(RenderWidgetUnittest, AutoResizeAllocatedLocalSurfaceId) { - widget()->InitializeLayerTreeView(); - viz::ParentLocalSurfaceIdAllocator allocator; // Enable auto-resize.
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc index c1ff79a..93f64ce 100644 --- a/content/shell/browser/layout_test/blink_test_controller.cc +++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -534,11 +534,29 @@ composite_all_frames_node_queue_ = std::queue<Node*>(); weak_factory_.InvalidateWeakPtrs(); + bool discard_main_window = false; + bool discard_secondary_window = false; + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kResetShellBetweenTests)) { + discard_main_window = true; + discard_secondary_window = true; + } + #if defined(OS_ANDROID) // Re-using the shell's main window on Android causes issues with networking // requests never succeeding. See http://crbug.com/277652. - DiscardMainWindow(); + discard_main_window = true; #endif + + if (discard_main_window) { + DiscardMainWindow(); + devtools_window_ = nullptr; + } + if (discard_secondary_window && secondary_window_) { + secondary_window_->Close(); + secondary_window_ = nullptr; + } + return true; }
diff --git a/content/shell/browser/shell.h b/content/shell/browser/shell.h index fbe8e4a..4faf60e 100644 --- a/content/shell/browser/shell.h +++ b/content/shell/browser/shell.h
@@ -175,7 +175,7 @@ RenderFrameHost* frame, const BluetoothChooser::EventHandler& event_handler) override; #if defined(OS_MACOSX) - void HandleKeyboardEvent(WebContents* source, + bool HandleKeyboardEvent(WebContents* source, const NativeWebKeyboardEvent& event) override; #endif bool DidAddMessageToConsole(WebContents* source,
diff --git a/content/shell/browser/shell_mac.mm b/content/shell/browser/shell_mac.mm index c283fe8..80fd97e 100644 --- a/content/shell/browser/shell_mac.mm +++ b/content/shell/browser/shell_mac.mm
@@ -317,10 +317,10 @@ } } -void Shell::HandleKeyboardEvent(WebContents* source, +bool Shell::HandleKeyboardEvent(WebContents* source, const NativeWebKeyboardEvent& event) { if (event.skip_in_browser || headless_ || hide_toolbar_) - return; + return false; // The event handling to get this strictly right is a tangle; cheat here a bit // by just letting the menus have a chance at it. @@ -328,11 +328,13 @@ if (([event.os_event modifierFlags] & NSCommandKeyMask) && [[event.os_event characters] isEqual:@"l"]) { [window_ makeFirstResponder:url_edit_view_]; - return; + return true; } [[NSApp mainMenu] performKeyEquivalent:event.os_event]; + return true; } + return false; } } // namespace content
diff --git a/content/shell/common/layout_test/layout_test_switches.cc b/content/shell/common/layout_test/layout_test_switches.cc index 262a246..5e00a75 100644 --- a/content/shell/common/layout_test/layout_test_switches.cc +++ b/content/shell/common/layout_test/layout_test_switches.cc
@@ -46,6 +46,10 @@ // Encode binary layout test results (images, audio) using base64. const char kEncodeBinary[] = "encode-binary"; +// Request Content Shell between tests. This causes tests to run twice as +// slowly, but provides more consistent results. +const char kResetShellBetweenTests[] = "reset-shell-between-tests"; + // Request the render trees of pages to be dumped as text once they have // finished loading. const char kRunWebTests[] = "run-web-tests";
diff --git a/content/shell/common/layout_test/layout_test_switches.h b/content/shell/common/layout_test/layout_test_switches.h index ebbf47c..5be1c267 100644 --- a/content/shell/common/layout_test/layout_test_switches.h +++ b/content/shell/common/layout_test/layout_test_switches.h
@@ -28,6 +28,7 @@ extern const char kAlwaysUseComplexText[]; extern const char kEnableLeakDetection[]; extern const char kEncodeBinary[]; +extern const char kResetShellBetweenTests[]; extern const char kRunWebTests[]; extern const char kStableReleaseMode[]; extern const char kTestsInBlink[];
diff --git a/content/shell/test_runner/web_view_test_proxy.cc b/content/shell/test_runner/web_view_test_proxy.cc index 28529d5..a7a7b28b 100644 --- a/content/shell/test_runner/web_view_test_proxy.cc +++ b/content/shell/test_runner/web_view_test_proxy.cc
@@ -29,9 +29,6 @@ void ProxyWebWidgetClient::DidInvalidateRect(const blink::WebRect& r) { base_class_widget_client_->DidInvalidateRect(r); } -blink::WebLayerTreeView* ProxyWebWidgetClient::InitializeLayerTreeView() { - return base_class_widget_client_->InitializeLayerTreeView(); -} bool ProxyWebWidgetClient::AllowsBrokenNullLayerTreeView() const { return base_class_widget_client_->AllowsBrokenNullLayerTreeView(); }
diff --git a/content/shell/test_runner/web_view_test_proxy.h b/content/shell/test_runner/web_view_test_proxy.h index 5d91c52e..30a95923 100644 --- a/content/shell/test_runner/web_view_test_proxy.h +++ b/content/shell/test_runner/web_view_test_proxy.h
@@ -61,7 +61,6 @@ // blink::WebWidgetClient implementation. void DidInvalidateRect(const blink::WebRect&) override; - blink::WebLayerTreeView* InitializeLayerTreeView() override; bool AllowsBrokenNullLayerTreeView() const override; void ScheduleAnimation() override; void IntrinsicSizingInfoChanged(
diff --git a/content/shell/test_runner/web_widget_test_client.cc b/content/shell/test_runner/web_widget_test_client.cc index 343997f..042e8aa 100644 --- a/content/shell/test_runner/web_widget_test_client.cc +++ b/content/shell/test_runner/web_widget_test_client.cc
@@ -102,12 +102,6 @@ web_widget_test_proxy_base_->event_sender()->DoDragDrop(data, mask); } -blink::WebLayerTreeView* WebWidgetTestClient::InitializeLayerTreeView() { - // This call should go to the production client, not here. - NOTREACHED(); - return nullptr; -} - bool WebWidgetTestClient::AllowsBrokenNullLayerTreeView() const { // This call should go to the production client, not here. NOTREACHED();
diff --git a/content/shell/test_runner/web_widget_test_client.h b/content/shell/test_runner/web_widget_test_client.h index d589721..f4c6666 100644 --- a/content/shell/test_runner/web_widget_test_client.h +++ b/content/shell/test_runner/web_widget_test_client.h
@@ -44,7 +44,6 @@ const blink::WebPoint& image_offset) override; // WebWidgetClient overrides that are not used. - blink::WebLayerTreeView* InitializeLayerTreeView() override; bool AllowsBrokenNullLayerTreeView() const override; private:
diff --git a/content/test/gpu/gpu_tests/context_lost_expectations.py b/content/test/gpu/gpu_tests/context_lost_expectations.py index 2953bab..cbcf163 100644 --- a/content/test/gpu/gpu_tests/context_lost_expectations.py +++ b/content/test/gpu/gpu_tests/context_lost_expectations.py
@@ -27,10 +27,6 @@ self.Skip('ContextLost_WebGLContextLostFromSelectElement', ['win8', 'nvidia'], bug=524808) - # Flaky on Win10 - self.Flaky('ContextLost_WebGLUnblockedAfterUserInitiatedReload', - ['win10', 'debug'], bug=895765) - # Flakily timing out on Win x64 Debug bot. # Unfortunately we can't identify this separately from the 32-bit bots. # Also unfortunately, the flaky retry mechanism doesn't work well in
diff --git a/content/test/gpu/gpu_tests/gpu_process_expectations.py b/content/test/gpu/gpu_tests/gpu_process_expectations.py index ef1f7d8..743db5d2 100644 --- a/content/test/gpu/gpu_tests/gpu_process_expectations.py +++ b/content/test/gpu/gpu_tests/gpu_process_expectations.py
@@ -16,3 +16,5 @@ # Test needs fixing for Nexus 9 self.Fail('GpuProcess_disabling_workarounds_works', ['android', 'nvidia'], bug=895020) + self.Fail('GpuProcess_webgl_disabled_extension', ['android', 'nvidia'], + bug=895945)
diff --git a/docs/README.md b/docs/README.md index 86db0ce7..579c5f4 100644 --- a/docs/README.md +++ b/docs/README.md
@@ -330,6 +330,7 @@ install Chromium OS on VMWare. * [User Data Directory](user_data_dir.md) - How the user data and cache directories are determined on all platforms. +* [Mojo](../mojo/README.md) - IPC mechanism used by services. ### Probably Obsolete * [TPM Quick Reference](tpm_quick_ref.md) - Trusted Platform Module notes.
diff --git a/extensions/browser/app_window/app_window.cc b/extensions/browser/app_window/app_window.cc index cfccd40..99fc005 100644 --- a/extensions/browser/app_window/app_window.cc +++ b/extensions/browser/app_window/app_window.cc
@@ -405,7 +405,7 @@ return content::KeyboardEventProcessingResult::NOT_HANDLED; } -void AppWindow::HandleKeyboardEvent( +bool AppWindow::HandleKeyboardEvent( WebContents* source, const content::NativeWebKeyboardEvent& event) { // If the window is currently fullscreen and not forced, ESC should leave @@ -414,10 +414,10 @@ if (event.windows_key_code == ui::VKEY_ESCAPE && IsFullscreen() && !IsForcedFullscreen()) { Restore(); - return; + return true; } - native_app_window_->HandleKeyboardEvent(event); + return native_app_window_->HandleKeyboardEvent(event); } void AppWindow::RequestToLockMouse(WebContents* web_contents,
diff --git a/extensions/browser/app_window/app_window.h b/extensions/browser/app_window/app_window.h index 8e80ca8..7950d9a 100644 --- a/extensions/browser/app_window/app_window.h +++ b/extensions/browser/app_window/app_window.h
@@ -433,7 +433,7 @@ content::KeyboardEventProcessingResult PreHandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; void RequestToLockMouse(content::WebContents* web_contents,
diff --git a/extensions/browser/app_window/native_app_window.h b/extensions/browser/app_window/native_app_window.h index 0ae528f..f6f4ed5 100644 --- a/extensions/browser/app_window/native_app_window.h +++ b/extensions/browser/app_window/native_app_window.h
@@ -58,7 +58,7 @@ // Allows the window to handle unhandled keyboard messages coming back from // the renderer. - virtual void HandleKeyboardEvent( + virtual bool HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) = 0; // Returns true if the window has no frame, as for a window opened by
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc index 613f905..3f156db5 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.cc +++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -588,13 +588,13 @@ web_view_guest_delegate_->HandleContextMenu(params); } -void WebViewGuest::HandleKeyboardEvent( +bool WebViewGuest::HandleKeyboardEvent( WebContents* source, const content::NativeWebKeyboardEvent& event) { if (HandleKeyboardShortcuts(event)) - return; + return true; - GuestViewBase::HandleKeyboardEvent(source, event); + return GuestViewBase::HandleKeyboardEvent(source, event); } bool WebViewGuest::PreHandleGestureEvent(WebContents* source,
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h index d61df18..343f162 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.h +++ b/extensions/browser/guest_view/web_view/web_view_guest.h
@@ -210,7 +210,7 @@ const base::string16& source_id) final; void CloseContents(content::WebContents* source) final; bool HandleContextMenu(const content::ContextMenuParams& params) final; - void HandleKeyboardEvent(content::WebContents* source, + bool HandleKeyboardEvent(content::WebContents* source, const content::NativeWebKeyboardEvent& event) final; void LoadProgressChanged(content::WebContents* source, double progress) final; bool PreHandleGestureEvent(content::WebContents* source,
diff --git a/extensions/components/native_app_window/native_app_window_views.cc b/extensions/components/native_app_window/native_app_window_views.cc index 59e4f97..9eaea15 100644 --- a/extensions/components/native_app_window/native_app_window_views.cc +++ b/extensions/components/native_app_window/native_app_window_views.cc
@@ -379,10 +379,10 @@ // Stub implementation. See also ChromeNativeAppWindowViews. } -void NativeAppWindowViews::HandleKeyboardEvent( +bool NativeAppWindowViews::HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) { - unhandled_keyboard_event_handler_.HandleKeyboardEvent(event, - GetFocusManager()); + return unhandled_keyboard_event_handler_.HandleKeyboardEvent( + event, GetFocusManager()); } bool NativeAppWindowViews::IsFrameless() const {
diff --git a/extensions/components/native_app_window/native_app_window_views.h b/extensions/components/native_app_window/native_app_window_views.h index 5c9b875..6bcc3e5 100644 --- a/extensions/components/native_app_window/native_app_window_views.h +++ b/extensions/components/native_app_window/native_app_window_views.h
@@ -132,7 +132,7 @@ const std::vector<extensions::DraggableRegion>& regions) override; SkRegion* GetDraggableRegion() override; void UpdateShape(std::unique_ptr<ShapeRects> rects) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) override; bool IsFrameless() const override; bool HasFrameColor() const override;
diff --git a/extensions/shell/browser/shell_native_app_window.cc b/extensions/shell/browser/shell_native_app_window.cc index 25741f4..33b3bf5 100644 --- a/extensions/shell/browser/shell_native_app_window.cc +++ b/extensions/shell/browser/shell_native_app_window.cc
@@ -136,9 +136,10 @@ NOTIMPLEMENTED(); } -void ShellNativeAppWindow::HandleKeyboardEvent( - const content::NativeWebKeyboardEvent& event) { +bool ShellNativeAppWindow::HandleKeyboardEvent( + const content::NativeWebKeyboardEvent& event) { // No special handling. The WebContents will handle it. + return false; } bool ShellNativeAppWindow::IsFrameless() const {
diff --git a/extensions/shell/browser/shell_native_app_window.h b/extensions/shell/browser/shell_native_app_window.h index a282a41..a00a052 100644 --- a/extensions/shell/browser/shell_native_app_window.h +++ b/extensions/shell/browser/shell_native_app_window.h
@@ -53,7 +53,7 @@ const std::vector<DraggableRegion>& regions) override; SkRegion* GetDraggableRegion() override; void UpdateShape(std::unique_ptr<ShapeRects> rects) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) override; bool IsFrameless() const override; bool HasFrameColor() const override;
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index b2d68024..d2ff1a5c 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn
@@ -213,6 +213,7 @@ "command_buffer/tests/gl_ext_multisample_compatibility_unittest.cc", "command_buffer/tests/gl_ext_srgb_unittest.cc", "command_buffer/tests/gl_ext_window_rectangles_unittest.cc", + "command_buffer/tests/gl_fence_sync_unittest.cc", "command_buffer/tests/gl_gpu_memory_buffer_unittest.cc", "command_buffer/tests/gl_iosurface_readback_workaround_unittest.cc", "command_buffer/tests/gl_lose_context_chromium_unittest.cc",
diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h index b8deb0b..6b0b363 100644 --- a/gpu/GLES2/gl2extchromium.h +++ b/gpu/GLES2/gl2extchromium.h
@@ -1272,6 +1272,10 @@ GLsizei height); #endif /* GL_CHROMIUM_unpremultiply_and_dither_copy */ +#ifndef GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT +#define GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT 0x8868 +#endif + #ifdef __cplusplus } #endif
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 149deef..70cae33 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -725,6 +725,7 @@ 'valid': [ 'GL_QUERY_RESULT_EXT', 'GL_QUERY_RESULT_AVAILABLE_EXT', + 'GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT', ], }, 'QueryParameter': { @@ -3707,7 +3708,12 @@ 'extension': "CHROMIUM_sync_point", }, 'WaitSyncTokenCHROMIUM': { - 'type': 'NoCommand', + 'type': 'Custom', + 'impl_func': False, + 'cmd_args': 'GLint namespace_id, ' + 'GLuint64 command_buffer_id, ' + 'GLuint64 release_count', + 'client_test': False, 'extension': "CHROMIUM_sync_point", }, 'DiscardBackbufferCHROMIUM': {
diff --git a/gpu/command_buffer/build_raster_cmd_buffer.py b/gpu/command_buffer/build_raster_cmd_buffer.py index 871ad640..e7bdf1f2 100755 --- a/gpu/command_buffer/build_raster_cmd_buffer.py +++ b/gpu/command_buffer/build_raster_cmd_buffer.py
@@ -38,6 +38,7 @@ 'valid': [ 'GL_QUERY_RESULT_EXT', 'GL_QUERY_RESULT_AVAILABLE_EXT', + 'GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT', ], }, 'QueryTarget': { @@ -365,7 +366,12 @@ 'type': 'NoCommand', }, 'WaitSyncTokenCHROMIUM': { - 'type': 'NoCommand', + 'type': 'Custom', + 'impl_func': False, + 'cmd_args': 'GLint namespace_id, ' + 'GLuint64 command_buffer_id, ' + 'GLuint64 release_count', + 'client_test': False, }, 'InitializeDiscardableTextureCHROMIUM': { 'type': 'Custom',
diff --git a/gpu/command_buffer/client/client_test_helper.h b/gpu/command_buffer/client/client_test_helper.h index eebbd286..9008bde 100644 --- a/gpu/command_buffer/client/client_test_helper.h +++ b/gpu/command_buffer/client/client_test_helper.h
@@ -137,7 +137,7 @@ DoSignalSyncToken(sync_token, &callback); } - MOCK_METHOD1(WaitSyncToken, void(const SyncToken&)); + MOCK_METHOD1(WaitSyncTokenHint, void(const SyncToken&)); MOCK_METHOD1(CanWaitUnverifiedSyncToken, bool(const SyncToken&)); MOCK_METHOD2(CreateGpuFence, void(uint32_t gpu_fence_id, ClientGpuFence source));
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 1c531c2..b422c307 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -2734,6 +2734,16 @@ } } +void WaitSyncTokenCHROMIUM(GLint namespace_id, + GLuint64 command_buffer_id, + GLuint64 release_count) { + gles2::cmds::WaitSyncTokenCHROMIUM* c = + GetCmdSpace<gles2::cmds::WaitSyncTokenCHROMIUM>(); + if (c) { + c->Init(namespace_id, command_buffer_id, release_count); + } +} + void UnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id, GLuint dest_id, GLint x,
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 253e934..9ee4ed69 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -1193,20 +1193,26 @@ } bool valid_value = false; + const bool flush_if_pending = + pname != GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT; switch (pname) { case GL_QUERY_RESULT_EXT: - if (!query->CheckResultsAvailable(helper_)) { + if (!query->CheckResultsAvailable(helper_, flush_if_pending)) { helper_->WaitForToken(query->token()); - if (!query->CheckResultsAvailable(helper_)) { + if (!query->CheckResultsAvailable(helper_, flush_if_pending)) { FinishHelper(); - CHECK(query->CheckResultsAvailable(helper_)); + CHECK(query->CheckResultsAvailable(helper_, flush_if_pending)); } } *params = query->GetResult(); valid_value = true; break; case GL_QUERY_RESULT_AVAILABLE_EXT: - *params = query->CheckResultsAvailable(helper_); + *params = query->CheckResultsAvailable(helper_, flush_if_pending); + valid_value = true; + break; + case GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT: + *params = query->CheckResultsAvailable(helper_, flush_if_pending); valid_value = true; break; default: @@ -6300,9 +6306,14 @@ return; } + helper_->WaitSyncTokenCHROMIUM( + static_cast<GLint>(sync_token.namespace_id()), + sync_token.command_buffer_id().GetUnsafeValue(), + sync_token.release_count()); + // Enqueue sync token in flush after inserting command so that it's not // included in an automatic flush. - gpu_control_->WaitSyncToken(verified_sync_token); + gpu_control_->WaitSyncTokenHint(verified_sync_token); } namespace {
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index 660aced8..5d9c7af 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -3931,9 +3931,12 @@ struct Cmds { cmds::InsertFenceSyncCHROMIUM insert_fence_sync; + cmds::WaitSyncTokenCHROMIUM wait_sync_token; }; Cmds expected; expected.insert_fence_sync.Init(kFenceSync); + expected.wait_sync_token.Init(kNamespaceId, kCommandBufferId.GetUnsafeValue(), + kFenceSync); EXPECT_CALL(*gpu_control_, GetNamespaceID()).WillOnce(Return(kNamespaceId)); EXPECT_CALL(*gpu_control_, GetCommandBufferID()) @@ -3943,7 +3946,7 @@ EXPECT_CALL(*gpu_control_, EnsureWorkVisible()); gl_->GenSyncTokenCHROMIUM(sync_token_data); - EXPECT_CALL(*gpu_control_, WaitSyncToken(sync_token)); + EXPECT_CALL(*gpu_control_, WaitSyncTokenHint(sync_token)); gl_->WaitSyncTokenCHROMIUM(sync_token_data); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); }
diff --git a/gpu/command_buffer/client/gpu_control.h b/gpu/command_buffer/client/gpu_control.h index a1191f8..8e3954c 100644 --- a/gpu/command_buffer/client/gpu_control.h +++ b/gpu/command_buffer/client/gpu_control.h
@@ -105,9 +105,11 @@ base::OnceClosure callback) = 0; // This allows the command buffer proxy to mark the next flush with sync token - // dependencies for the gpu scheduler, or to block prior to the flush in case - // of android webview. - virtual void WaitSyncToken(const SyncToken& sync_token) = 0; + // dependencies for the gpu scheduler. This is used in addition to the + // WaitSyncToken command in the command buffer which is still needed. For + // example, the WaitSyncToken command is used to pull texture updates when + // used in conjunction with MailboxManagerSync. + virtual void WaitSyncTokenHint(const SyncToken& sync_token) = 0; // Under some circumstances a sync token may be used which has not been // verified to have been flushed. For example, fence syncs queued on the same
diff --git a/gpu/command_buffer/client/query_tracker.cc b/gpu/command_buffer/client/query_tracker.cc index 400807d..ef8a972 100644 --- a/gpu/command_buffer/client/query_tracker.cc +++ b/gpu/command_buffer/client/query_tracker.cc
@@ -203,8 +203,8 @@ MarkAsPending(client->cmd_buffer_helper()->InsertToken(), submit_count); } -bool QueryTracker::Query::CheckResultsAvailable( - CommandBufferHelper* helper) { +bool QueryTracker::Query::CheckResultsAvailable(CommandBufferHelper* helper, + bool flush_if_pending) { if (Pending()) { bool processed_all = base::subtle::Acquire_Load( &info_.sync->process_count) == submit_count(); @@ -236,7 +236,8 @@ } state_ = kComplete; } else { - if ((helper->flush_generation() - flush_count_ - 1) >= 0x80000000) { + if (flush_if_pending && + (helper->flush_generation() - flush_count_ - 1) >= 0x80000000) { helper->Flush(); } else { // Insert no-ops so that eventually the GPU process will see more work.
diff --git a/gpu/command_buffer/client/query_tracker.h b/gpu/command_buffer/client/query_tracker.h index 5c12fb6d..1596e985 100644 --- a/gpu/command_buffer/client/query_tracker.h +++ b/gpu/command_buffer/client/query_tracker.h
@@ -170,7 +170,12 @@ return state_ == kPending; } - bool CheckResultsAvailable(CommandBufferHelper* helper); + // Checks whether the result of this query is available. + // If the result is pending and |flush_if_pending| is true, this will ensure + // that at least the commands up till the EndQuery for this query are + // flushed. + bool CheckResultsAvailable(CommandBufferHelper* helper, + bool flush_if_pending); uint64_t GetResult() const;
diff --git a/gpu/command_buffer/client/query_tracker_unittest.cc b/gpu/command_buffer/client/query_tracker_unittest.cc index 48d6ba5..01a1460 100644 --- a/gpu/command_buffer/client/query_tracker_unittest.cc +++ b/gpu/command_buffer/client/query_tracker_unittest.cc
@@ -301,19 +301,30 @@ // Store FlushGeneration count after EndQuery is called uint32_t gen1 = GetFlushGeneration(); - // Check CheckResultsAvailable. - EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); + bool flush_if_pending = false; + EXPECT_FALSE(query->CheckResultsAvailable(helper_.get(), flush_if_pending)); EXPECT_FALSE(query->NeverUsed()); EXPECT_TRUE(query->Pending()); + // No flush should happen if |flush_if_pending| is false. uint32_t gen2 = GetFlushGeneration(); + EXPECT_EQ(gen1, gen2); + + flush_if_pending = true; + + // Check CheckResultsAvailable. + EXPECT_FALSE(query->CheckResultsAvailable(helper_.get(), flush_if_pending)); + EXPECT_FALSE(query->NeverUsed()); + EXPECT_TRUE(query->Pending()); + + gen2 = GetFlushGeneration(); EXPECT_NE(gen1, gen2); // Repeated calls to CheckResultsAvailable should not flush unnecessarily - EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); + EXPECT_FALSE(query->CheckResultsAvailable(helper_.get(), flush_if_pending)); gen1 = GetFlushGeneration(); EXPECT_EQ(gen1, gen2); - EXPECT_FALSE(query->CheckResultsAvailable(helper_.get())); + EXPECT_FALSE(query->CheckResultsAvailable(helper_.get(), flush_if_pending)); gen1 = GetFlushGeneration(); EXPECT_EQ(gen1, gen2); @@ -323,7 +334,7 @@ sync->result = kResult; // Check CheckResultsAvailable. - EXPECT_TRUE(query->CheckResultsAvailable(helper_.get())); + EXPECT_TRUE(query->CheckResultsAvailable(helper_.get(), flush_if_pending)); EXPECT_EQ(kResult, query->GetResult()); EXPECT_FALSE(query->NeverUsed()); EXPECT_FALSE(query->Pending());
diff --git a/gpu/command_buffer/client/raster_cmd_helper_autogen.h b/gpu/command_buffer/client/raster_cmd_helper_autogen.h index d513c791..ee345a055 100644 --- a/gpu/command_buffer/client/raster_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/raster_cmd_helper_autogen.h
@@ -103,6 +103,16 @@ } } +void WaitSyncTokenCHROMIUM(GLint namespace_id, + GLuint64 command_buffer_id, + GLuint64 release_count) { + raster::cmds::WaitSyncTokenCHROMIUM* c = + GetCmdSpace<raster::cmds::WaitSyncTokenCHROMIUM>(); + if (c) { + c->Init(namespace_id, command_buffer_id, release_count); + } +} + void UnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id, GLuint dest_id, GLint x,
diff --git a/gpu/command_buffer/client/raster_implementation.cc b/gpu/command_buffer/client/raster_implementation.cc index e016b1e..692cfd7 100644 --- a/gpu/command_buffer/client/raster_implementation.cc +++ b/gpu/command_buffer/client/raster_implementation.cc
@@ -690,20 +690,22 @@ } bool valid_value = false; + const bool flush_if_pending = + pname != GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT; switch (pname) { case GL_QUERY_RESULT_EXT: - if (!query->CheckResultsAvailable(helper_)) { + if (!query->CheckResultsAvailable(helper_, flush_if_pending)) { helper_->WaitForToken(query->token()); - if (!query->CheckResultsAvailable(helper_)) { + if (!query->CheckResultsAvailable(helper_, flush_if_pending)) { FinishHelper(); - CHECK(query->CheckResultsAvailable(helper_)); + CHECK(query->CheckResultsAvailable(helper_, flush_if_pending)); } } *params = query->GetResult(); valid_value = true; break; case GL_QUERY_RESULT_AVAILABLE_EXT: - *params = query->CheckResultsAvailable(helper_); + *params = query->CheckResultsAvailable(helper_, flush_if_pending); valid_value = true; break; default: @@ -955,7 +957,14 @@ return; } - gpu_control_->WaitSyncToken(verified_sync_token); + helper_->WaitSyncTokenCHROMIUM( + static_cast<GLint>(sync_token.namespace_id()), + sync_token.command_buffer_id().GetUnsafeValue(), + sync_token.release_count()); + + // Enqueue sync token in flush after inserting command so that it's not + // included in an automatic flush. + gpu_control_->WaitSyncTokenHint(verified_sync_token); } namespace {
diff --git a/gpu/command_buffer/client/raster_implementation_unittest.cc b/gpu/command_buffer/client/raster_implementation_unittest.cc index f3edff0b..662a39a 100644 --- a/gpu/command_buffer/client/raster_implementation_unittest.cc +++ b/gpu/command_buffer/client/raster_implementation_unittest.cc
@@ -736,9 +736,12 @@ struct Cmds { cmds::InsertFenceSyncCHROMIUM insert_fence_sync; + cmds::WaitSyncTokenCHROMIUM wait_sync_token; }; Cmds expected; expected.insert_fence_sync.Init(kFenceSync); + expected.wait_sync_token.Init(kNamespaceId, kCommandBufferId.GetUnsafeValue(), + kFenceSync); EXPECT_CALL(*gpu_control_, GetNamespaceID()).WillOnce(Return(kNamespaceId)); EXPECT_CALL(*gpu_control_, GetCommandBufferID()) @@ -748,7 +751,7 @@ EXPECT_CALL(*gpu_control_, EnsureWorkVisible()); gl_->GenSyncTokenCHROMIUM(sync_token_data); - EXPECT_CALL(*gpu_control_, WaitSyncToken(sync_token)); + EXPECT_CALL(*gpu_control_, WaitSyncTokenHint(sync_token)); gl_->WaitSyncTokenCHROMIUM(sync_token_data); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); }
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 148c87c..29c250c 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -13519,6 +13519,73 @@ static_assert(offsetof(InsertFenceSyncCHROMIUM, release_count_1) == 8, "offset of InsertFenceSyncCHROMIUM release_count_1 should be 8"); +struct WaitSyncTokenCHROMIUM { + typedef WaitSyncTokenCHROMIUM ValueType; + static const CommandId kCmdId = kWaitSyncTokenCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLint _namespace_id, + GLuint64 _command_buffer_id, + GLuint64 _release_count) { + SetHeader(); + namespace_id = _namespace_id; + GLES2Util::MapUint64ToTwoUint32(static_cast<uint64_t>(_command_buffer_id), + &command_buffer_id_0, &command_buffer_id_1); + GLES2Util::MapUint64ToTwoUint32(static_cast<uint64_t>(_release_count), + &release_count_0, &release_count_1); + } + + void* Set(void* cmd, + GLint _namespace_id, + GLuint64 _command_buffer_id, + GLuint64 _release_count) { + static_cast<ValueType*>(cmd)->Init(_namespace_id, _command_buffer_id, + _release_count); + return NextCmdAddress<ValueType>(cmd); + } + + GLuint64 command_buffer_id() const volatile { + return static_cast<GLuint64>(GLES2Util::MapTwoUint32ToUint64( + command_buffer_id_0, command_buffer_id_1)); + } + + GLuint64 release_count() const volatile { + return static_cast<GLuint64>( + GLES2Util::MapTwoUint32ToUint64(release_count_0, release_count_1)); + } + + gpu::CommandHeader header; + int32_t namespace_id; + uint32_t command_buffer_id_0; + uint32_t command_buffer_id_1; + uint32_t release_count_0; + uint32_t release_count_1; +}; + +static_assert(sizeof(WaitSyncTokenCHROMIUM) == 24, + "size of WaitSyncTokenCHROMIUM should be 24"); +static_assert(offsetof(WaitSyncTokenCHROMIUM, header) == 0, + "offset of WaitSyncTokenCHROMIUM header should be 0"); +static_assert(offsetof(WaitSyncTokenCHROMIUM, namespace_id) == 4, + "offset of WaitSyncTokenCHROMIUM namespace_id should be 4"); +static_assert( + offsetof(WaitSyncTokenCHROMIUM, command_buffer_id_0) == 8, + "offset of WaitSyncTokenCHROMIUM command_buffer_id_0 should be 8"); +static_assert( + offsetof(WaitSyncTokenCHROMIUM, command_buffer_id_1) == 12, + "offset of WaitSyncTokenCHROMIUM command_buffer_id_1 should be 12"); +static_assert(offsetof(WaitSyncTokenCHROMIUM, release_count_0) == 16, + "offset of WaitSyncTokenCHROMIUM release_count_0 should be 16"); +static_assert(offsetof(WaitSyncTokenCHROMIUM, release_count_1) == 20, + "offset of WaitSyncTokenCHROMIUM release_count_1 should be 20"); + struct UnpremultiplyAndDitherCopyCHROMIUM { typedef UnpremultiplyAndDitherCopyCHROMIUM ValueType; static const CommandId kCmdId = kUnpremultiplyAndDitherCopyCHROMIUM;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index ccb500d..ad5eec7 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -4520,6 +4520,21 @@ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, WaitSyncTokenCHROMIUM) { + cmds::WaitSyncTokenCHROMIUM& cmd = + *GetBufferAs<cmds::WaitSyncTokenCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(11), static_cast<GLuint64>(12), + static_cast<GLuint64>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::WaitSyncTokenCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(11), cmd.namespace_id); + EXPECT_EQ(static_cast<GLuint64>(12), cmd.command_buffer_id()); + EXPECT_EQ(static_cast<GLuint64>(13), cmd.release_count()); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, UnpremultiplyAndDitherCopyCHROMIUM) { cmds::UnpremultiplyAndDitherCopyCHROMIUM& cmd = *GetBufferAs<cmds::UnpremultiplyAndDitherCopyCHROMIUM>();
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index b0ca0c4..5d8a9131 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -290,63 +290,64 @@ OP(DiscardFramebufferEXTImmediate) /* 531 */ \ OP(LoseContextCHROMIUM) /* 532 */ \ OP(InsertFenceSyncCHROMIUM) /* 533 */ \ - OP(UnpremultiplyAndDitherCopyCHROMIUM) /* 534 */ \ - OP(DrawBuffersEXTImmediate) /* 535 */ \ - OP(DiscardBackbufferCHROMIUM) /* 536 */ \ - OP(ScheduleOverlayPlaneCHROMIUM) /* 537 */ \ - OP(ScheduleCALayerSharedStateCHROMIUM) /* 538 */ \ - OP(ScheduleCALayerCHROMIUM) /* 539 */ \ - OP(ScheduleCALayerInUseQueryCHROMIUMImmediate) /* 540 */ \ - OP(CommitOverlayPlanesCHROMIUM) /* 541 */ \ - OP(FlushDriverCachesCHROMIUM) /* 542 */ \ - OP(ScheduleDCLayerSharedStateCHROMIUM) /* 543 */ \ - OP(ScheduleDCLayerCHROMIUM) /* 544 */ \ - OP(MatrixLoadfCHROMIUMImmediate) /* 545 */ \ - OP(MatrixLoadIdentityCHROMIUM) /* 546 */ \ - OP(GenPathsCHROMIUM) /* 547 */ \ - OP(DeletePathsCHROMIUM) /* 548 */ \ - OP(IsPathCHROMIUM) /* 549 */ \ - OP(PathCommandsCHROMIUM) /* 550 */ \ - OP(PathParameterfCHROMIUM) /* 551 */ \ - OP(PathParameteriCHROMIUM) /* 552 */ \ - OP(PathStencilFuncCHROMIUM) /* 553 */ \ - OP(StencilFillPathCHROMIUM) /* 554 */ \ - OP(StencilStrokePathCHROMIUM) /* 555 */ \ - OP(CoverFillPathCHROMIUM) /* 556 */ \ - OP(CoverStrokePathCHROMIUM) /* 557 */ \ - OP(StencilThenCoverFillPathCHROMIUM) /* 558 */ \ - OP(StencilThenCoverStrokePathCHROMIUM) /* 559 */ \ - OP(StencilFillPathInstancedCHROMIUM) /* 560 */ \ - OP(StencilStrokePathInstancedCHROMIUM) /* 561 */ \ - OP(CoverFillPathInstancedCHROMIUM) /* 562 */ \ - OP(CoverStrokePathInstancedCHROMIUM) /* 563 */ \ - OP(StencilThenCoverFillPathInstancedCHROMIUM) /* 564 */ \ - OP(StencilThenCoverStrokePathInstancedCHROMIUM) /* 565 */ \ - OP(BindFragmentInputLocationCHROMIUMBucket) /* 566 */ \ - OP(ProgramPathFragmentInputGenCHROMIUM) /* 567 */ \ - OP(CoverageModulationCHROMIUM) /* 568 */ \ - OP(BlendBarrierKHR) /* 569 */ \ - OP(ApplyScreenSpaceAntialiasingCHROMIUM) /* 570 */ \ - OP(BindFragDataLocationIndexedEXTBucket) /* 571 */ \ - OP(BindFragDataLocationEXTBucket) /* 572 */ \ - OP(GetFragDataIndexEXT) /* 573 */ \ - OP(UniformMatrix4fvStreamTextureMatrixCHROMIUMImmediate) /* 574 */ \ - OP(OverlayPromotionHintCHROMIUM) /* 575 */ \ - OP(SwapBuffersWithBoundsCHROMIUMImmediate) /* 576 */ \ - OP(SetDrawRectangleCHROMIUM) /* 577 */ \ - OP(SetEnableDCLayersCHROMIUM) /* 578 */ \ - OP(InitializeDiscardableTextureCHROMIUM) /* 579 */ \ - OP(UnlockDiscardableTextureCHROMIUM) /* 580 */ \ - OP(LockDiscardableTextureCHROMIUM) /* 581 */ \ - OP(TexStorage2DImageCHROMIUM) /* 582 */ \ - OP(SetColorSpaceMetadataCHROMIUM) /* 583 */ \ - OP(WindowRectanglesEXTImmediate) /* 584 */ \ - OP(CreateGpuFenceINTERNAL) /* 585 */ \ - OP(WaitGpuFenceCHROMIUM) /* 586 */ \ - OP(DestroyGpuFenceCHROMIUM) /* 587 */ \ - OP(SetReadbackBufferShadowAllocationINTERNAL) /* 588 */ \ - OP(FramebufferTextureMultiviewLayeredANGLE) /* 589 */ \ - OP(MaxShaderCompilerThreadsKHR) /* 590 */ + OP(WaitSyncTokenCHROMIUM) /* 534 */ \ + OP(UnpremultiplyAndDitherCopyCHROMIUM) /* 535 */ \ + OP(DrawBuffersEXTImmediate) /* 536 */ \ + OP(DiscardBackbufferCHROMIUM) /* 537 */ \ + OP(ScheduleOverlayPlaneCHROMIUM) /* 538 */ \ + OP(ScheduleCALayerSharedStateCHROMIUM) /* 539 */ \ + OP(ScheduleCALayerCHROMIUM) /* 540 */ \ + OP(ScheduleCALayerInUseQueryCHROMIUMImmediate) /* 541 */ \ + OP(CommitOverlayPlanesCHROMIUM) /* 542 */ \ + OP(FlushDriverCachesCHROMIUM) /* 543 */ \ + OP(ScheduleDCLayerSharedStateCHROMIUM) /* 544 */ \ + OP(ScheduleDCLayerCHROMIUM) /* 545 */ \ + OP(MatrixLoadfCHROMIUMImmediate) /* 546 */ \ + OP(MatrixLoadIdentityCHROMIUM) /* 547 */ \ + OP(GenPathsCHROMIUM) /* 548 */ \ + OP(DeletePathsCHROMIUM) /* 549 */ \ + OP(IsPathCHROMIUM) /* 550 */ \ + OP(PathCommandsCHROMIUM) /* 551 */ \ + OP(PathParameterfCHROMIUM) /* 552 */ \ + OP(PathParameteriCHROMIUM) /* 553 */ \ + OP(PathStencilFuncCHROMIUM) /* 554 */ \ + OP(StencilFillPathCHROMIUM) /* 555 */ \ + OP(StencilStrokePathCHROMIUM) /* 556 */ \ + OP(CoverFillPathCHROMIUM) /* 557 */ \ + OP(CoverStrokePathCHROMIUM) /* 558 */ \ + OP(StencilThenCoverFillPathCHROMIUM) /* 559 */ \ + OP(StencilThenCoverStrokePathCHROMIUM) /* 560 */ \ + OP(StencilFillPathInstancedCHROMIUM) /* 561 */ \ + OP(StencilStrokePathInstancedCHROMIUM) /* 562 */ \ + OP(CoverFillPathInstancedCHROMIUM) /* 563 */ \ + OP(CoverStrokePathInstancedCHROMIUM) /* 564 */ \ + OP(StencilThenCoverFillPathInstancedCHROMIUM) /* 565 */ \ + OP(StencilThenCoverStrokePathInstancedCHROMIUM) /* 566 */ \ + OP(BindFragmentInputLocationCHROMIUMBucket) /* 567 */ \ + OP(ProgramPathFragmentInputGenCHROMIUM) /* 568 */ \ + OP(CoverageModulationCHROMIUM) /* 569 */ \ + OP(BlendBarrierKHR) /* 570 */ \ + OP(ApplyScreenSpaceAntialiasingCHROMIUM) /* 571 */ \ + OP(BindFragDataLocationIndexedEXTBucket) /* 572 */ \ + OP(BindFragDataLocationEXTBucket) /* 573 */ \ + OP(GetFragDataIndexEXT) /* 574 */ \ + OP(UniformMatrix4fvStreamTextureMatrixCHROMIUMImmediate) /* 575 */ \ + OP(OverlayPromotionHintCHROMIUM) /* 576 */ \ + OP(SwapBuffersWithBoundsCHROMIUMImmediate) /* 577 */ \ + OP(SetDrawRectangleCHROMIUM) /* 578 */ \ + OP(SetEnableDCLayersCHROMIUM) /* 579 */ \ + OP(InitializeDiscardableTextureCHROMIUM) /* 580 */ \ + OP(UnlockDiscardableTextureCHROMIUM) /* 581 */ \ + OP(LockDiscardableTextureCHROMIUM) /* 582 */ \ + OP(TexStorage2DImageCHROMIUM) /* 583 */ \ + OP(SetColorSpaceMetadataCHROMIUM) /* 584 */ \ + OP(WindowRectanglesEXTImmediate) /* 585 */ \ + OP(CreateGpuFenceINTERNAL) /* 586 */ \ + OP(WaitGpuFenceCHROMIUM) /* 587 */ \ + OP(DestroyGpuFenceCHROMIUM) /* 588 */ \ + OP(SetReadbackBufferShadowAllocationINTERNAL) /* 589 */ \ + OP(FramebufferTextureMultiviewLayeredANGLE) /* 590 */ \ + OP(MaxShaderCompilerThreadsKHR) /* 591 */ enum CommandId { kOneBeforeStartPoint =
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index 5129de10..b3ce56f 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -1732,6 +1732,9 @@ 0x8867, "GL_QUERY_RESULT_AVAILABLE_EXT", }, { + 0x8868, "GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT", + }, + { 0x8869, "GL_MAX_VERTEX_ATTRIBS", }, { @@ -5696,6 +5699,8 @@ static const EnumToString string_table[] = { {GL_QUERY_RESULT_EXT, "GL_QUERY_RESULT_EXT"}, {GL_QUERY_RESULT_AVAILABLE_EXT, "GL_QUERY_RESULT_AVAILABLE_EXT"}, + {GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT, + "GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT"}, }; return GLES2Util::GetQualifiedEnumString(string_table, arraysize(string_table), value);
diff --git a/gpu/command_buffer/common/raster_cmd_format_autogen.h b/gpu/command_buffer/common/raster_cmd_format_autogen.h index 3ce82fa..075d6a9 100644 --- a/gpu/command_buffer/common/raster_cmd_format_autogen.h +++ b/gpu/command_buffer/common/raster_cmd_format_autogen.h
@@ -446,6 +446,75 @@ static_assert(offsetof(InsertFenceSyncCHROMIUM, release_count_1) == 8, "offset of InsertFenceSyncCHROMIUM release_count_1 should be 8"); +struct WaitSyncTokenCHROMIUM { + typedef WaitSyncTokenCHROMIUM ValueType; + static const CommandId kCmdId = kWaitSyncTokenCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLint _namespace_id, + GLuint64 _command_buffer_id, + GLuint64 _release_count) { + SetHeader(); + namespace_id = _namespace_id; + gles2::GLES2Util::MapUint64ToTwoUint32( + static_cast<uint64_t>(_command_buffer_id), &command_buffer_id_0, + &command_buffer_id_1); + gles2::GLES2Util::MapUint64ToTwoUint32( + static_cast<uint64_t>(_release_count), &release_count_0, + &release_count_1); + } + + void* Set(void* cmd, + GLint _namespace_id, + GLuint64 _command_buffer_id, + GLuint64 _release_count) { + static_cast<ValueType*>(cmd)->Init(_namespace_id, _command_buffer_id, + _release_count); + return NextCmdAddress<ValueType>(cmd); + } + + GLuint64 command_buffer_id() const volatile { + return static_cast<GLuint64>(gles2::GLES2Util::MapTwoUint32ToUint64( + command_buffer_id_0, command_buffer_id_1)); + } + + GLuint64 release_count() const volatile { + return static_cast<GLuint64>(gles2::GLES2Util::MapTwoUint32ToUint64( + release_count_0, release_count_1)); + } + + gpu::CommandHeader header; + int32_t namespace_id; + uint32_t command_buffer_id_0; + uint32_t command_buffer_id_1; + uint32_t release_count_0; + uint32_t release_count_1; +}; + +static_assert(sizeof(WaitSyncTokenCHROMIUM) == 24, + "size of WaitSyncTokenCHROMIUM should be 24"); +static_assert(offsetof(WaitSyncTokenCHROMIUM, header) == 0, + "offset of WaitSyncTokenCHROMIUM header should be 0"); +static_assert(offsetof(WaitSyncTokenCHROMIUM, namespace_id) == 4, + "offset of WaitSyncTokenCHROMIUM namespace_id should be 4"); +static_assert( + offsetof(WaitSyncTokenCHROMIUM, command_buffer_id_0) == 8, + "offset of WaitSyncTokenCHROMIUM command_buffer_id_0 should be 8"); +static_assert( + offsetof(WaitSyncTokenCHROMIUM, command_buffer_id_1) == 12, + "offset of WaitSyncTokenCHROMIUM command_buffer_id_1 should be 12"); +static_assert(offsetof(WaitSyncTokenCHROMIUM, release_count_0) == 16, + "offset of WaitSyncTokenCHROMIUM release_count_0 should be 16"); +static_assert(offsetof(WaitSyncTokenCHROMIUM, release_count_1) == 20, + "offset of WaitSyncTokenCHROMIUM release_count_1 should be 20"); + struct UnpremultiplyAndDitherCopyCHROMIUM { typedef UnpremultiplyAndDitherCopyCHROMIUM ValueType; static const CommandId kCmdId = kUnpremultiplyAndDitherCopyCHROMIUM;
diff --git a/gpu/command_buffer/common/raster_cmd_format_test_autogen.h b/gpu/command_buffer/common/raster_cmd_format_test_autogen.h index a9051c0..58d0f73 100644 --- a/gpu/command_buffer/common/raster_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/raster_cmd_format_test_autogen.h
@@ -159,6 +159,21 @@ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(RasterFormatTest, WaitSyncTokenCHROMIUM) { + cmds::WaitSyncTokenCHROMIUM& cmd = + *GetBufferAs<cmds::WaitSyncTokenCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLint>(11), static_cast<GLuint64>(12), + static_cast<GLuint64>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::WaitSyncTokenCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLint>(11), cmd.namespace_id); + EXPECT_EQ(static_cast<GLuint64>(12), cmd.command_buffer_id()); + EXPECT_EQ(static_cast<GLuint64>(13), cmd.release_count()); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(RasterFormatTest, UnpremultiplyAndDitherCopyCHROMIUM) { cmds::UnpremultiplyAndDitherCopyCHROMIUM& cmd = *GetBufferAs<cmds::UnpremultiplyAndDitherCopyCHROMIUM>();
diff --git a/gpu/command_buffer/common/raster_cmd_ids_autogen.h b/gpu/command_buffer/common/raster_cmd_ids_autogen.h index 52c2507..39f0670 100644 --- a/gpu/command_buffer/common/raster_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/raster_cmd_ids_autogen.h
@@ -23,26 +23,27 @@ OP(EndQueryEXT) /* 264 */ \ OP(LoseContextCHROMIUM) /* 265 */ \ OP(InsertFenceSyncCHROMIUM) /* 266 */ \ - OP(UnpremultiplyAndDitherCopyCHROMIUM) /* 267 */ \ - OP(BeginRasterCHROMIUMImmediate) /* 268 */ \ - OP(RasterCHROMIUM) /* 269 */ \ - OP(EndRasterCHROMIUM) /* 270 */ \ - OP(CreateTransferCacheEntryINTERNAL) /* 271 */ \ - OP(DeleteTransferCacheEntryINTERNAL) /* 272 */ \ - OP(UnlockTransferCacheEntryINTERNAL) /* 273 */ \ - OP(CreateTexture) /* 274 */ \ - OP(SetColorSpaceMetadata) /* 275 */ \ - OP(ProduceTextureDirectImmediate) /* 276 */ \ - OP(CreateAndConsumeTextureINTERNALImmediate) /* 277 */ \ - OP(TexParameteri) /* 278 */ \ - OP(BindTexImage2DCHROMIUM) /* 279 */ \ - OP(ReleaseTexImage2DCHROMIUM) /* 280 */ \ - OP(TexStorage2D) /* 281 */ \ - OP(CopySubTexture) /* 282 */ \ - OP(TraceBeginCHROMIUM) /* 283 */ \ - OP(TraceEndCHROMIUM) /* 284 */ \ - OP(SetActiveURLCHROMIUM) /* 285 */ \ - OP(ResetActiveURLCHROMIUM) /* 286 */ + OP(WaitSyncTokenCHROMIUM) /* 267 */ \ + OP(UnpremultiplyAndDitherCopyCHROMIUM) /* 268 */ \ + OP(BeginRasterCHROMIUMImmediate) /* 269 */ \ + OP(RasterCHROMIUM) /* 270 */ \ + OP(EndRasterCHROMIUM) /* 271 */ \ + OP(CreateTransferCacheEntryINTERNAL) /* 272 */ \ + OP(DeleteTransferCacheEntryINTERNAL) /* 273 */ \ + OP(UnlockTransferCacheEntryINTERNAL) /* 274 */ \ + OP(CreateTexture) /* 275 */ \ + OP(SetColorSpaceMetadata) /* 276 */ \ + OP(ProduceTextureDirectImmediate) /* 277 */ \ + OP(CreateAndConsumeTextureINTERNALImmediate) /* 278 */ \ + OP(TexParameteri) /* 279 */ \ + OP(BindTexImage2DCHROMIUM) /* 280 */ \ + OP(ReleaseTexImage2DCHROMIUM) /* 281 */ \ + OP(TexStorage2D) /* 282 */ \ + OP(CopySubTexture) /* 283 */ \ + OP(TraceBeginCHROMIUM) /* 284 */ \ + OP(TraceEndCHROMIUM) /* 285 */ \ + OP(SetActiveURLCHROMIUM) /* 286 */ \ + OP(ResetActiveURLCHROMIUM) /* 287 */ enum CommandId { kOneBeforeStartPoint =
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index 14d4dc2b..7578d60 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn
@@ -219,6 +219,7 @@ "shader_translator.h", "shader_translator_cache.cc", "shader_translator_cache.h", + "shared_image_backing.cc", "shared_image_backing.h", "shared_image_backing_factory.h", "shared_image_backing_factory_gl_texture.cc",
diff --git a/gpu/command_buffer/service/command_buffer_direct.cc b/gpu/command_buffer/service/command_buffer_direct.cc index 03fd9a5..8c7f861 100644 --- a/gpu/command_buffer/service/command_buffer_direct.cc +++ b/gpu/command_buffer/service/command_buffer_direct.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" +#include "gpu/command_buffer/service/sync_point_manager.h" #include "gpu/command_buffer/service/transfer_buffer_manager.h" namespace gpu { @@ -18,11 +19,37 @@ CommandBufferDirect::CommandBufferDirect( TransferBufferManager* transfer_buffer_manager) - : service_(this, transfer_buffer_manager), - command_buffer_id_( - CommandBufferId::FromUnsafeValue(g_next_command_buffer_id++)) {} + : CommandBufferDirect(transfer_buffer_manager, nullptr) {} -CommandBufferDirect::~CommandBufferDirect() = default; +CommandBufferDirect::CommandBufferDirect( + TransferBufferManager* transfer_buffer_manager, + SyncPointManager* sync_point_manager) + : service_(this, transfer_buffer_manager), + sync_point_manager_(sync_point_manager), + command_buffer_id_( + CommandBufferId::FromUnsafeValue(g_next_command_buffer_id++)) { + if (sync_point_manager_) { + sync_point_order_data_ = sync_point_manager_->CreateSyncPointOrderData(); + sync_point_client_state_ = sync_point_manager_->CreateSyncPointClientState( + GetNamespaceID(), GetCommandBufferID(), + sync_point_order_data_->sequence_id()); + } else { + sync_point_order_data_ = nullptr; + sync_point_client_state_ = nullptr; + } +} + +CommandBufferDirect::~CommandBufferDirect() { + sync_point_manager_ = nullptr; + if (sync_point_order_data_) { + sync_point_order_data_->Destroy(); + sync_point_order_data_ = nullptr; + } + if (sync_point_client_state_) { + sync_point_client_state_->Destroy(); + sync_point_client_state_ = nullptr; + } +} CommandBuffer::State CommandBufferDirect::GetLastState() { service_.UpdateState(); @@ -49,7 +76,32 @@ void CommandBufferDirect::Flush(int32_t put_offset) { DCHECK(handler_); + uint32_t order_num = 0; + if (sync_point_manager_) { + // If sync point manager is supported, assign order numbers to commands. + if (paused_order_num_) { + // Was previous paused, continue to process the order number. + order_num = paused_order_num_; + paused_order_num_ = 0; + } else { + order_num = sync_point_order_data_->GenerateUnprocessedOrderNumber(); + } + sync_point_order_data_->BeginProcessingOrderNumber(order_num); + } + + if (pause_commands_) { + // Do not process commands, simply store the current order number. + paused_order_num_ = order_num; + + sync_point_order_data_->PauseProcessingOrderNumber(order_num); + return; + } + service_.Flush(put_offset, handler_); + if (sync_point_manager_) { + // Finish processing order number here. + sync_point_order_data_->FinishProcessingOrderNumber(order_num); + } } void CommandBufferDirect::OrderingBarrier(int32_t put_offset) { @@ -83,7 +135,17 @@ const std::string& shader) {} void CommandBufferDirect::OnFenceSyncRelease(uint64_t release) { - NOTIMPLEMENTED(); + DCHECK(sync_point_client_state_); + service_.SetReleaseCount(release); + sync_point_client_state_->ReleaseFenceSync(release); +} + +bool CommandBufferDirect::OnWaitSyncToken(const gpu::SyncToken& sync_token) { + DCHECK(sync_point_manager_); + if (sync_point_manager_->IsSyncTokenReleased(sync_token)) + return false; + service_.SetScheduled(false); + return true; } void CommandBufferDirect::OnDescheduleUntilFinished() { @@ -96,6 +158,35 @@ void CommandBufferDirect::OnSwapBuffers(uint64_t swap_id, uint32_t flags) {} +gpu::CommandBufferNamespace CommandBufferDirect::GetNamespaceID() const { + return gpu::CommandBufferNamespace::IN_PROCESS; +} + +CommandBufferId CommandBufferDirect::GetCommandBufferID() const { + return command_buffer_id_; +} + +void CommandBufferDirect::SetCommandsPaused(bool paused) { + pause_commands_ = paused; +} + +void CommandBufferDirect::SignalSyncToken(const gpu::SyncToken& sync_token, + base::OnceClosure callback) { + if (sync_point_manager_) { + DCHECK(!paused_order_num_); + uint32_t order_num = + sync_point_order_data_->GenerateUnprocessedOrderNumber(); + sync_point_order_data_->BeginProcessingOrderNumber(order_num); + base::RepeatingClosure maybe_pass_callback = + base::AdaptCallbackForRepeating(std::move(callback)); + if (!sync_point_client_state_->Wait(sync_token, maybe_pass_callback)) + maybe_pass_callback.Run(); + sync_point_order_data_->FinishProcessingOrderNumber(order_num); + } else { + std::move(callback).Run(); + } +} + scoped_refptr<Buffer> CommandBufferDirect::CreateTransferBufferWithId( size_t size, int32_t id) {
diff --git a/gpu/command_buffer/service/command_buffer_direct.h b/gpu/command_buffer/service/command_buffer_direct.h index 0eec8e6..7897b08 100644 --- a/gpu/command_buffer/service/command_buffer_direct.h +++ b/gpu/command_buffer/service/command_buffer_direct.h
@@ -16,6 +16,10 @@ class AsyncAPIInterface; class TransferBufferManager; +class SyncPointClientState; +class SyncPointManager; +class SyncPointOrderData; +struct SyncToken; class GPU_EXPORT CommandBufferDirect : public CommandBuffer, public CommandBufferServiceClient, @@ -23,7 +27,10 @@ public: using MakeCurrentCallback = base::Callback<bool()>; + CommandBufferDirect(TransferBufferManager* transfer_buffer_manager, + SyncPointManager* sync_point_manager); explicit CommandBufferDirect(TransferBufferManager* transfer_buffer_manager); + ~CommandBufferDirect() override; void set_handler(AsyncAPIInterface* handler) { handler_ = handler; } @@ -49,11 +56,19 @@ void OnConsoleMessage(int32_t id, const std::string& message) override; void CacheShader(const std::string& key, const std::string& shader) override; void OnFenceSyncRelease(uint64_t release) override; + bool OnWaitSyncToken(const gpu::SyncToken&) override; void OnDescheduleUntilFinished() override; void OnRescheduleAfterFinished() override; void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override; void ScheduleGrContextCleanup() override {} + CommandBufferNamespace GetNamespaceID() const; + CommandBufferId GetCommandBufferID() const; + + void SetCommandsPaused(bool paused); + void SignalSyncToken(const gpu::SyncToken& sync_token, + base::OnceClosure callback); + scoped_refptr<Buffer> CreateTransferBufferWithId(size_t size, int32_t id); void SetGetOffsetForTest(int32_t get_offset) { @@ -62,7 +77,13 @@ private: CommandBufferService service_; + SyncPointManager* sync_point_manager_; + AsyncAPIInterface* handler_ = nullptr; + scoped_refptr<SyncPointOrderData> sync_point_order_data_; + scoped_refptr<SyncPointClientState> sync_point_client_state_; + bool pause_commands_ = false; + uint32_t paused_order_num_ = 0; const CommandBufferId command_buffer_id_; };
diff --git a/gpu/command_buffer/service/decoder_client.h b/gpu/command_buffer/service/decoder_client.h index c412e33..6715536 100644 --- a/gpu/command_buffer/service/decoder_client.h +++ b/gpu/command_buffer/service/decoder_client.h
@@ -14,6 +14,8 @@ namespace gpu { +struct SyncToken; + class GPU_EXPORT DecoderClient { public: virtual ~DecoderClient() = default; @@ -29,6 +31,14 @@ // reschedule waiting decoders. virtual void OnFenceSyncRelease(uint64_t release) = 0; + // Called when the decoder needs to wait on a sync token. If the wait is valid + // (fence sync is not released yet), the client must unschedule the command + // buffer and return true. The client is responsible for rescheduling the + // command buffer when the fence is released. If the wait is a noop (fence is + // already released) or invalid, the client must leave the command buffer + // scheduled, and return false. + virtual bool OnWaitSyncToken(const gpu::SyncToken&) = 0; + // Called when the decoder needs to be descheduled while waiting for a fence // completion. The client is responsible for descheduling the command buffer // before returning, and then calling PerformPollingWork periodically to test
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 12d9dafa..75a8b109 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -4970,10 +4970,12 @@ gpu_trace_commands_ = gpu_tracer_->IsTracing() && *gpu_decoder_category_; gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_; query_manager_->ProcessFrameBeginUpdates(); + query_manager_->BeginProcessingCommands(); } void GLES2DecoderImpl::EndDecoding() { gpu_tracer_->EndDecoding(); + query_manager_->EndProcessingCommands(); } ErrorState* GLES2DecoderImpl::GetErrorState() { @@ -16186,6 +16188,34 @@ return error::kNoError; } +error::Error GLES2DecoderImpl::HandleWaitSyncTokenCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::WaitSyncTokenCHROMIUM& c = + *static_cast<const volatile gles2::cmds::WaitSyncTokenCHROMIUM*>( + cmd_data); + + const gpu::CommandBufferNamespace kMinNamespaceId = + gpu::CommandBufferNamespace::INVALID; + const gpu::CommandBufferNamespace kMaxNamespaceId = + gpu::CommandBufferNamespace::NUM_COMMAND_BUFFER_NAMESPACES; + + gpu::CommandBufferNamespace namespace_id = + static_cast<gpu::CommandBufferNamespace>(c.namespace_id); + if ((namespace_id < static_cast<int32_t>(kMinNamespaceId)) || + (namespace_id >= static_cast<int32_t>(kMaxNamespaceId))) { + namespace_id = gpu::CommandBufferNamespace::INVALID; + } + const CommandBufferId command_buffer_id = + CommandBufferId::FromUnsafeValue(c.command_buffer_id()); + const uint64_t release = c.release_count(); + + gpu::SyncToken sync_token; + sync_token.Set(namespace_id, command_buffer_id, release); + return client_->OnWaitSyncToken(sync_token) ? error::kDeferCommandUntilLater + : error::kNoError; +} + error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM( uint32_t immediate_data_size, const volatile void* cmd_data) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index 42e5cf1..13b30ea1 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -4189,6 +4189,15 @@ return error::kNoError; } +error::Error GLES2DecoderPassthroughImpl::DoWaitSyncTokenCHROMIUM( + CommandBufferNamespace namespace_id, + CommandBufferId command_buffer_id, + GLuint64 release_count) { + SyncToken sync_token(namespace_id, command_buffer_id, release_count); + return client_->OnWaitSyncToken(sync_token) ? error::kDeferCommandUntilLater + : error::kNoError; +} + error::Error GLES2DecoderPassthroughImpl::DoDrawBuffersEXT( GLsizei count, const volatile GLenum* bufs) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc index dff256f..b694ab9 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers.cc
@@ -1685,6 +1685,31 @@ return DoInsertFenceSyncCHROMIUM(release_count); } +error::Error GLES2DecoderPassthroughImpl::HandleWaitSyncTokenCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::WaitSyncTokenCHROMIUM& c = + *static_cast<const volatile gles2::cmds::WaitSyncTokenCHROMIUM*>( + cmd_data); + CommandBufferNamespace namespace_id = + static_cast<gpu::CommandBufferNamespace>(c.namespace_id); + const uint64_t release_count = c.release_count(); + CommandBufferId command_buffer_id = + CommandBufferId::FromUnsafeValue(c.command_buffer_id()); + + const CommandBufferNamespace kMinNamespaceId = + CommandBufferNamespace::INVALID; + const CommandBufferNamespace kMaxNamespaceId = + CommandBufferNamespace::NUM_COMMAND_BUFFER_NAMESPACES; + if ((namespace_id < static_cast<int32_t>(kMinNamespaceId)) || + (namespace_id >= static_cast<int32_t>(kMaxNamespaceId))) { + namespace_id = gpu::CommandBufferNamespace::INVALID; + } + + return DoWaitSyncTokenCHROMIUM(namespace_id, command_buffer_id, + release_count); +} + error::Error GLES2DecoderPassthroughImpl::HandleDiscardBackbufferCHROMIUM( uint32_t immediate_data_size, const volatile void* cmd_data) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index f6b1a73..03fdfe5 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -141,6 +141,9 @@ void GLES2DecoderTestBase::CacheShader(const std::string& key, const std::string& shader) {} void GLES2DecoderTestBase::OnFenceSyncRelease(uint64_t release) {} +bool GLES2DecoderTestBase::OnWaitSyncToken(const gpu::SyncToken&) { + return false; +} void GLES2DecoderTestBase::OnDescheduleUntilFinished() {} void GLES2DecoderTestBase::OnRescheduleAfterFinished() {} void GLES2DecoderTestBase::OnSwapBuffers(uint64_t swap_id, uint32_t flags) {} @@ -2392,6 +2395,9 @@ void GLES2DecoderPassthroughTestBase::CacheShader(const std::string& key, const std::string& shader) {} void GLES2DecoderPassthroughTestBase::OnFenceSyncRelease(uint64_t release) {} +bool GLES2DecoderPassthroughTestBase::OnWaitSyncToken(const gpu::SyncToken&) { + return false; +} void GLES2DecoderPassthroughTestBase::OnDescheduleUntilFinished() {} void GLES2DecoderPassthroughTestBase::OnRescheduleAfterFinished() {} void GLES2DecoderPassthroughTestBase::OnSwapBuffers(uint64_t swap_id,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index 72113d1..28de0a1f 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -59,6 +59,7 @@ void OnConsoleMessage(int32_t id, const std::string& message) override; void CacheShader(const std::string& key, const std::string& shader) override; void OnFenceSyncRelease(uint64_t release) override; + bool OnWaitSyncToken(const gpu::SyncToken&) override; void OnDescheduleUntilFinished() override; void OnRescheduleAfterFinished() override; void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override; @@ -847,6 +848,7 @@ void OnConsoleMessage(int32_t id, const std::string& message) override; void CacheShader(const std::string& key, const std::string& shader) override; void OnFenceSyncRelease(uint64_t release) override; + bool OnWaitSyncToken(const gpu::SyncToken&) override; void OnDescheduleUntilFinished() override; void OnRescheduleAfterFinished() override; void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override;
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index fe157ec7..74e2dde 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -715,6 +715,7 @@ switch (value) { case GL_QUERY_RESULT_EXT: case GL_QUERY_RESULT_AVAILABLE_EXT: + case GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT: return true; } return false;
diff --git a/gpu/command_buffer/service/memory_program_cache_unittest.cc b/gpu/command_buffer/service/memory_program_cache_unittest.cc index 0aa22b2..d221cb7 100644 --- a/gpu/command_buffer/service/memory_program_cache_unittest.cc +++ b/gpu/command_buffer/service/memory_program_cache_unittest.cc
@@ -94,6 +94,7 @@ shader_cache_shader_ = shader; } void OnFenceSyncRelease(uint64_t release) override {} + bool OnWaitSyncToken(const gpu::SyncToken&) override { return false; } void OnDescheduleUntilFinished() override {} void OnRescheduleAfterFinished() override {} void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override {}
diff --git a/gpu/command_buffer/service/passthrough_program_cache_unittest.cc b/gpu/command_buffer/service/passthrough_program_cache_unittest.cc index a362e236..9deae3c 100644 --- a/gpu/command_buffer/service/passthrough_program_cache_unittest.cc +++ b/gpu/command_buffer/service/passthrough_program_cache_unittest.cc
@@ -44,6 +44,7 @@ void CacheShader(const std::string& key, const std::string& shader) override { } void OnFenceSyncRelease(uint64_t release) override {} + bool OnWaitSyncToken(const gpu::SyncToken&) override { return false; } void OnDescheduleUntilFinished() override {} void OnRescheduleAfterFinished() override {} void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override {}
diff --git a/gpu/command_buffer/service/program_manager_unittest.cc b/gpu/command_buffer/service/program_manager_unittest.cc index e2e55c7..a6a1e4c 100644 --- a/gpu/command_buffer/service/program_manager_unittest.cc +++ b/gpu/command_buffer/service/program_manager_unittest.cc
@@ -90,6 +90,7 @@ void CacheShader(const std::string& key, const std::string& shader) override { } void OnFenceSyncRelease(uint64_t release) override {} + bool OnWaitSyncToken(const gpu::SyncToken&) override { return false; } void OnDescheduleUntilFinished() override {} void OnRescheduleAfterFinished() override {} void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override {}
diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc index 994898de..588b119 100644 --- a/gpu/command_buffer/service/query_manager.cc +++ b/gpu/command_buffer/service/query_manager.cc
@@ -32,23 +32,48 @@ void Resume() override; void Process(bool did_finish) override; void Destroy(bool have_context) override; + void BeginProcessingCommands() override; + void EndProcessingCommands() override; protected: ~CommandsIssuedQuery() override; private: - base::TimeTicks begin_time_; + enum class CommandProcessingState { + // Used prior to receiving the Begin notification and after End which + // completes the query. + kNotStarted, + + // Used when the query is active and the commands with the associated + // context are being processed. + kProcessingCommands, + + // Used when the query is active but the associated context has been + // de-scheduled. + kNotProcessingCommands + }; + + void Reset(); + + CommandProcessingState command_processing_state_ = + CommandProcessingState::kNotStarted; + base::TimeDelta elapsed_time_; + base::TimeTicks begin_command_processing_time_; }; CommandsIssuedQuery::CommandsIssuedQuery(QueryManager* manager, GLenum target, scoped_refptr<gpu::Buffer> buffer, QuerySync* sync) - : Query(manager, target, std::move(buffer), sync) {} + : Query(manager, target, std::move(buffer), sync) { + Reset(); +} void CommandsIssuedQuery::Begin() { + DCHECK_EQ(command_processing_state_, CommandProcessingState::kNotStarted); + MarkAsActive(); - begin_time_ = base::TimeTicks::Now(); + BeginProcessingCommands(); } void CommandsIssuedQuery::Pause() { @@ -60,9 +85,20 @@ } void CommandsIssuedQuery::End(base::subtle::Atomic32 submit_count) { - const base::TimeDelta elapsed = base::TimeTicks::Now() - begin_time_; + base::TimeDelta elapsed = elapsed_time_; + if (begin_command_processing_time_ != base::TimeTicks()) + elapsed += base::TimeTicks::Now() - begin_command_processing_time_; + MarkAsPending(submit_count); MarkAsCompleted(elapsed.InMicroseconds()); + + Reset(); +} + +void CommandsIssuedQuery::Reset() { + command_processing_state_ = CommandProcessingState::kNotStarted; + begin_command_processing_time_ = base::TimeTicks(); + elapsed_time_ = base::TimeDelta(); } void CommandsIssuedQuery::QueryCounter(base::subtle::Atomic32 submit_count) { @@ -79,6 +115,29 @@ } } +void CommandsIssuedQuery::BeginProcessingCommands() { + DCHECK_NE(command_processing_state_, + CommandProcessingState::kProcessingCommands); + DCHECK_EQ(begin_command_processing_time_, base::TimeTicks()); + + command_processing_state_ = CommandProcessingState::kProcessingCommands; + begin_command_processing_time_ = base::TimeTicks::Now(); +} + +void CommandsIssuedQuery::EndProcessingCommands() { + DCHECK_NE(command_processing_state_, + CommandProcessingState::kNotProcessingCommands); + + // The query may been ended before all commands associated with the context + // were processed. + if (command_processing_state_ == CommandProcessingState::kNotStarted) + return; + + command_processing_state_ = CommandProcessingState::kNotProcessingCommands; + elapsed_time_ += base::TimeTicks::Now() - begin_command_processing_time_; + begin_command_processing_time_ = base::TimeTicks(); +} + CommandsIssuedQuery::~CommandsIssuedQuery() = default; class CommandsCompletedQuery : public QueryManager::Query { @@ -409,4 +468,14 @@ } } +void QueryManager::BeginProcessingCommands() { + for (std::pair<const GLenum, scoped_refptr<Query>>& it : active_queries_) + it.second->BeginProcessingCommands(); +} + +void QueryManager::EndProcessingCommands() { + for (std::pair<const GLenum, scoped_refptr<Query>>& it : active_queries_) + it.second->EndProcessingCommands(); +} + } // namespace gpu
diff --git a/gpu/command_buffer/service/query_manager.h b/gpu/command_buffer/service/query_manager.h index 355bd0c..1b6b8c57 100644 --- a/gpu/command_buffer/service/query_manager.h +++ b/gpu/command_buffer/service/query_manager.h
@@ -79,6 +79,9 @@ virtual void Destroy(bool have_context) = 0; + virtual void BeginProcessingCommands() {} + virtual void EndProcessingCommands() {} + void AddCallback(base::OnceClosure callback); protected: @@ -202,6 +205,9 @@ void PauseQueries(); void ResumeQueries(); + void BeginProcessingCommands(); + void EndProcessingCommands(); + // Processes pending queries. Returns false if any queries are pointing // to invalid shared memory. |did_finish| is true if this is called as // a result of calling glFinish().
diff --git a/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h index e41d3af3..2e25dac 100644 --- a/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h
@@ -20,6 +20,7 @@ switch (value) { case GL_QUERY_RESULT_EXT: case GL_QUERY_RESULT_AVAILABLE_EXT: + case GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT: return true; } return false;
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index 5636e9e..fcec23c 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -294,6 +294,7 @@ case kInsertFenceSyncCHROMIUM: case kRasterCHROMIUM: case kUnlockTransferCacheEntryINTERNAL: + case kWaitSyncTokenCHROMIUM: return true; default: return false; @@ -1471,10 +1472,12 @@ gpu_tracer_->BeginDecoding(); gpu_trace_commands_ = gpu_tracer_->IsTracing() && *gpu_decoder_category_; gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_; + query_manager_->BeginProcessingCommands(); } void RasterDecoderImpl::EndDecoding() { gpu_tracer_->EndDecoding(); + query_manager_->EndProcessingCommands(); } const char* RasterDecoderImpl::GetCommandName(unsigned int command_id) const { @@ -1855,6 +1858,34 @@ } } +error::Error RasterDecoderImpl::HandleWaitSyncTokenCHROMIUM( + uint32_t immediate_data_size, + const volatile void* cmd_data) { + const volatile gles2::cmds::WaitSyncTokenCHROMIUM& c = + *static_cast<const volatile gles2::cmds::WaitSyncTokenCHROMIUM*>( + cmd_data); + + static constexpr CommandBufferNamespace kMinNamespaceId = + CommandBufferNamespace::INVALID; + static constexpr CommandBufferNamespace kMaxNamespaceId = + CommandBufferNamespace::NUM_COMMAND_BUFFER_NAMESPACES; + + CommandBufferNamespace namespace_id = + static_cast<CommandBufferNamespace>(c.namespace_id); + if ((namespace_id < static_cast<int32_t>(kMinNamespaceId)) || + (namespace_id >= static_cast<int32_t>(kMaxNamespaceId))) { + namespace_id = CommandBufferNamespace::INVALID; + } + const CommandBufferId command_buffer_id = + CommandBufferId::FromUnsafeValue(c.command_buffer_id()); + const uint64_t release = c.release_count(); + + SyncToken sync_token; + sync_token.Set(namespace_id, command_buffer_id, release); + return client_->OnWaitSyncToken(sync_token) ? error::kDeferCommandUntilLater + : error::kNoError; +} + error::Error RasterDecoderImpl::HandleSetColorSpaceMetadata( uint32_t immediate_data_size, const volatile void* cmd_data) {
diff --git a/gpu/command_buffer/service/raster_decoder_unittest.cc b/gpu/command_buffer/service/raster_decoder_unittest.cc index 1d25d7f..403202e1 100644 --- a/gpu/command_buffer/service/raster_decoder_unittest.cc +++ b/gpu/command_buffer/service/raster_decoder_unittest.cc
@@ -581,6 +581,7 @@ void CacheShader(const std::string& key, const std::string& shader) override { } void OnFenceSyncRelease(uint64_t release) override {} + bool OnWaitSyncToken(const gpu::SyncToken&) override { return false; } void OnDescheduleUntilFinished() override {} void OnRescheduleAfterFinished() override {} void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override {}
diff --git a/gpu/command_buffer/service/raster_decoder_unittest_base.cc b/gpu/command_buffer/service/raster_decoder_unittest_base.cc index 1e2361b..0b05964 100644 --- a/gpu/command_buffer/service/raster_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/raster_decoder_unittest_base.cc
@@ -71,6 +71,9 @@ void RasterDecoderTestBase::CacheShader(const std::string& key, const std::string& shader) {} void RasterDecoderTestBase::OnFenceSyncRelease(uint64_t release) {} +bool RasterDecoderTestBase::OnWaitSyncToken(const gpu::SyncToken&) { + return false; +} void RasterDecoderTestBase::OnDescheduleUntilFinished() {} void RasterDecoderTestBase::OnRescheduleAfterFinished() {} void RasterDecoderTestBase::OnSwapBuffers(uint64_t swap_id, uint32_t flags) {}
diff --git a/gpu/command_buffer/service/raster_decoder_unittest_base.h b/gpu/command_buffer/service/raster_decoder_unittest_base.h index 60adc576..88baebb 100644 --- a/gpu/command_buffer/service/raster_decoder_unittest_base.h +++ b/gpu/command_buffer/service/raster_decoder_unittest_base.h
@@ -58,6 +58,7 @@ void OnConsoleMessage(int32_t id, const std::string& message) override; void CacheShader(const std::string& key, const std::string& shader) override; void OnFenceSyncRelease(uint64_t release) override; + bool OnWaitSyncToken(const gpu::SyncToken&) override; void OnDescheduleUntilFinished() override; void OnRescheduleAfterFinished() override; void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override;
diff --git a/gpu/command_buffer/service/shared_image_backing.cc b/gpu/command_buffer/service/shared_image_backing.cc new file mode 100644 index 0000000..ddfff04 --- /dev/null +++ b/gpu/command_buffer/service/shared_image_backing.cc
@@ -0,0 +1,26 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/command_buffer/service/shared_image_backing.h" + +namespace gpu { + +SharedImageBacking::SharedImageBacking(const Mailbox& mailbox, + viz::ResourceFormat format, + const gfx::Size& size, + const gfx::ColorSpace& color_space, + uint32_t usage) + : mailbox_(mailbox), + format_(format), + size_(size), + color_space_(color_space), + usage_(usage) {} + +SharedImageBacking::~SharedImageBacking() = default; + +size_t SharedImageBacking::EstimatedSize() const { + return 0; +} + +} // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_backing.h b/gpu/command_buffer/service/shared_image_backing.h index 07cdf4c1..c5519cd 100644 --- a/gpu/command_buffer/service/shared_image_backing.h +++ b/gpu/command_buffer/service/shared_image_backing.h
@@ -11,6 +11,13 @@ #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/size.h" +namespace base { +namespace trace_event { +class ProcessMemoryDump; +class MemoryAllocatorDump; +} // namespace trace_event +} // namespace base + namespace gpu { class MailboxManager; @@ -20,33 +27,42 @@ // TODO(ericrk): Add SharedImageRepresentation and Begin/End logic. class SharedImageBacking { public: - SharedImageBacking(viz::ResourceFormat format, + SharedImageBacking(const Mailbox& mailbox, + viz::ResourceFormat format, const gfx::Size& size, const gfx::ColorSpace& color_space, - uint32_t usage) - : format_(format), - size_(size), - color_space_(color_space), - usage_(usage) {} + uint32_t usage); - virtual ~SharedImageBacking() {} + virtual ~SharedImageBacking(); viz::ResourceFormat format() const { return format_; } const gfx::Size& size() const { return size_; } const gfx::ColorSpace& color_space() const { return color_space_; } uint32_t usage() const { return usage_; } + const Mailbox& mailbox() const { return mailbox_; } + + // Memory dump helpers: + // Returns the estimated size of the backing. If 0 is returned, the dump will + // be omitted. + virtual size_t EstimatedSize() const; + // Allows the backing to attach additional data to the dump or dump + // additional sub paths. + virtual void OnMemoryDump(const std::string& dump_name, + base::trace_event::MemoryAllocatorDump* dump, + base::trace_event::ProcessMemoryDump* pmd, + uint64_t client_tracing_id) {} // Prepares the backing for use with the legacy mailbox system. // TODO(ericrk): Remove this once the new codepath is complete. - virtual bool ProduceLegacyMailbox(const Mailbox& mailbox, - MailboxManager* mailbox_manager) = 0; + virtual bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) = 0; virtual void Destroy(bool have_context) = 0; private: - viz::ResourceFormat format_; - gfx::Size size_; - gfx::ColorSpace color_space_; - uint32_t usage_; + const Mailbox mailbox_; + const viz::ResourceFormat format_; + const gfx::Size size_; + const gfx::ColorSpace color_space_; + const uint32_t usage_; }; } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_backing_factory.h b/gpu/command_buffer/service/shared_image_backing_factory.h index e6f3d11..a2ddef5 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory.h +++ b/gpu/command_buffer/service/shared_image_backing_factory.h
@@ -16,11 +16,13 @@ namespace gpu { class SharedImageBacking; +struct Mailbox; class SharedImageBackingFactory { public: virtual ~SharedImageBackingFactory() = default; virtual std::unique_ptr<SharedImageBacking> CreateSharedImage( + const Mailbox& mailbox, viz::ResourceFormat format, const gfx::Size& size, const gfx::ColorSpace& color_space,
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc index 53f314eb..a817d61 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
@@ -4,11 +4,9 @@ #include "gpu/command_buffer/service/shared_image_backing_factory_gl_texture.h" -#include <inttypes.h> - #include "base/feature_list.h" -#include "base/strings/stringprintf.h" #include "base/trace_event/memory_dump_manager.h" +#include "base/trace_event/trace_event.h" #include "components/viz/common/resources/resource_format_utils.h" #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" #include "gpu/command_buffer/common/shared_image_trace_utils.h" @@ -32,22 +30,22 @@ // as a gles2::Texture. Can be used with the legacy mailbox implementation. class SharedImageBackingGLTexture : public SharedImageBacking { public: - SharedImageBackingGLTexture(viz::ResourceFormat format, + SharedImageBackingGLTexture(const Mailbox& mailbox, + viz::ResourceFormat format, const gfx::Size& size, const gfx::ColorSpace& color_space, uint32_t usage, gles2::Texture* texture) - : SharedImageBacking(format, size, color_space, usage), + : SharedImageBacking(mailbox, format, size, color_space, usage), texture_(texture) { DCHECK(texture_); } ~SharedImageBackingGLTexture() override { DCHECK(!texture_); } - bool ProduceLegacyMailbox(const Mailbox& mailbox, - MailboxManager* mailbox_manager) override { + bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override { DCHECK(texture_); - mailbox_manager->ProduceTexture(mailbox, texture_); + mailbox_manager->ProduceTexture(mailbox(), texture_); return true; } @@ -57,6 +55,28 @@ texture_ = nullptr; } + size_t EstimatedSize() const override { return texture_->estimated_size(); } + + void OnMemoryDump(const std::string& dump_name, + base::trace_event::MemoryAllocatorDump* dump, + base::trace_event::ProcessMemoryDump* pmd, + uint64_t client_tracing_id) override { + // Add a |service_guid| which expresses shared ownership between the + // various GPU dumps. + auto client_guid = GetSharedImageGUIDForTracing(mailbox()); + auto service_guid = + gl::GetGLTextureServiceGUIDForTracing(texture_->service_id()); + pmd->CreateSharedGlobalAllocatorDump(service_guid); + // TODO(piman): coalesce constant with TextureManager::DumpTextureRef. + int importance = 2; // This client always owns the ref. + + pmd->AddOwnershipEdge(client_guid, service_guid, importance); + + // Dump all sub-levels held by the texture. They will appear below the + // main gl/textures/client_X/mailbox_Y dump. + texture_->DumpLevelMemory(pmd, client_tracing_id, dump_name); + } + private: gles2::Texture* texture_ = nullptr; }; @@ -67,12 +87,13 @@ class SharedImageBackingPassthroughGLTexture : public SharedImageBacking { public: SharedImageBackingPassthroughGLTexture( + const Mailbox& mailbox, viz::ResourceFormat format, const gfx::Size& size, const gfx::ColorSpace& color_space, uint32_t usage, scoped_refptr<gles2::TexturePassthrough> passthrough_texture) - : SharedImageBacking(format, size, color_space, usage), + : SharedImageBacking(mailbox, format, size, color_space, usage), passthrough_texture_(std::move(passthrough_texture)) { DCHECK(passthrough_texture_); } @@ -81,10 +102,9 @@ DCHECK(!passthrough_texture_); } - bool ProduceLegacyMailbox(const Mailbox& mailbox, - MailboxManager* mailbox_manager) override { + bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override { DCHECK(passthrough_texture_); - mailbox_manager->ProduceTexture(mailbox, passthrough_texture_.get()); + mailbox_manager->ProduceTexture(mailbox(), passthrough_texture_.get()); return true; } @@ -200,6 +220,7 @@ std::unique_ptr<SharedImageBacking> SharedImageBackingFactoryGLTexture::CreateSharedImage( + const Mailbox& mailbox, viz::ResourceFormat format, const gfx::Size& size, const gfx::ColorSpace& color_space, @@ -307,7 +328,8 @@ if (image) passthrough_texture->SetLevelImage(target, 0, image.get()); backing = std::make_unique<SharedImageBackingPassthroughGLTexture>( - format, size, color_space, usage, std::move(passthrough_texture)); + mailbox, format, size, color_space, usage, + std::move(passthrough_texture)); } else { gles2::Texture* texture = new gles2::Texture(service_id); texture->SetLightweightRef(memory_tracker_.get()); @@ -328,7 +350,7 @@ texture->SetLevelImage(target, 0, image.get(), gles2::Texture::BOUND); texture->SetImmutable(true); backing = std::make_unique<SharedImageBackingGLTexture>( - format, size, color_space, usage, texture); + mailbox, format, size, color_space, usage, texture); } api->glBindTextureFn(target, old_texture_binding);
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.h b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.h index 4ac6d483..76b463ca 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.h +++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.h
@@ -25,6 +25,7 @@ class GpuDriverBugWorkarounds; struct GpuFeatureInfo; struct GpuPreferences; +struct Mailbox; class ImageFactory; namespace gles2 { @@ -47,6 +48,7 @@ // SharedImageBackingFactory implementation. std::unique_ptr<SharedImageBacking> CreateSharedImage( + const Mailbox& mailbox, viz::ResourceFormat format, const gfx::Size& size, const gfx::ColorSpace& color_space,
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc index 56bc8f7..81b637d 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc
@@ -58,18 +58,18 @@ }; TEST_P(SharedImageBackingFactoryGLTextureTest, Basic) { + auto mailbox = Mailbox::Generate(); auto format = viz::ResourceFormat::RGBA_8888; gfx::Size size(256, 256); auto color_space = gfx::ColorSpace::CreateSRGB(); uint32_t usage = SHARED_IMAGE_USAGE_GLES2; - auto backing = - backing_factory_->CreateSharedImage(format, size, color_space, usage); + auto backing = backing_factory_->CreateSharedImage(mailbox, format, size, + color_space, usage); EXPECT_TRUE(backing); // TODO(ericrk): Validate via a SharedImageRepresentation. For now use legacy // mailbox. - auto mailbox = Mailbox::Generate(); - EXPECT_TRUE(backing->ProduceLegacyMailbox(mailbox, &mailbox_manager_)); + EXPECT_TRUE(backing->ProduceLegacyMailbox(&mailbox_manager_)); TextureBase* texture_base = mailbox_manager_.ConsumeTexture(mailbox); ASSERT_TRUE(texture_base); GLenum expected_target = GL_TEXTURE_2D; @@ -90,18 +90,18 @@ } TEST_P(SharedImageBackingFactoryGLTextureTest, Image) { + auto mailbox = Mailbox::Generate(); auto format = viz::ResourceFormat::RGBA_8888; gfx::Size size(256, 256); auto color_space = gfx::ColorSpace::CreateSRGB(); uint32_t usage = SHARED_IMAGE_USAGE_SCANOUT; - auto backing = - backing_factory_->CreateSharedImage(format, size, color_space, usage); + auto backing = backing_factory_->CreateSharedImage(mailbox, format, size, + color_space, usage); EXPECT_TRUE(backing); // TODO(ericrk): Validate via a SharedImageRepresentation. For now use legacy // mailbox. - auto mailbox = Mailbox::Generate(); - EXPECT_TRUE(backing->ProduceLegacyMailbox(mailbox, &mailbox_manager_)); + EXPECT_TRUE(backing->ProduceLegacyMailbox(&mailbox_manager_)); TextureBase* texture_base = mailbox_manager_.ConsumeTexture(mailbox); ASSERT_TRUE(texture_base); GLenum target = texture_base->target(); @@ -121,27 +121,29 @@ } TEST_P(SharedImageBackingFactoryGLTextureTest, InvalidFormat) { + auto mailbox = Mailbox::Generate(); auto format = viz::ResourceFormat::UYVY_422; gfx::Size size(256, 256); auto color_space = gfx::ColorSpace::CreateSRGB(); uint32_t usage = SHARED_IMAGE_USAGE_GLES2; - auto backing = - backing_factory_->CreateSharedImage(format, size, color_space, usage); + auto backing = backing_factory_->CreateSharedImage(mailbox, format, size, + color_space, usage); EXPECT_FALSE(backing); } TEST_P(SharedImageBackingFactoryGLTextureTest, InvalidSize) { + auto mailbox = Mailbox::Generate(); auto format = viz::ResourceFormat::RGBA_8888; gfx::Size size(0, 0); auto color_space = gfx::ColorSpace::CreateSRGB(); uint32_t usage = SHARED_IMAGE_USAGE_GLES2; - auto backing = - backing_factory_->CreateSharedImage(format, size, color_space, usage); + auto backing = backing_factory_->CreateSharedImage(mailbox, format, size, + color_space, usage); EXPECT_FALSE(backing); size = gfx::Size(INT_MAX, INT_MAX); - backing = - backing_factory_->CreateSharedImage(format, size, color_space, usage); + backing = backing_factory_->CreateSharedImage(mailbox, format, size, + color_space, usage); EXPECT_FALSE(backing); }
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc index 70293f4c..19c0acf 100644 --- a/gpu/command_buffer/service/shared_image_factory.cc +++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -34,9 +34,7 @@ SharedImageManager* shared_image_manager, ImageFactory* image_factory, gles2::MemoryTracker* tracker) - : use_passthrough_(gpu_preferences.use_passthrough_cmd_decoder && - gles2::PassthroughCommandDecoderSupported()), - mailbox_manager_(mailbox_manager), + : mailbox_manager_(mailbox_manager), shared_image_manager_(shared_image_manager), backing_factory_( std::make_unique<SharedImageBackingFactoryGLTexture>(gpu_preferences, @@ -66,11 +64,11 @@ std::unique_ptr<SharedImageBacking> backing; if (wrapped_sk_image_factory_ && (usage & SHARED_IMAGE_USAGE_OOP_RASTERIZATION)) { - backing = wrapped_sk_image_factory_->CreateSharedImage(format, size, - color_space, usage); + backing = wrapped_sk_image_factory_->CreateSharedImage( + mailbox, format, size, color_space, usage); } else { - backing = - backing_factory_->CreateSharedImage(format, size, color_space, usage); + backing = backing_factory_->CreateSharedImage(mailbox, format, size, + color_space, usage); } if (!backing) { @@ -79,14 +77,14 @@ } // TODO(ericrk): Handle the non-legacy case. - if (!backing->ProduceLegacyMailbox(mailbox, mailbox_manager_)) { + if (!backing->ProduceLegacyMailbox(mailbox_manager_)) { LOG(ERROR) << "CreateSharedImage: could not convert backing to legacy mailbox."; backing->Destroy(true /* have_context */); return false; } - if (!shared_image_manager_->Register(mailbox, std::move(backing))) { + if (!shared_image_manager_->Register(std::move(backing))) { LOG(ERROR) << "CreateSharedImage: Could not register backing with " "SharedImageManager."; backing->Destroy(true /* have_context */); @@ -120,59 +118,9 @@ base::trace_event::ProcessMemoryDump* pmd, int client_id, uint64_t client_tracing_id) { - if (use_passthrough_) - return true; - - // TODO(ericrk): Move some of this to SharedImageBacking. for (const auto& mailbox : mailboxes_) { - uint64_t estimated_size = 0; - TextureBase* texture_base = mailbox_manager_->ConsumeTexture(mailbox); - - gles2::Texture* texture = nullptr; - switch (texture_base->GetType()) { - case TextureBase::Type::kValidated: - texture = gles2::Texture::CheckedCast(texture_base); - estimated_size = texture->estimated_size(); - break; - case TextureBase::Type::kSkImage: - estimated_size = - raster::WrappedSkImage::CheckedCast(texture_base)->estimated_size(); - break; - default: - NOTREACHED(); - continue; - } - - // Unique name in the process. - std::string dump_name = - base::StringPrintf("gpu/shared-images/client_0x%" PRIX32 "/mailbox_%s", - client_id, mailbox.ToDebugString().c_str()); - - base::trace_event::MemoryAllocatorDump* dump = - pmd->CreateAllocatorDump(dump_name); - dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, - base::trace_event::MemoryAllocatorDump::kUnitsBytes, - estimated_size); - // Add a mailbox guid which expresses shared ownership with the client - // process. - // This must match the client-side. - auto client_guid = GetSharedImageGUIDForTracing(mailbox); - pmd->CreateSharedGlobalAllocatorDump(client_guid); - pmd->AddOwnershipEdge(dump->guid(), client_guid); - // Add a |service_guid| which expresses shared ownership between the - // various GPU dumps. - auto service_guid = - gl::GetGLTextureServiceGUIDForTracing(texture->GetTracingId()); - pmd->CreateSharedGlobalAllocatorDump(service_guid); - // TODO(piman): coalesce constant with TextureManager::DumpTextureRef. - int importance = 2; // This client always owns the ref. - - pmd->AddOwnershipEdge(client_guid, service_guid, importance); - - // Dump all sub-levels held by the texture. They will appear below the - // main gl/textures/client_X/mailbox_Y dump. - if (texture) - texture->DumpLevelMemory(pmd, client_tracing_id, dump_name); + shared_image_manager_->OnMemoryDump(mailbox, pmd, client_id, + client_tracing_id); } return true;
diff --git a/gpu/command_buffer/service/shared_image_factory.h b/gpu/command_buffer/service/shared_image_factory.h index f3ff67e..9f0f44cb 100644 --- a/gpu/command_buffer/service/shared_image_factory.h +++ b/gpu/command_buffer/service/shared_image_factory.h
@@ -60,7 +60,6 @@ uint64_t client_tracing_id); private: - bool use_passthrough_; MailboxManager* mailbox_manager_; SharedImageManager* shared_image_manager_;
diff --git a/gpu/command_buffer/service/shared_image_manager.cc b/gpu/command_buffer/service/shared_image_manager.cc index b2211282..e0dec4f 100644 --- a/gpu/command_buffer/service/shared_image_manager.cc +++ b/gpu/command_buffer/service/shared_image_manager.cc
@@ -4,7 +4,32 @@ #include "gpu/command_buffer/service/shared_image_manager.h" +#include <inttypes.h> + +#include "base/logging.h" +#include "base/strings/stringprintf.h" +#include "base/trace_event/memory_dump_manager.h" +#include "base/trace_event/process_memory_dump.h" +#include "base/trace_event/trace_event.h" +#include "gpu/command_buffer/common/shared_image_trace_utils.h" +#include "ui/gl/trace_util.h" + namespace gpu { +// Overrides for flat_set lookups: +bool operator<(const gpu::SharedImageManager::BackingAndRefCount& lhs, + const gpu::SharedImageManager::BackingAndRefCount& rhs) { + return lhs.backing->mailbox() < rhs.backing->mailbox(); +} + +bool operator<(const gpu::Mailbox& lhs, + const gpu::SharedImageManager::BackingAndRefCount& rhs) { + return lhs < rhs.backing->mailbox(); +} + +bool operator<(const gpu::SharedImageManager::BackingAndRefCount& lhs, + const gpu::Mailbox& rhs) { + return lhs.backing->mailbox() < rhs; +} SharedImageManager::SharedImageManager() = default; @@ -12,14 +37,12 @@ DCHECK(images_.empty()); } -bool SharedImageManager::Register(const Mailbox& mailbox, - std::unique_ptr<SharedImageBacking> backing) { - auto found = images_.find(mailbox); +bool SharedImageManager::Register(std::unique_ptr<SharedImageBacking> backing) { + auto found = images_.find(backing->mailbox()); if (found != images_.end()) return false; - images_.emplace(mailbox, - BackingAndRefCount(std::move(backing), 1 /* ref_count */)); + images_.emplace(std::move(backing), 1 /* ref_count */); return true; } @@ -31,13 +54,51 @@ return; } - found->second.ref_count--; - if (found->second.ref_count == 0) { - found->second.backing->Destroy(have_context); + found->ref_count--; + if (found->ref_count == 0) { + found->backing->Destroy(have_context); images_.erase(found); } } +void SharedImageManager::OnMemoryDump(const Mailbox& mailbox, + base::trace_event::ProcessMemoryDump* pmd, + int client_id, + uint64_t client_tracing_id) { + auto found = images_.find(mailbox); + if (found == images_.end()) { + LOG(ERROR) << "SharedImageManager::OnMemoryDump: Trying to dump memory for " + "a non existent mailbox."; + return; + } + + auto* backing = found->backing.get(); + size_t estimated_size = backing->EstimatedSize(); + if (estimated_size == 0) + return; + + // Unique name in the process. + std::string dump_name = + base::StringPrintf("gpu/shared-images/client_0x%" PRIX32 "/mailbox_%s", + client_id, mailbox.ToDebugString().c_str()); + + base::trace_event::MemoryAllocatorDump* dump = + pmd->CreateAllocatorDump(dump_name); + dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + estimated_size); + // Add a mailbox guid which expresses shared ownership with the client + // process. + // This must match the client-side. + auto client_guid = GetSharedImageGUIDForTracing(mailbox); + pmd->CreateSharedGlobalAllocatorDump(client_guid); + pmd->AddOwnershipEdge(dump->guid(), client_guid); + + // Allow the SharedImageBacking to attach additional data to the dump + // or dump additional sub-paths. + backing->OnMemoryDump(dump_name, dump, pmd, client_tracing_id); +} + SharedImageManager::BackingAndRefCount::BackingAndRefCount( std::unique_ptr<SharedImageBacking> backing, uint32_t ref_count)
diff --git a/gpu/command_buffer/service/shared_image_manager.h b/gpu/command_buffer/service/shared_image_manager.h index 10a1263..2b1ff67f 100644 --- a/gpu/command_buffer/service/shared_image_manager.h +++ b/gpu/command_buffer/service/shared_image_manager.h
@@ -5,7 +5,7 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_MANAGER_H_ #define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_MANAGER_H_ -#include "base/containers/flat_map.h" +#include "base/containers/flat_set.h" #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/service/shared_image_backing.h" #include "gpu/gpu_gles2_export.h" @@ -20,8 +20,7 @@ // Registers a SharedImageBacking with the manager and returns true on // success. On success, the backing has one ref which may be released by // calling Unregister. - bool Register(const Mailbox& mailbox, - std::unique_ptr<SharedImageBacking> backing); + bool Register(std::unique_ptr<SharedImageBacking> backing); // Releases the registration ref. If a backing reaches zero refs, it is // destroyed. @@ -31,6 +30,12 @@ // SharedImageRepresentation. Representations also take a ref on the // mailbox, releasing it when the representation is destroyed. + // Dump memory for the given mailbox. + void OnMemoryDump(const Mailbox& mailbox, + base::trace_event::ProcessMemoryDump* pmd, + int client_id, + uint64_t client_tracing_id); + private: struct BackingAndRefCount { BackingAndRefCount(std::unique_ptr<SharedImageBacking> backing, @@ -41,7 +46,12 @@ std::unique_ptr<SharedImageBacking> backing; uint32_t ref_count = 0; }; - base::flat_map<Mailbox, BackingAndRefCount> images_; + friend bool operator<(const BackingAndRefCount& lhs, + const BackingAndRefCount& rhs); + friend bool operator<(const Mailbox& lhs, const BackingAndRefCount& rhs); + friend bool operator<(const BackingAndRefCount& lhs, const Mailbox& rhs); + + base::flat_set<BackingAndRefCount> images_; DISALLOW_COPY_AND_ASSIGN(SharedImageManager); };
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc index 0b6c0ba..aa44af6 100644 --- a/gpu/command_buffer/service/wrapped_sk_image.cc +++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -6,7 +6,11 @@ #include "base/hash.h" #include "base/logging.h" +#include "base/trace_event/memory_dump_manager.h" +#include "base/trace_event/process_memory_dump.h" +#include "base/trace_event/trace_event.h" #include "components/viz/common/resources/resource_format_utils.h" +#include "gpu/command_buffer/common/shared_image_trace_utils.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/raster_decoder_context_state.h" #include "gpu/command_buffer/service/shared_image_backing.h" @@ -15,6 +19,7 @@ #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrTypes.h" #include "ui/gl/gl_context.h" +#include "ui/gl/trace_util.h" namespace gpu { namespace raster { @@ -23,22 +28,22 @@ class WrappedSkImageBacking : public SharedImageBacking { public: - WrappedSkImageBacking(viz::ResourceFormat format, + WrappedSkImageBacking(const Mailbox& mailbox, + viz::ResourceFormat format, const gfx::Size& size, const gfx::ColorSpace& color_space, uint32_t usage, std::unique_ptr<WrappedSkImage> wrapped_sk_image) - : SharedImageBacking(format, size, color_space, usage), + : SharedImageBacking(mailbox, format, size, color_space, usage), wrapped_sk_image_(std::move(wrapped_sk_image)) { DCHECK(!!wrapped_sk_image_); } ~WrappedSkImageBacking() override { DCHECK(!wrapped_sk_image_); } - bool ProduceLegacyMailbox(const Mailbox& mailbox, - MailboxManager* mailbox_manager) override { + bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override { DCHECK(!!wrapped_sk_image_); - mailbox_manager->ProduceTexture(mailbox, wrapped_sk_image_.get()); + mailbox_manager->ProduceTexture(mailbox(), wrapped_sk_image_.get()); return true; } @@ -47,6 +52,26 @@ wrapped_sk_image_.reset(); } + size_t EstimatedSize() const override { + return wrapped_sk_image_->estimated_size(); + } + + void OnMemoryDump(const std::string& dump_name, + base::trace_event::MemoryAllocatorDump* dump, + base::trace_event::ProcessMemoryDump* pmd, + uint64_t client_tracing_id) override { + // Add a |service_guid| which expresses shared ownership between the + // various GPU dumps. + auto client_guid = GetSharedImageGUIDForTracing(mailbox()); + auto service_guid = gl::GetGLTextureServiceGUIDForTracing( + wrapped_sk_image_->GetTracingId()); + pmd->CreateSharedGlobalAllocatorDump(service_guid); + // TODO(piman): coalesce constant with TextureManager::DumpTextureRef. + int importance = 2; // This client always owns the ref. + + pmd->AddOwnershipEdge(client_guid, service_guid, importance); + } + private: std::unique_ptr<WrappedSkImage> wrapped_sk_image_; @@ -62,6 +87,7 @@ WrappedSkImageFactory::~WrappedSkImageFactory() = default; std::unique_ptr<SharedImageBacking> WrappedSkImageFactory::CreateSharedImage( + const Mailbox& mailbox, viz::ResourceFormat format, const gfx::Size& size, const gfx::ColorSpace& color_space, @@ -69,8 +95,8 @@ std::unique_ptr<WrappedSkImage> texture(new WrappedSkImage(context_state_)); if (!texture->Initialize(size, format)) return nullptr; - return std::make_unique<WrappedSkImageBacking>(format, size, color_space, - usage, std::move(texture)); + return std::make_unique<WrappedSkImageBacking>( + mailbox, format, size, color_space, usage, std::move(texture)); } WrappedSkImage::WrappedSkImage(raster::RasterDecoderContextState* context_state)
diff --git a/gpu/command_buffer/service/wrapped_sk_image.h b/gpu/command_buffer/service/wrapped_sk_image.h index 3c6b98d..faa5a7e 100644 --- a/gpu/command_buffer/service/wrapped_sk_image.h +++ b/gpu/command_buffer/service/wrapped_sk_image.h
@@ -31,6 +31,7 @@ // SharedImageBackingFactory implementation: std::unique_ptr<SharedImageBacking> CreateSharedImage( + const Mailbox& mailbox, viz::ResourceFormat format, const gfx::Size& size, const gfx::ColorSpace& color_space,
diff --git a/gpu/command_buffer/tests/decoder_perftest.cc b/gpu/command_buffer/tests/decoder_perftest.cc index cbe76c4..2ee83f4c 100644 --- a/gpu/command_buffer/tests/decoder_perftest.cc +++ b/gpu/command_buffer/tests/decoder_perftest.cc
@@ -264,61 +264,59 @@ size_t width, size_t height, unsigned internalformat) override { - NOTREACHED(); + NOTIMPLEMENTED(); return -1; } - void DestroyImage(int32_t id) override { NOTREACHED(); } + void DestroyImage(int32_t id) override { NOTIMPLEMENTED(); } void SignalQuery(uint32_t query, base::OnceClosure callback) override { - NOTREACHED(); + NOTIMPLEMENTED(); } void CreateGpuFence(uint32_t gpu_fence_id, ClientGpuFence source) override { - NOTREACHED(); + NOTIMPLEMENTED(); } void GetGpuFence(uint32_t gpu_fence_id, base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)> callback) override { - NOTREACHED(); + NOTIMPLEMENTED(); } - void SetLock(base::Lock*) override { NOTREACHED(); } + void SetLock(base::Lock*) override { NOTIMPLEMENTED(); } - void EnsureWorkVisible() override { NOTREACHED(); } + void EnsureWorkVisible() override {} gpu::CommandBufferNamespace GetNamespaceID() const override { - return gpu::CommandBufferNamespace::INVALID; + return command_buffer_->GetNamespaceID(); } CommandBufferId GetCommandBufferID() const override { - return gpu::CommandBufferId(); + return command_buffer_->GetCommandBufferID(); } - void FlushPendingWork() override { NOTREACHED(); } + void FlushPendingWork() override {} uint64_t GenerateFenceSyncRelease() override { - NOTREACHED(); + NOTIMPLEMENTED(); return 0; } bool IsFenceSyncReleased(uint64_t release) override { - NOTREACHED(); + NOTIMPLEMENTED(); return true; } void SignalSyncToken(const gpu::SyncToken& sync_token, base::OnceClosure callback) override { - NOTREACHED(); + NOTIMPLEMENTED(); } - void WaitSyncToken(const gpu::SyncToken& sync_token) override { - NOTREACHED(); - } + void WaitSyncTokenHint(const gpu::SyncToken& sync_token) override {} bool CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) override { - NOTREACHED(); + NOTIMPLEMENTED(); return true; }
diff --git a/gpu/command_buffer/tests/fuzzer_main.cc b/gpu/command_buffer/tests/fuzzer_main.cc index 4a17622..1559138 100644 --- a/gpu/command_buffer/tests/fuzzer_main.cc +++ b/gpu/command_buffer/tests/fuzzer_main.cc
@@ -17,6 +17,7 @@ #include "build/build_config.h" #include "gpu/command_buffer/common/constants.h" #include "gpu/command_buffer/common/context_creation_attribs.h" +#include "gpu/command_buffer/common/sync_token.h" #include "gpu/command_buffer/service/buffer_manager.h" #include "gpu/command_buffer/service/command_buffer_direct.h" #include "gpu/command_buffer/service/context_group.h" @@ -30,6 +31,7 @@ #include "gpu/command_buffer/service/raster_decoder_context_state.h" #include "gpu/command_buffer/service/service_discardable_manager.h" #include "gpu/command_buffer/service/shared_image_manager.h" +#include "gpu/command_buffer/service/sync_point_manager.h" #include "gpu/command_buffer/service/transfer_buffer_manager.h" #include "ui/gfx/geometry/size.h" #include "ui/gl/gl_context.h" @@ -349,8 +351,8 @@ config_.attrib_helper.bind_generates_resource, &image_manager_, nullptr /* image_factory */, nullptr /* progress_reporter */, gpu_feature_info, discardable_manager_.get(), &shared_image_manager_); - command_buffer_.reset( - new CommandBufferDirect(context_group->transfer_buffer_manager())); + command_buffer_.reset(new CommandBufferDirect( + context_group->transfer_buffer_manager(), &sync_point_manager_)); #if defined(GPU_FUZZER_USE_RASTER_DECODER) CHECK(feature_info->feature_flags().chromium_raster_transport); @@ -506,6 +508,7 @@ gles2::MailboxManagerImpl mailbox_manager_; gles2::TraceOutputter outputter_; scoped_refptr<gl::GLShareGroup> share_group_; + SyncPointManager sync_point_manager_; gles2::ImageManager image_manager_; std::unique_ptr<ServiceDiscardableManager> discardable_manager_; SharedImageManager shared_image_manager_;
diff --git a/gpu/command_buffer/tests/gl_fence_sync_unittest.cc b/gpu/command_buffer/tests/gl_fence_sync_unittest.cc new file mode 100644 index 0000000..5695997 --- /dev/null +++ b/gpu/command_buffer/tests/gl_fence_sync_unittest.cc
@@ -0,0 +1,91 @@ +// Copyright 2015 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 <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <GLES2/gl2extchromium.h> + +#include <memory> + +#include "base/bind.h" +#include "gpu/command_buffer/common/sync_token.h" +#include "gpu/command_buffer/service/sync_point_manager.h" +#include "gpu/command_buffer/tests/gl_manager.h" +#include "gpu/command_buffer/tests/gl_test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +#define SHADER(Src) #Src + +namespace gpu { + +class GLFenceSyncTest : public testing::Test { + protected: + void SetUp() override { + sync_point_manager_.reset(new SyncPointManager()); + + GLManager::Options options; + options.sync_point_manager = sync_point_manager_.get(); + gl1_.Initialize(options); + gl2_.Initialize(options); + } + + void TearDown() override { + gl2_.Destroy(); + gl1_.Destroy(); + + sync_point_manager_.reset(); + } + + std::unique_ptr<SyncPointManager> sync_point_manager_; + GLManager gl1_; + GLManager gl2_; +}; + +TEST_F(GLFenceSyncTest, SimpleReleaseWait) { + gl1_.MakeCurrent(); + + SyncToken sync_token; + glFlush(); + glGenSyncTokenCHROMIUM(sync_token.GetData()); + ASSERT_TRUE(GL_NO_ERROR == glGetError()); + + // Make sure it is actually released. + EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token)); + + gl2_.MakeCurrent(); + glWaitSyncTokenCHROMIUM(sync_token.GetConstData()); + glFinish(); +} + +static void TestCallback(int* storage, int assign) { + *storage = assign; +} + +TEST_F(GLFenceSyncTest, SimpleReleaseSignal) { + gl1_.MakeCurrent(); + + // Pause the command buffer so the fence sync does not immediately trigger. + gl1_.SetCommandsPaused(true); + + SyncToken sync_token; + glGenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); + glFlush(); + ASSERT_TRUE(sync_token.HasData()); + + gl2_.MakeCurrent(); + int callback_called = 0; + gl2_.SignalSyncToken(sync_token, + base::Bind(TestCallback, &callback_called, 1)); + + gl1_.MakeCurrent(); + EXPECT_EQ(0, callback_called); + + gl1_.SetCommandsPaused(false); + glFinish(); + + EXPECT_EQ(1, callback_called); +} + +} // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc index 11478b10..60ddd3c1 100644 --- a/gpu/command_buffer/tests/gl_manager.cc +++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -196,8 +196,9 @@ class CommandBufferCheckLostContext : public CommandBufferDirect { public: CommandBufferCheckLostContext(TransferBufferManager* transfer_buffer_manager, + SyncPointManager* sync_point_manager, bool context_lost_allowed) - : CommandBufferDirect(transfer_buffer_manager), + : CommandBufferDirect(transfer_buffer_manager, sync_point_manager), context_lost_allowed_(context_lost_allowed) {} ~CommandBufferCheckLostContext() override = default; @@ -356,7 +357,8 @@ } command_buffer_.reset(new CommandBufferCheckLostContext( - context_group->transfer_buffer_manager(), options.context_lost_allowed)); + context_group->transfer_buffer_manager(), options.sync_point_manager, + options.context_lost_allowed)); decoder_.reset(::gpu::gles2::GLES2Decoder::Create( command_buffer_.get(), command_buffer_->service(), &outputter_, @@ -463,6 +465,10 @@ decoder_->PerformIdleWork(); } +void GLManager::SetCommandsPaused(bool paused) { + command_buffer_->SetCommandsPaused(paused); +} + void GLManager::Destroy() { if (gles2_implementation_.get()) { MakeCurrent(); @@ -557,60 +563,56 @@ } void GLManager::SignalQuery(uint32_t query, base::OnceClosure callback) { - NOTREACHED(); + NOTIMPLEMENTED(); } void GLManager::CreateGpuFence(uint32_t gpu_fence_id, ClientGpuFence source) { - NOTREACHED(); + NOTIMPLEMENTED(); } void GLManager::GetGpuFence( uint32_t gpu_fence_id, base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)> callback) { - NOTREACHED(); + NOTIMPLEMENTED(); } void GLManager::SetLock(base::Lock*) { - NOTREACHED(); + NOTIMPLEMENTED(); } void GLManager::EnsureWorkVisible() { - NOTREACHED(); + // This is only relevant for out-of-process command buffers. } gpu::CommandBufferNamespace GLManager::GetNamespaceID() const { - return CommandBufferNamespace::INVALID; + return command_buffer_->GetNamespaceID(); } CommandBufferId GLManager::GetCommandBufferID() const { - return CommandBufferId(); + return command_buffer_->GetCommandBufferID(); } void GLManager::FlushPendingWork() { - NOTREACHED(); + // This is only relevant for out-of-process command buffers. } uint64_t GLManager::GenerateFenceSyncRelease() { - NOTREACHED(); - return 0; + return next_fence_sync_release_++; } bool GLManager::IsFenceSyncReleased(uint64_t release) { - NOTREACHED(); - return false; + return release <= command_buffer_->GetLastState().release_count; } void GLManager::SignalSyncToken(const gpu::SyncToken& sync_token, base::OnceClosure callback) { - NOTREACHED(); + command_buffer_->SignalSyncToken( + sync_token, base::AdaptCallbackForRepeating(std::move(callback))); } -void GLManager::WaitSyncToken(const gpu::SyncToken& sync_token) { - NOTREACHED(); -} +void GLManager::WaitSyncTokenHint(const gpu::SyncToken& sync_token) {} bool GLManager::CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) { - NOTREACHED(); return false; }
diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h index 76c71ca..c8d6c3b 100644 --- a/gpu/command_buffer/tests/gl_manager.h +++ b/gpu/command_buffer/tests/gl_manager.h
@@ -38,6 +38,7 @@ class GpuMemoryBufferFactory; class ImageFactory; class MailboxManager; +class SyncPointManager; class TransferBuffer; namespace gles2 { @@ -53,6 +54,8 @@ Options(); // The size of the backbuffer. gfx::Size size = gfx::Size(4, 4); + // If not null will have a corresponding sync point manager. + SyncPointManager* sync_point_manager = nullptr; // If not null will share resources with this context. GLManager* share_group_manager = nullptr; // If not null will share a mailbox manager with this context. @@ -111,6 +114,8 @@ use_native_pixmap_memory_buffers_ = use_native_pixmap_memory_buffers; } + void SetCommandsPaused(bool paused); + gles2::GLES2Decoder* decoder() const { return decoder_.get(); } @@ -152,7 +157,7 @@ bool IsFenceSyncReleased(uint64_t release) override; void SignalSyncToken(const gpu::SyncToken& sync_token, base::OnceClosure callback) override; - void WaitSyncToken(const gpu::SyncToken& sync_token) override; + void WaitSyncTokenHint(const gpu::SyncToken& sync_token) override; bool CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) override; size_t GetSharedMemoryBytesAllocated() const; @@ -187,6 +192,8 @@ std::unique_ptr<gpu::GpuMemoryBufferFactory> gpu_memory_buffer_factory_; SharedImageManager shared_image_manager_; + uint64_t next_fence_sync_release_ = 1; + bool use_iosurface_memory_buffers_ = false; bool use_native_pixmap_memory_buffers_ = false;
diff --git a/gpu/gles2_conform_support/egl/context.cc b/gpu/gles2_conform_support/egl/context.cc index 1545fb1..23c3cd9 100644 --- a/gpu/gles2_conform_support/egl/context.cc +++ b/gpu/gles2_conform_support/egl/context.cc
@@ -175,38 +175,38 @@ size_t width, size_t height, unsigned internalformat) { - NOTREACHED(); + NOTIMPLEMENTED(); return -1; } void Context::DestroyImage(int32_t id) { - NOTREACHED(); + NOTIMPLEMENTED(); } void Context::SignalQuery(uint32_t query, base::OnceClosure callback) { - NOTREACHED(); + NOTIMPLEMENTED(); } void Context::CreateGpuFence(uint32_t gpu_fence_id, ClientGpuFence source) { - NOTREACHED(); + NOTIMPLEMENTED(); } void Context::GetGpuFence( uint32_t gpu_fence_id, base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)> callback) { - NOTREACHED(); + NOTIMPLEMENTED(); } void Context::SetLock(base::Lock*) { - NOTREACHED(); + NOTIMPLEMENTED(); } void Context::EnsureWorkVisible() { - NOTREACHED(); + // This is only relevant for out-of-process command buffers. } gpu::CommandBufferNamespace Context::GetNamespaceID() const { - return gpu::CommandBufferNamespace::INVALID; + return gpu::CommandBufferNamespace::IN_PROCESS; } gpu::CommandBufferId Context::GetCommandBufferID() const { @@ -214,27 +214,24 @@ } void Context::FlushPendingWork() { - NOTREACHED(); + // This is only relevant for out-of-process command buffers. } uint64_t Context::GenerateFenceSyncRelease() { - NOTREACHED(); - return 0; + return display_->GenerateFenceSyncRelease(); } bool Context::IsFenceSyncReleased(uint64_t release) { - NOTREACHED(); + NOTIMPLEMENTED(); return false; } void Context::SignalSyncToken(const gpu::SyncToken& sync_token, base::OnceClosure callback) { - NOTREACHED(); + NOTIMPLEMENTED(); } -void Context::WaitSyncToken(const gpu::SyncToken& sync_token) { - NOTREACHED(); -} +void Context::WaitSyncTokenHint(const gpu::SyncToken& sync_token) {} bool Context::CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) { return false;
diff --git a/gpu/gles2_conform_support/egl/context.h b/gpu/gles2_conform_support/egl/context.h index 60917fb..42b432aa 100644 --- a/gpu/gles2_conform_support/egl/context.h +++ b/gpu/gles2_conform_support/egl/context.h
@@ -80,7 +80,7 @@ bool IsFenceSyncReleased(uint64_t release) override; void SignalSyncToken(const gpu::SyncToken& sync_token, base::OnceClosure callback) override; - void WaitSyncToken(const gpu::SyncToken& sync_token) override; + void WaitSyncTokenHint(const gpu::SyncToken& sync_token) override; bool CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) override; // Called by ThreadState to set the needed global variables when this context
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.cc b/gpu/ipc/client/command_buffer_proxy_impl.cc index 4702a07..31cc9b0 100644 --- a/gpu/ipc/client/command_buffer_proxy_impl.cc +++ b/gpu/ipc/client/command_buffer_proxy_impl.cc
@@ -269,6 +269,10 @@ last_put_offset_ = put_offset; last_flush_id_ = channel_->OrderingBarrier( route_id_, put_offset, std::move(pending_sync_token_fences_)); + + pending_sync_token_fences_.clear(); + + flushed_fence_sync_release_ = next_fence_sync_release_ - 1; } void CommandBufferProxyImpl::SetUpdateVSyncParametersCallback( @@ -432,9 +436,13 @@ bool requires_sync_token = handle.type == gfx::IO_SURFACE_BUFFER; uint64_t image_fence_sync = 0; - if (requires_sync_token) + if (requires_sync_token) { image_fence_sync = GenerateFenceSyncRelease(); + // Make sure fence syncs were flushed before CreateImage() was called. + DCHECK_EQ(image_fence_sync, flushed_fence_sync_release_ + 1); + } + DCHECK(gpu::IsImageFromGpuMemoryBufferFormatSupported( gpu_memory_buffer->GetFormat(), capabilities_)); DCHECK(gpu::IsImageSizeValidForGpuMemoryBufferFormat( @@ -543,7 +551,8 @@ signal_tasks_.insert(std::make_pair(signal_id, std::move(callback))); } -void CommandBufferProxyImpl::WaitSyncToken(const gpu::SyncToken& sync_token) { +void CommandBufferProxyImpl::WaitSyncTokenHint( + const gpu::SyncToken& sync_token) { CheckLock(); base::AutoLock lock(last_state_lock_); if (last_state_.error != gpu::error::kNoError) @@ -650,8 +659,8 @@ if (last_state_.error != gpu::error::kNoError) return; - Send(new GpuCommandBufferMsg_ReturnFrontBuffer(route_id_, mailbox, sync_token, - is_lost)); + Send(new GpuCommandBufferMsg_WaitSyncToken(route_id_, sync_token)); + Send(new GpuCommandBufferMsg_ReturnFrontBuffer(route_id_, mailbox, is_lost)); } bool CommandBufferProxyImpl::Send(IPC::Message* msg) {
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.h b/gpu/ipc/client/command_buffer_proxy_impl.h index 3df4dd8..c71dbe1 100644 --- a/gpu/ipc/client/command_buffer_proxy_impl.h +++ b/gpu/ipc/client/command_buffer_proxy_impl.h
@@ -129,7 +129,7 @@ bool IsFenceSyncReleased(uint64_t release) override; void SignalSyncToken(const gpu::SyncToken& sync_token, base::OnceClosure callback) override; - void WaitSyncToken(const gpu::SyncToken& sync_token) override; + void WaitSyncTokenHint(const gpu::SyncToken& sync_token) override; bool CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) override; void TakeFrontBuffer(const gpu::Mailbox& mailbox); void ReturnFrontBuffer(const gpu::Mailbox& mailbox, @@ -263,6 +263,12 @@ // Sync token waits that haven't been flushed yet. std::vector<SyncToken> pending_sync_token_fences_; + // Last flushed fence sync release, same as last item in queue if not empty. + uint64_t flushed_fence_sync_release_ = 0; + + // Last verified fence sync. + uint64_t verified_fence_sync_release_ = 0; + GpuConsoleMessageCallback console_message_callback_; // Tasks to be invoked in SignalSyncPoint responses.
diff --git a/gpu/ipc/client/gpu_channel_host.cc b/gpu/ipc/client/gpu_channel_host.cc index 583cd7d..6ecc095 100644 --- a/gpu/ipc/client/gpu_channel_host.cc +++ b/gpu/ipc/client/gpu_channel_host.cc
@@ -156,8 +156,7 @@ deferred_message.message = GpuCommandBufferMsg_AsyncFlush( pending_ordering_barrier_->route_id, pending_ordering_barrier_->put_offset, - pending_ordering_barrier_->deferred_message_id, - pending_ordering_barrier_->sync_token_fences); + pending_ordering_barrier_->deferred_message_id); deferred_message.sync_token_fences = std::move(pending_ordering_barrier_->sync_token_fences); deferred_messages_.push_back(std::move(deferred_message));
diff --git a/gpu/ipc/command_buffer_task_executor.h b/gpu/ipc/command_buffer_task_executor.h index a0c6714..42f33ef 100644 --- a/gpu/ipc/command_buffer_task_executor.h +++ b/gpu/ipc/command_buffer_task_executor.h
@@ -56,6 +56,9 @@ // Returns true if sequence should yield while running its current task. virtual bool ShouldYield() = 0; + // Enables or disables further execution of tasks in this sequence. + virtual void SetEnabled(bool enabled) = 0; + // Schedule a task with provided sync token dependencies. The dependencies // are hints for sync token waits within the task, and can be ignored by the // implementation. @@ -79,6 +82,10 @@ // Creates a memory tracker for the context group if this returns true. virtual bool ShouldCreateMemoryTracker() const = 0; + // Block thread when a WaitSyncToken command is encountered instead of calling + // OnWaitSyncToken(). + virtual bool BlockThreadOnWaitSyncToken() const = 0; + // Schedules |task| to run out of order with respect to other sequenced tasks. virtual void ScheduleOutOfOrderTask(base::OnceClosure task) = 0;
diff --git a/gpu/ipc/common/gpu_messages.h b/gpu/ipc/common/gpu_messages.h index 6b6470c4..b563322 100644 --- a/gpu/ipc/common/gpu_messages.h +++ b/gpu/ipc/common/gpu_messages.h
@@ -159,9 +159,8 @@ // Returns a front buffer taken with GpuCommandBufferMsg_TakeFrontBuffer. This // allows it to be reused. -IPC_MESSAGE_ROUTED3(GpuCommandBufferMsg_ReturnFrontBuffer, +IPC_MESSAGE_ROUTED2(GpuCommandBufferMsg_ReturnFrontBuffer, gpu::Mailbox /* mailbox */, - gpu::SyncToken /* sync_token */, bool /* is_lost */) // Wait until the token is in a specific range, inclusive. @@ -183,10 +182,9 @@ // TODO(sunnyps): This is an internal implementation detail of the gpu service // and is not sent by the client. Remove this once the non-scheduler code path // is removed. -IPC_MESSAGE_ROUTED3(GpuCommandBufferMsg_AsyncFlush, +IPC_MESSAGE_ROUTED2(GpuCommandBufferMsg_AsyncFlush, int32_t /* put_offset */, - uint32_t /* flush_id */, - std::vector<gpu::SyncToken> /* sync_token_fences */) + uint32_t /* flush_id */) // Sent by the GPU process to display messages in the console. IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_ConsoleMsg, @@ -216,6 +214,10 @@ uint64_t, /* swap_id */ gfx::PresentationFeedback /* feedback */) +// The receiver will stop processing messages until the Synctoken is signaled. +IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_WaitSyncToken, + gpu::SyncToken /* sync_token */) + // The receiver will asynchronously wait until the SyncToken is signaled, and // then return a GpuCommandBufferMsg_SignalAck message. IPC_MESSAGE_ROUTED2(GpuCommandBufferMsg_SignalSyncToken,
diff --git a/gpu/ipc/gpu_in_process_thread_service.cc b/gpu/ipc/gpu_in_process_thread_service.cc index c0d6edd..3d3c773 100644 --- a/gpu/ipc/gpu_in_process_thread_service.cc +++ b/gpu/ipc/gpu_in_process_thread_service.cc
@@ -28,6 +28,13 @@ bool ShouldYield() override { return scheduler_->ShouldYield(sequence_id_); } + void SetEnabled(bool enabled) override { + if (enabled) + scheduler_->EnableSequence(sequence_id_); + else + scheduler_->DisableSequence(sequence_id_); + } + void ScheduleTask(base::OnceClosure task, std::vector<SyncToken> sync_token_fences) override { scheduler_->ScheduleTask(Scheduler::Task(sequence_id_, std::move(task), @@ -75,6 +82,10 @@ return true; } +bool GpuInProcessThreadService::BlockThreadOnWaitSyncToken() const { + return false; +} + std::unique_ptr<CommandBufferTaskExecutor::Sequence> GpuInProcessThreadService::CreateSequence() { return std::make_unique<SchedulerSequence>(scheduler_);
diff --git a/gpu/ipc/gpu_in_process_thread_service.h b/gpu/ipc/gpu_in_process_thread_service.h index df52823..1527230 100644 --- a/gpu/ipc/gpu_in_process_thread_service.h +++ b/gpu/ipc/gpu_in_process_thread_service.h
@@ -35,6 +35,7 @@ // CommandBufferTaskExecutor implementation. bool ForceVirtualizedGLContexts() const override; bool ShouldCreateMemoryTracker() const override; + bool BlockThreadOnWaitSyncToken() const override; std::unique_ptr<CommandBufferTaskExecutor::Sequence> CreateSequence() override; void ScheduleOutOfOrderTask(base::OnceClosure task) override;
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc index ec0a9bf4..922423b 100644 --- a/gpu/ipc/in_process_command_buffer.cc +++ b/gpu/ipc/in_process_command_buffer.cc
@@ -807,29 +807,16 @@ return false; } -void InProcessCommandBuffer::FlushOnGpuThread( - int32_t put_offset, - const std::vector<SyncToken>& sync_token_fences) { +void InProcessCommandBuffer::FlushOnGpuThread(int32_t put_offset) { DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); TRACE_EVENT1("gpu", "InProcessCommandBuffer::FlushOnGpuThread", "put_offset", put_offset); ScopedEvent handle_flush(&flush_event_); - // Check if sync token waits are invalid or already complete. Do not use - // SyncPointManager::IsSyncTokenReleased() as it can't say if the wait is - // invalid. - for (const auto& sync_token : sync_token_fences) - DCHECK(!sync_point_client_state_->Wait(sync_token, base::DoNothing())); if (!MakeCurrent()) return; - MailboxManager* mailbox_manager = context_group_->mailbox_manager(); - if (mailbox_manager->UsesSync()) { - for (const auto& sync_token : sync_token_fences) - mailbox_manager->PullTextureUpdates(sync_token); - } - { base::Optional<raster::GrShaderCache::ScopedCacheUse> cache_use; if (gr_shader_cache_) @@ -842,9 +829,10 @@ bool has_unprocessed_commands = HasUnprocessedCommandsOnGpuThread(); if (!command_buffer_->scheduled() || has_unprocessed_commands) { + DCHECK(!task_executor_->BlockThreadOnWaitSyncToken()); ContinueGpuTask(base::BindOnce(&InProcessCommandBuffer::FlushOnGpuThread, gpu_thread_weak_ptr_factory_.GetWeakPtr(), - put_offset, sync_token_fences)); + put_offset)); } // If we've processed all pending commands but still have pending queries, @@ -891,16 +879,15 @@ put_offset); last_put_offset_ = put_offset; + flushed_fence_sync_release_ = next_fence_sync_release_ - 1; std::vector<SyncToken> sync_token_fences; next_flush_sync_token_fences_.swap(sync_token_fences); - // Don't use std::move() for |sync_token_fences| because evaluation order for - // arguments is not defined. - ScheduleGpuTask(base::BindOnce(&InProcessCommandBuffer::FlushOnGpuThread, - gpu_thread_weak_ptr_factory_.GetWeakPtr(), - put_offset, sync_token_fences), - sync_token_fences); + ScheduleGpuTask( + base::BindOnce(&InProcessCommandBuffer::FlushOnGpuThread, + gpu_thread_weak_ptr_factory_.GetWeakPtr(), put_offset), + std::move(sync_token_fences)); } void InProcessCommandBuffer::OrderingBarrier(int32_t put_offset) { @@ -1027,9 +1014,13 @@ bool requires_sync_point = handle.type == gfx::IO_SURFACE_BUFFER; uint64_t fence_sync = 0; - if (requires_sync_point) + if (requires_sync_point) { fence_sync = GenerateFenceSyncRelease(); + // Previous fence syncs should be flushed already. + DCHECK_EQ(fence_sync - 1, flushed_fence_sync_release_); + } + ScheduleGpuTask(base::BindOnce( &InProcessCommandBuffer::CreateImageOnGpuThread, gpu_thread_weak_ptr_factory_.GetWeakPtr(), new_id, std::move(handle), @@ -1039,6 +1030,7 @@ base::checked_cast<uint32_t>(internalformat), fence_sync)); if (fence_sync) { + flushed_fence_sync_release_ = fence_sync; SyncToken sync_token(GetNamespaceID(), GetCommandBufferID(), fence_sync); sync_token.SetVerifyFlush(); gpu_memory_buffer_manager_->SetDestructionSyncToken(gpu_memory_buffer, @@ -1139,13 +1131,58 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); SyncToken sync_token(GetNamespaceID(), GetCommandBufferID(), release); + context_group_->mailbox_manager()->PushTextureUpdates(sync_token); + sync_point_client_state_->ReleaseFenceSync(release); +} + +// TODO(sunnyps): Remove the wait command once all sync tokens are passed as +// task dependencies. +bool InProcessCommandBuffer::OnWaitSyncToken(const SyncToken& sync_token) { + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + DCHECK(!waiting_for_sync_point_); + TRACE_EVENT0("gpu", "InProcessCommandBuffer::OnWaitSyncToken"); + + SyncPointManager* sync_point_manager = task_executor_->sync_point_manager(); + DCHECK(sync_point_manager); MailboxManager* mailbox_manager = context_group_->mailbox_manager(); - if (mailbox_manager->UsesSync()) - mailbox_manager->PushTextureUpdates(sync_token); + DCHECK(mailbox_manager); - command_buffer_->SetReleaseCount(release); - sync_point_client_state_->ReleaseFenceSync(release); + if (task_executor_->BlockThreadOnWaitSyncToken()) { + // Wait if sync point wait is valid. + if (sync_point_client_state_->Wait( + sync_token, + base::Bind(&base::WaitableEvent::Signal, + base::Unretained(&fence_sync_wait_event_)))) { + fence_sync_wait_event_.Wait(); + } + + mailbox_manager->PullTextureUpdates(sync_token); + return false; + } + + waiting_for_sync_point_ = sync_point_client_state_->Wait( + sync_token, + base::Bind(&InProcessCommandBuffer::OnWaitSyncTokenCompleted, + gpu_thread_weak_ptr_factory_.GetWeakPtr(), sync_token)); + if (!waiting_for_sync_point_) { + mailbox_manager->PullTextureUpdates(sync_token); + return false; + } + + command_buffer_->SetScheduled(false); + task_sequence_->SetEnabled(false); + return true; +} + +void InProcessCommandBuffer::OnWaitSyncTokenCompleted( + const SyncToken& sync_token) { + DCHECK_CALLED_ON_VALID_SEQUENCE(gpu_sequence_checker_); + DCHECK(waiting_for_sync_point_); + context_group_->mailbox_manager()->PullTextureUpdates(sync_token); + waiting_for_sync_point_ = false; + command_buffer_->SetScheduled(true); + task_sequence_->SetEnabled(true); } void InProcessCommandBuffer::OnDescheduleUntilFinished() { @@ -1357,7 +1394,7 @@ return release <= GetLastState().release_count; } -void InProcessCommandBuffer::WaitSyncToken(const SyncToken& sync_token) { +void InProcessCommandBuffer::WaitSyncTokenHint(const SyncToken& sync_token) { next_flush_sync_token_fences_.push_back(sync_token); }
diff --git a/gpu/ipc/in_process_command_buffer.h b/gpu/ipc/in_process_command_buffer.h index 57bdefb0..243f330 100644 --- a/gpu/ipc/in_process_command_buffer.h +++ b/gpu/ipc/in_process_command_buffer.h
@@ -140,7 +140,7 @@ bool IsFenceSyncReleased(uint64_t release) override; void SignalSyncToken(const SyncToken& sync_token, base::OnceClosure callback) override; - void WaitSyncToken(const SyncToken& sync_token) override; + void WaitSyncTokenHint(const SyncToken& sync_token) override; bool CanWaitUnverifiedSyncToken(const SyncToken& sync_token) override; // CommandBufferServiceClient implementation (called on gpu thread): @@ -151,6 +151,7 @@ void OnConsoleMessage(int32_t id, const std::string& message) override; void CacheShader(const std::string& key, const std::string& shader) override; void OnFenceSyncRelease(uint64_t release) override; + bool OnWaitSyncToken(const SyncToken& sync_token) override; void OnDescheduleUntilFinished() override; void OnRescheduleAfterFinished() override; void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override; @@ -234,8 +235,7 @@ // Flush up to put_offset. If execution is deferred either by yielding, or due // to a sync token wait, HasUnprocessedCommandsOnGpuThread() returns true. - void FlushOnGpuThread(int32_t put_offset, - const std::vector<SyncToken>& sync_token_fences); + void FlushOnGpuThread(int32_t put_offset); bool HasUnprocessedCommandsOnGpuThread(); void UpdateLastStateOnGpuThread(); @@ -287,6 +287,7 @@ // Callbacks on the gpu thread. void PerformDelayedWorkOnGpuThread(); + void OnWaitSyncTokenCompleted(const SyncToken& sync_token); // Callback implementations on the client thread. void OnContextLost(); @@ -299,6 +300,7 @@ // Members accessed on the gpu thread (possibly with the exception of // creation): + bool waiting_for_sync_point_ = false; bool use_virtualized_gl_context_ = false; raster::GrShaderCache* gr_shader_cache_ = nullptr; scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_; @@ -330,6 +332,7 @@ Capabilities capabilities_; GpuMemoryBufferManager* gpu_memory_buffer_manager_ = nullptr; uint64_t next_fence_sync_release_ = 1; + uint64_t flushed_fence_sync_release_ = 0; std::vector<SyncToken> next_flush_sync_token_fences_; // Sequence checker for client sequence used for initialization, destruction, // callbacks, such as context loss, and methods which provide such callbacks,
diff --git a/gpu/ipc/service/command_buffer_stub.cc b/gpu/ipc/service/command_buffer_stub.cc index b3db1be..ed7e19a 100644 --- a/gpu/ipc/service/command_buffer_stub.cc +++ b/gpu/ipc/service/command_buffer_stub.cc
@@ -150,6 +150,7 @@ stream_id_(stream_id), route_id_(route_id), last_flush_id_(0), + waiting_for_sync_point_(false), previous_processed_num_(0), wait_set_get_buffer_count_(0) {} @@ -175,6 +176,7 @@ message.type() != GpuCommandBufferMsg_WaitForGetOffsetInRange::ID && message.type() != GpuCommandBufferMsg_RegisterTransferBuffer::ID && message.type() != GpuCommandBufferMsg_DestroyTransferBuffer::ID && + message.type() != GpuCommandBufferMsg_WaitSyncToken::ID && message.type() != GpuCommandBufferMsg_SignalSyncToken::ID && message.type() != GpuCommandBufferMsg_SignalQuery::ID) { if (!MakeCurrent()) @@ -199,6 +201,7 @@ OnRegisterTransferBuffer); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer, OnDestroyTransferBuffer); + IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_WaitSyncToken, OnWaitSyncToken) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncToken, OnSignalSyncToken) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalQuery, OnSignalQuery) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateImage, OnCreateImage); @@ -514,10 +517,7 @@ } } -void CommandBufferStub::OnAsyncFlush( - int32_t put_offset, - uint32_t flush_id, - const std::vector<SyncToken>& sync_token_fences) { +void CommandBufferStub::OnAsyncFlush(int32_t put_offset, uint32_t flush_id) { TRACE_EVENT1("gpu", "CommandBufferStub::OnAsyncFlush", "put_offset", put_offset); DCHECK(command_buffer_); @@ -525,22 +525,11 @@ // to catch regressions. Ignore the message. DVLOG_IF(0, flush_id - last_flush_id_ >= 0x8000000U) << "Received a Flush message out-of-order"; - // Check if sync token waits are invalid or already complete. Do not use - // SyncPointManager::IsSyncTokenReleased() as it can't say if the wait is - // invalid. - for (const auto& sync_token : sync_token_fences) - DCHECK(!sync_point_client_state_->Wait(sync_token, base::DoNothing())); last_flush_id_ = flush_id; CommandBuffer::State pre_state = command_buffer_->GetState(); FastSetActiveURL(active_url_, active_url_hash_, channel_); - MailboxManager* mailbox_manager = context_group_->mailbox_manager(); - if (mailbox_manager->UsesSync()) { - for (const auto& sync_token : sync_token_fences) - mailbox_manager->PullTextureUpdates(sync_token); - } - { auto* gr_shader_cache = channel_->gpu_channel_manager()->gr_shader_cache(); base::Optional<raster::GrShaderCache::ScopedCacheUse> cache_use; @@ -691,6 +680,43 @@ channel_->gpu_channel_manager()->ScheduleGrContextCleanup(); } +// TODO(sunnyps): Remove the wait command once all sync tokens are passed as +// task dependencies. +bool CommandBufferStub::OnWaitSyncToken(const SyncToken& sync_token) { + DCHECK(!waiting_for_sync_point_); + DCHECK(command_buffer_->scheduled()); + TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncToken", this, "CommandBufferStub", + this); + + waiting_for_sync_point_ = sync_point_client_state_->WaitNonThreadSafe( + sync_token, channel_->task_runner(), + base::Bind(&CommandBufferStub::OnWaitSyncTokenCompleted, AsWeakPtr(), + sync_token)); + + if (waiting_for_sync_point_) { + command_buffer_->SetScheduled(false); + channel_->OnCommandBufferDescheduled(this); + return true; + } + + MailboxManager* mailbox_manager = context_group_->mailbox_manager(); + if (mailbox_manager->UsesSync() && MakeCurrent()) + mailbox_manager->PullTextureUpdates(sync_token); + return false; +} + +void CommandBufferStub::OnWaitSyncTokenCompleted(const SyncToken& sync_token) { + DCHECK(waiting_for_sync_point_); + TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncToken", this, "CommandBufferStub", + this); + // Don't call PullTextureUpdates here because we can't MakeCurrent if we're + // executing commands on another context. The WaitSyncToken command will run + // again and call PullTextureUpdates once this command buffer gets scheduled. + waiting_for_sync_point_ = false; + command_buffer_->SetScheduled(true); + channel_->OnCommandBufferScheduled(this); +} + void CommandBufferStub::OnCreateImage( GpuCommandBufferMsg_CreateImage_Params params) { TRACE_EVENT0("gpu", "CommandBufferStub::OnCreateImage");
diff --git a/gpu/ipc/service/command_buffer_stub.h b/gpu/ipc/service/command_buffer_stub.h index 5e8d3e99..dfd7ebb6 100644 --- a/gpu/ipc/service/command_buffer_stub.h +++ b/gpu/ipc/service/command_buffer_stub.h
@@ -97,6 +97,7 @@ void OnConsoleMessage(int32_t id, const std::string& message) override; void CacheShader(const std::string& key, const std::string& shader) override; void OnFenceSyncRelease(uint64_t release) override; + bool OnWaitSyncToken(const SyncToken& sync_token) override; void OnDescheduleUntilFinished() override; void OnRescheduleAfterFinished() override; void ScheduleGrContextCleanup() override; @@ -179,9 +180,7 @@ // Message handlers: void OnSetGetBuffer(int32_t shm_id); virtual void OnTakeFrontBuffer(const Mailbox& mailbox) = 0; - virtual void OnReturnFrontBuffer(const Mailbox& mailbox, - const SyncToken& sync_token, - bool is_lost) = 0; + virtual void OnReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) = 0; void OnGetState(IPC::Message* reply_message); void OnWaitForTokenInRange(int32_t start, int32_t end, @@ -190,9 +189,7 @@ int32_t start, int32_t end, IPC::Message* reply_message); - void OnAsyncFlush(int32_t put_offset, - uint32_t flush_id, - const std::vector<SyncToken>& sync_token_fences); + void OnAsyncFlush(int32_t put_offset, uint32_t flush_id); void OnRegisterTransferBuffer(int32_t id, base::UnsafeSharedMemoryRegion transfer_buffer); void OnDestroyTransferBuffer(int32_t id); @@ -207,6 +204,8 @@ const gfx::GpuFenceHandle& handle); void OnGetGpuFenceHandle(uint32_t gpu_fence_id); + void OnWaitSyncTokenCompleted(const SyncToken& sync_token); + void OnCreateImage(GpuCommandBufferMsg_CreateImage_Params params); void OnDestroyImage(int32_t id); void OnCreateStreamTexture(uint32_t texture_id, @@ -238,6 +237,8 @@ base::ObserverList<DestructionObserver>::Unchecked destruction_observers_; + bool waiting_for_sync_point_; + base::TimeTicks process_delayed_work_time_; uint32_t previous_processed_num_; base::TimeTicks last_idle_time_;
diff --git a/gpu/ipc/service/gles2_command_buffer_stub.cc b/gpu/ipc/service/gles2_command_buffer_stub.cc index 211aa42b..a5c624a 100644 --- a/gpu/ipc/service/gles2_command_buffer_stub.cc +++ b/gpu/ipc/service/gles2_command_buffer_stub.cc
@@ -426,14 +426,7 @@ } void GLES2CommandBufferStub::OnReturnFrontBuffer(const Mailbox& mailbox, - const SyncToken& sync_token, bool is_lost) { - // Check if sync token wait is invalid or already complete. Do not use - // SyncPointManager::IsSyncTokenReleased() as it can't say if the wait is - // invalid. - DCHECK(!sync_point_client_state_->Wait(sync_token, base::DoNothing())); - // No need to pull texture updates. - DCHECK(!context_group_->mailbox_manager()->UsesSync()); gles2_decoder_->ReturnFrontBuffer(mailbox, is_lost); }
diff --git a/gpu/ipc/service/gles2_command_buffer_stub.h b/gpu/ipc/service/gles2_command_buffer_stub.h index ae0cd39..4d4530ba 100644 --- a/gpu/ipc/service/gles2_command_buffer_stub.h +++ b/gpu/ipc/service/gles2_command_buffer_stub.h
@@ -51,9 +51,7 @@ private: void OnTakeFrontBuffer(const Mailbox& mailbox) override; - void OnReturnFrontBuffer(const Mailbox& mailbox, - const SyncToken& sync_token, - bool is_lost) override; + void OnReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override; void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override; // Keep a more specifically typed reference to the decoder to avoid
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc index 59f1a96..af29d8b3 100644 --- a/gpu/ipc/service/gpu_channel.cc +++ b/gpu/ipc/service/gpu_channel.cc
@@ -104,11 +104,6 @@ private: ~GpuChannelMessageFilter() override; - SequenceId GetSequenceId(int32_t route_id) const; - - bool HandleFlushMessage(const IPC::Message& message); - bool HandleReturnFrontBufferMessage(const IPC::Message& message); - bool MessageErrorHandler(const IPC::Message& message, const char* error_msg); IPC::Channel* ipc_channel_ = nullptr; @@ -223,16 +218,6 @@ if (message.should_unblock() || message.is_reply()) return MessageErrorHandler(message, "Unexpected message type"); - switch (message.type()) { - case GpuCommandBufferMsg_AsyncFlush::ID: - case GpuCommandBufferMsg_DestroyTransferBuffer::ID: - case GpuChannelMsg_CreateSharedImage::ID: - case GpuChannelMsg_DestroySharedImage::ID: - return MessageErrorHandler(message, "Invalid message"); - default: - break; - } - if (message.type() == GpuChannelMsg_Nop::ID) { IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message); ipc_channel_->Send(reply); @@ -248,96 +233,64 @@ if (!gpu_channel_) return MessageErrorHandler(message, "Channel destroyed"); - // Handle flush first so that it doesn't get handled out of order. - if (message.type() == GpuChannelMsg_FlushDeferredMessages::ID) - return HandleFlushMessage(message); + switch (message.type()) { + case GpuCommandBufferMsg_AsyncFlush::ID: + case GpuCommandBufferMsg_DestroyTransferBuffer::ID: + case GpuChannelMsg_CreateSharedImage::ID: + case GpuChannelMsg_DestroySharedImage::ID: + return MessageErrorHandler(message, "Invalid message"); + default: + break; + } - if (message.type() == GpuCommandBufferMsg_ReturnFrontBuffer::ID) - return HandleReturnFrontBufferMessage(message); + if (message.type() == GpuChannelMsg_FlushDeferredMessages::ID) { + GpuChannelMsg_FlushDeferredMessages::Param params; - bool handle_out_of_order = - message.routing_id() == MSG_ROUTING_CONTROL || - message.type() == GpuCommandBufferMsg_WaitForTokenInRange::ID || - message.type() == GpuCommandBufferMsg_WaitForGetOffsetInRange::ID; + if (!GpuChannelMsg_FlushDeferredMessages::Read(&message, ¶ms)) + return MessageErrorHandler(message, "Invalid flush message"); - if (handle_out_of_order) { + std::vector<GpuDeferredMessage> deferred_messages = + std::get<0>(std::move(params)); + std::vector<Scheduler::Task> tasks; + tasks.reserve(deferred_messages.size()); + + for (auto& deferred_message : deferred_messages) { + auto it = route_sequences_.find(deferred_message.message.routing_id()); + if (it == route_sequences_.end()) { + DLOG(ERROR) << "Invalid route id in flush list"; + continue; + } + + tasks.emplace_back( + it->second /* sequence_id */, + base::BindOnce(&GpuChannel::HandleMessage, gpu_channel_->AsWeakPtr(), + std::move(deferred_message.message)), + std::move(deferred_message.sync_token_fences)); + } + + scheduler_->ScheduleTasks(std::move(tasks)); + + } else if (message.routing_id() == MSG_ROUTING_CONTROL || + message.type() == GpuCommandBufferMsg_WaitForTokenInRange::ID || + message.type() == + GpuCommandBufferMsg_WaitForGetOffsetInRange::ID) { // It's OK to post task that may never run even for sync messages, because // if the channel is destroyed, the client Send will fail. - main_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&GpuChannel::HandleOutOfOrderMessage, - gpu_channel_->AsWeakPtr(), message)); - return true; + main_task_runner_->PostTask(FROM_HERE, + base::Bind(&GpuChannel::HandleOutOfOrderMessage, + gpu_channel_->AsWeakPtr(), message)); + } else { + auto it = route_sequences_.find(message.routing_id()); + if (it == route_sequences_.end()) + return MessageErrorHandler(message, "Invalid route id"); + + scheduler_->ScheduleTask( + Scheduler::Task(it->second /* sequence_id */, + base::BindOnce(&GpuChannel::HandleMessage, + gpu_channel_->AsWeakPtr(), message), + std::vector<SyncToken>())); } - // Messages which do not have sync token dependencies. - SequenceId sequence_id = GetSequenceId(message.routing_id()); - if (sequence_id.is_null()) - return MessageErrorHandler(message, "Invalid route id"); - - scheduler_->ScheduleTask( - Scheduler::Task(sequence_id, - base::BindOnce(&GpuChannel::HandleMessage, - gpu_channel_->AsWeakPtr(), message), - std::vector<SyncToken>())); - return true; -} - -SequenceId GpuChannelMessageFilter::GetSequenceId(int32_t route_id) const { - gpu_channel_lock_.AssertAcquired(); - auto it = route_sequences_.find(route_id); - if (it == route_sequences_.end()) - return SequenceId(); - return it->second; -} - -bool GpuChannelMessageFilter::HandleFlushMessage(const IPC::Message& message) { - DCHECK_EQ(message.type(), GpuChannelMsg_FlushDeferredMessages::ID); - gpu_channel_lock_.AssertAcquired(); - - GpuChannelMsg_FlushDeferredMessages::Param params; - if (!GpuChannelMsg_FlushDeferredMessages::Read(&message, ¶ms)) - return MessageErrorHandler(message, "Invalid flush message"); - - std::vector<GpuDeferredMessage> deferred_messages = - std::get<0>(std::move(params)); - - std::vector<Scheduler::Task> tasks; - tasks.reserve(deferred_messages.size()); - for (auto& deferred_message : deferred_messages) { - auto it = route_sequences_.find(deferred_message.message.routing_id()); - if (it == route_sequences_.end()) { - DLOG(ERROR) << "Invalid route id in flush list"; - continue; - } - tasks.emplace_back( - it->second /* sequence_id */, - base::BindOnce(&GpuChannel::HandleMessage, gpu_channel_->AsWeakPtr(), - std::move(deferred_message.message)), - std::move(deferred_message.sync_token_fences)); - } - scheduler_->ScheduleTasks(std::move(tasks)); - return true; -} - -bool GpuChannelMessageFilter::HandleReturnFrontBufferMessage( - const IPC::Message& message) { - DCHECK_EQ(message.type(), GpuCommandBufferMsg_ReturnFrontBuffer::ID); - gpu_channel_lock_.AssertAcquired(); - - GpuCommandBufferMsg_ReturnFrontBuffer::Param params; - if (!GpuCommandBufferMsg_ReturnFrontBuffer::Read(&message, ¶ms)) - return MessageErrorHandler(message, "Invalid ReturnFrontBuffer message"); - - SequenceId sequence_id = GetSequenceId(message.routing_id()); - if (sequence_id.is_null()) - return MessageErrorHandler(message, "Invalid route id"); - - SyncToken sync_token = std::get<1>(params); - scheduler_->ScheduleTask( - Scheduler::Task(sequence_id, - base::BindOnce(&GpuChannel::HandleMessage, - gpu_channel_->AsWeakPtr(), message), - std::vector<SyncToken>{sync_token})); return true; } @@ -538,7 +491,8 @@ // If we get descheduled or yield while processing a message. if (stub && (stub->HasUnprocessedCommands() || !stub->IsScheduled())) { - DCHECK_EQ(GpuCommandBufferMsg_AsyncFlush::ID, msg.type()); + DCHECK((uint32_t)GpuCommandBufferMsg_AsyncFlush::ID == msg.type() || + (uint32_t)GpuCommandBufferMsg_WaitSyncToken::ID == msg.type()); scheduler_->ContinueTask( stub->sequence_id(), base::BindOnce(&GpuChannel::HandleMessage, AsWeakPtr(), msg));
diff --git a/gpu/ipc/service/raster_command_buffer_stub.cc b/gpu/ipc/service/raster_command_buffer_stub.cc index 3f8a69d..dda58ab 100644 --- a/gpu/ipc/service/raster_command_buffer_stub.cc +++ b/gpu/ipc/service/raster_command_buffer_stub.cc
@@ -233,7 +233,6 @@ NOTREACHED(); } void RasterCommandBufferStub::OnReturnFrontBuffer(const Mailbox& mailbox, - const SyncToken& sync_token, bool is_lost) { NOTREACHED(); }
diff --git a/gpu/ipc/service/raster_command_buffer_stub.h b/gpu/ipc/service/raster_command_buffer_stub.h index 28989f1..b1b0547 100644 --- a/gpu/ipc/service/raster_command_buffer_stub.h +++ b/gpu/ipc/service/raster_command_buffer_stub.h
@@ -30,9 +30,7 @@ private: void OnTakeFrontBuffer(const Mailbox& mailbox) override; - void OnReturnFrontBuffer(const Mailbox& mailbox, - const SyncToken& sync_token, - bool is_lost) override; + void OnReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override; void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override; void SetActiveURL(GURL url) override; void ResetActiveURL() override;
diff --git a/gpu/ipc/service/webgpu_command_buffer_stub.cc b/gpu/ipc/service/webgpu_command_buffer_stub.cc index 9dafcd2..99e089e6 100644 --- a/gpu/ipc/service/webgpu_command_buffer_stub.cc +++ b/gpu/ipc/service/webgpu_command_buffer_stub.cc
@@ -171,7 +171,6 @@ LOG(ERROR) << "Called WebGPUCommandBufferStub::OnTakeFrontBuffer"; } void WebGPUCommandBufferStub::OnReturnFrontBuffer(const Mailbox& mailbox, - const SyncToken& sync_token, bool is_lost) { LOG(ERROR) << "Called WebGPUCommandBufferStub::OnReturnFrontBuffer"; }
diff --git a/gpu/ipc/service/webgpu_command_buffer_stub.h b/gpu/ipc/service/webgpu_command_buffer_stub.h index 866ae1f..cc74b5d 100644 --- a/gpu/ipc/service/webgpu_command_buffer_stub.h +++ b/gpu/ipc/service/webgpu_command_buffer_stub.h
@@ -30,9 +30,7 @@ private: void OnTakeFrontBuffer(const Mailbox& mailbox) override; - void OnReturnFrontBuffer(const Mailbox& mailbox, - const SyncToken& sync_token, - bool is_lost) override; + void OnReturnFrontBuffer(const Mailbox& mailbox, bool is_lost) override; void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override; DISALLOW_COPY_AND_ASSIGN(WebGPUCommandBufferStub);
diff --git a/gpu/vulkan/features.gni b/gpu/vulkan/features.gni index 315646cb4..d97fadb7 100644 --- a/gpu/vulkan/features.gni +++ b/gpu/vulkan/features.gni
@@ -8,11 +8,5 @@ # For details see declare_args() in build/config/BUILDCONFIG.gn. declare_args() { # Enable experimental vulkan backend. - enable_vulkan = is_linux || is_android || is_fuchsia - - # We want to temporarily disable Vulkan on Android to give us time to - # investigate ways to reduce its binary size. - if (is_android) { - enable_vulkan = false - } + enable_vulkan = is_linux || is_fuchsia }
diff --git a/gpu/vulkan/init/BUILD.gn b/gpu/vulkan/init/BUILD.gn index 5d8f2aa..7800c20 100644 --- a/gpu/vulkan/init/BUILD.gn +++ b/gpu/vulkan/init/BUILD.gn
@@ -32,4 +32,7 @@ if (use_ozone) { deps += [ "//ui/ozone" ] } + if (is_win) { + deps += [ "//gpu/vulkan/win32" ] + } }
diff --git a/gpu/vulkan/init/vulkan_factory.cc b/gpu/vulkan/init/vulkan_factory.cc index fd27ac3..4b842bc 100644 --- a/gpu/vulkan/init/vulkan_factory.cc +++ b/gpu/vulkan/init/vulkan_factory.cc
@@ -11,6 +11,10 @@ #include "gpu/vulkan/android/vulkan_implementation_android.h" #endif +#if defined(OS_WIN) +#include "gpu/vulkan/win32/vulkan_implementation_win32.h" +#endif + #if defined(USE_X11) #include "gpu/vulkan/x/vulkan_implementation_x11.h" // nogncheck #endif @@ -31,6 +35,8 @@ return ui::OzonePlatform::GetInstance() ->GetSurfaceFactoryOzone() ->CreateVulkanImplementation(); +#elif defined(OS_WIN) + return std::make_unique<VulkanImplementationWin32>(); #else #error Unsupported Vulkan Platform. #endif
diff --git a/gpu/vulkan/win32/BUILD.gn b/gpu/vulkan/win32/BUILD.gn new file mode 100644 index 0000000..d1834ff8 --- /dev/null +++ b/gpu/vulkan/win32/BUILD.gn
@@ -0,0 +1,35 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/ui.gni") +import("//gpu/vulkan/features.gni") + +assert(enable_vulkan) +assert(is_win) + +config("vulkan_win32") { + defines = [ "VK_USE_PLATFORM_WIN32_KHR" ] +} + +component("win32") { + output_name = "vulkan_win32" + + sources = [ + "vulkan_implementation_win32.cc", + "vulkan_implementation_win32.h", + ] + + defines = [ "IS_VULKAN_WIN32_IMPL" ] + + public_configs = [ ":vulkan_win32" ] + + deps = [ + "//ui/gfx", + ] + + public_deps = [ + "//base", + "//gpu/vulkan", + ] +}
diff --git a/gpu/vulkan/win32/vulkan_implementation_win32.cc b/gpu/vulkan/win32/vulkan_implementation_win32.cc new file mode 100644 index 0000000..0e3fa1a --- /dev/null +++ b/gpu/vulkan/win32/vulkan_implementation_win32.cc
@@ -0,0 +1,110 @@ +// Copyright (c) 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/vulkan/win32/vulkan_implementation_win32.h" + +#include <Windows.h> + +#include "base/files/file_path.h" +#include "base/logging.h" +#include "gpu/vulkan/vulkan_function_pointers.h" +#include "gpu/vulkan/vulkan_instance.h" +#include "gpu/vulkan/vulkan_surface.h" +#include "ui/gfx/gpu_fence.h" + +namespace gpu { + +VulkanImplementationWin32::~VulkanImplementationWin32() = default; + +bool VulkanImplementationWin32::InitializeVulkanInstance() { + std::vector<const char*> required_extensions = { + VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME}; + + VulkanFunctionPointers* vulkan_function_pointers = + gpu::GetVulkanFunctionPointers(); + + base::NativeLibraryLoadError native_library_load_error; + vulkan_function_pointers->vulkan_loader_library_ = base::LoadNativeLibrary( + base::FilePath(L"vulkan-1.dll"), &native_library_load_error); + if (!vulkan_function_pointers->vulkan_loader_library_) + return false; + + if (!vulkan_instance_.Initialize(required_extensions, {})) { + vulkan_instance_.Destroy(); + return false; + } + + // Initialize platform function pointers + vkGetPhysicalDeviceWin32PresentationSupportKHR_ = + reinterpret_cast<PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR>( + vkGetInstanceProcAddr( + vulkan_instance_.vk_instance(), + "vkGetPhysicalDeviceWin32PresentationSupportKHR")); + if (!vkGetPhysicalDeviceWin32PresentationSupportKHR_) { + LOG(ERROR) << "vkGetPhysicalDeviceWin32PresentationSupportKHR not found"; + vulkan_instance_.Destroy(); + return false; + } + + vkCreateWin32SurfaceKHR_ = + reinterpret_cast<PFN_vkCreateWin32SurfaceKHR>(vkGetInstanceProcAddr( + vulkan_instance_.vk_instance(), "vkCreateWin32SurfaceKHR")); + if (!vkCreateWin32SurfaceKHR_) { + LOG(ERROR) << "vkCreateWin32SurfaceKHR not found"; + vulkan_instance_.Destroy(); + return false; + } + + return true; +} + +VkInstance VulkanImplementationWin32::GetVulkanInstance() { + return vulkan_instance_.vk_instance(); +} + +std::unique_ptr<VulkanSurface> VulkanImplementationWin32::CreateViewSurface( + gfx::AcceleratedWidget window) { + VkSurfaceKHR surface; + VkWin32SurfaceCreateInfoKHR surface_create_info = {}; + surface_create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + surface_create_info.hinstance = + reinterpret_cast<HINSTANCE>(GetWindowLongPtr(window, GWLP_HINSTANCE)); + surface_create_info.hwnd = window; + VkResult result = vkCreateWin32SurfaceKHR_( + GetVulkanInstance(), &surface_create_info, nullptr, &surface); + if (VK_SUCCESS != result) { + DLOG(ERROR) << "vkCreatWin32SurfaceKHR() failed: " << result; + return nullptr; + } + + return std::make_unique<VulkanSurface>(GetVulkanInstance(), surface); +} + +bool VulkanImplementationWin32::GetPhysicalDevicePresentationSupport( + VkPhysicalDevice device, + const std::vector<VkQueueFamilyProperties>& queue_family_properties, + uint32_t queue_family_index) { + return vkGetPhysicalDeviceWin32PresentationSupportKHR_(device, + queue_family_index); +} + +std::vector<const char*> +VulkanImplementationWin32::GetRequiredDeviceExtensions() { + return {VK_KHR_SWAPCHAIN_EXTENSION_NAME}; +} + +VkFence VulkanImplementationWin32::CreateVkFenceForGpuFence( + VkDevice vk_device) { + NOTREACHED(); + return VK_NULL_HANDLE; +} + +std::unique_ptr<gfx::GpuFence> +VulkanImplementationWin32::ExportVkFenceToGpuFence(VkDevice vk_device, + VkFence vk_fence) { + NOTREACHED(); + return nullptr; +} + +} // namespace gpu
diff --git a/gpu/vulkan/win32/vulkan_implementation_win32.h b/gpu/vulkan/win32/vulkan_implementation_win32.h new file mode 100644 index 0000000..43c3352 --- /dev/null +++ b/gpu/vulkan/win32/vulkan_implementation_win32.h
@@ -0,0 +1,49 @@ +// Copyright (c) 2018 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 GPU_VULKAN_WIN32_VULKAN_IMPLEMENTATION_WIN32_H_ +#define GPU_VULKAN_WIN32_VULKAN_IMPLEMENTATION_WIN32_H_ + +#include <memory> + +#include "base/component_export.h" +#include "gpu/vulkan/vulkan_implementation.h" +#include "gpu/vulkan/vulkan_instance.h" + +namespace gpu { + +class COMPONENT_EXPORT(VULKAN_WIN32) VulkanImplementationWin32 + : public VulkanImplementation { + public: + VulkanImplementationWin32() = default; + ~VulkanImplementationWin32() override; + + // VulkanImplementation: + bool InitializeVulkanInstance() override; + VkInstance GetVulkanInstance() override; + std::unique_ptr<VulkanSurface> CreateViewSurface( + gfx::AcceleratedWidget window) override; + bool GetPhysicalDevicePresentationSupport( + VkPhysicalDevice device, + const std::vector<VkQueueFamilyProperties>& queue_family_properties, + uint32_t queue_family_index) override; + std::vector<const char*> GetRequiredDeviceExtensions() override; + VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override; + std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence( + VkDevice vk_device, + VkFence vk_fence) override; + + private: + VulkanInstance vulkan_instance_; + + PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR + vkGetPhysicalDeviceWin32PresentationSupportKHR_ = nullptr; + PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(VulkanImplementationWin32); +}; + +} // namespace gpu + +#endif // GPU_VULKAN_WIN32_VULKAN_IMPLEMENTATION_WIN32_H_
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index fa9ca30..4603850f 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -564,6 +564,7 @@ test("headless_unittests") { sources = [ + "lib/browser/protocol/protocol_unittest.cc", "public/domains/types_unittest.cc", "public/util/error_reporter_unittest.cc", ]
diff --git a/headless/lib/browser/headless_request_context_manager.cc b/headless/lib/browser/headless_request_context_manager.cc index b859494..653f587 100644 --- a/headless/lib/browser/headless_request_context_manager.cc +++ b/headless/lib/browser/headless_request_context_manager.cc
@@ -357,6 +357,11 @@ builder->SetCreateHttpTransactionFactoryCallback( base::BindOnce(&content::CreateDevToolsNetworkTransactionFactory)); builder->SetInterceptors(std::move(request_interceptors_)); + for (auto& protocol_handler : protocol_handlers_) { + builder->SetProtocolHandler(protocol_handler.first, + std::move(protocol_handler.second)); + } + protocol_handlers_.clear(); net::URLRequestContext* url_request_context = nullptr; network_context_owner_ =
diff --git a/headless/lib/browser/protocol/protocol_string.cc b/headless/lib/browser/protocol/protocol_string.cc index c102f2fe..5e82611 100644 --- a/headless/lib/browser/protocol/protocol_string.cc +++ b/headless/lib/browser/protocol/protocol_string.cc
@@ -4,6 +4,8 @@ #include "headless/lib/browser/protocol/protocol_string.h" +#include <utility> +#include "base/base64.h" #include "base/json/json_reader.h" #include "base/memory/ptr_util.h" #include "base/strings/string16.h" @@ -159,5 +161,54 @@ string_.reserve(capacity); } +Binary::Binary() : bytes_(new base::RefCountedBytes) {} +Binary::Binary(const Binary& binary) : bytes_(binary.bytes_) {} +Binary::Binary(scoped_refptr<base::RefCountedMemory> bytes) : bytes_(bytes) {} +Binary::~Binary() {} + +String Binary::toBase64() const { + std::string encoded; + base::Base64Encode( + base::StringPiece(reinterpret_cast<const char*>(data()), size()), + &encoded); + return encoded; +} + +// static +Binary Binary::fromBase64(const String& base64, bool* success) { + std::string decoded; + *success = base::Base64Decode(base::StringPiece(base64), &decoded); + if (*success) { + return Binary::fromString(std::move(decoded)); + } + return Binary(); +} + +// static +Binary Binary::fromRefCounted(scoped_refptr<base::RefCountedMemory> memory) { + return Binary(memory); +} + +// static +Binary Binary::fromVector(std::vector<uint8_t>&& data) { + return Binary(base::RefCountedBytes::TakeVector(&data)); +} + +// static +Binary Binary::fromVector(const std::vector<uint8_t>& data) { + std::vector<uint8_t> copied_data(data); + return Binary(base::RefCountedBytes::TakeVector(&copied_data)); +} + +// static +Binary Binary::fromString(std::string&& data) { + return Binary(base::RefCountedString::TakeString(&data)); +} + +// static +Binary Binary::fromString(const std::string& data) { + std::string copied_data(data); + return Binary(base::RefCountedString::TakeString(&copied_data)); +} } // namespace protocol } // namespace headless
diff --git a/headless/lib/browser/protocol/protocol_string.h b/headless/lib/browser/protocol/protocol_string.h index fd77f7e..f6d988ca 100644 --- a/headless/lib/browser/protocol/protocol_string.h +++ b/headless/lib/browser/protocol/protocol_string.h
@@ -7,9 +7,11 @@ #include <memory> #include <string> +#include <vector> #include "base/logging.h" #include "base/macros.h" +#include "base/memory/ref_counted_memory.h" #include "base/strings/string_number_conversions.h" #include "headless/public/headless_export.h" @@ -83,6 +85,29 @@ static std::unique_ptr<Value> parseJSON(const String&); }; +// A read-only sequence of uninterpreted bytes with reference-counted storage. +class HEADLESS_EXPORT Binary { + public: + Binary(const Binary&); + Binary(); + ~Binary(); + + const uint8_t* data() const { return bytes_->front(); } + size_t size() const { return bytes_->size(); } + + String toBase64() const; + static Binary fromBase64(const String& base64, bool* success); + static Binary fromRefCounted(scoped_refptr<base::RefCountedMemory> memory); + static Binary fromVector(std::vector<uint8_t>&& data); + static Binary fromVector(const std::vector<uint8_t>& data); + static Binary fromString(std::string&& data); + static Binary fromString(const std::string& data); + + private: + explicit Binary(scoped_refptr<base::RefCountedMemory> bytes); + scoped_refptr<base::RefCountedMemory> bytes_; +}; + std::unique_ptr<Value> toProtocolValue(const base::Value* value, int depth); std::unique_ptr<base::Value> toBaseValue(Value* value, int depth);
diff --git a/headless/lib/browser/protocol/protocol_unittest.cc b/headless/lib/browser/protocol/protocol_unittest.cc new file mode 100644 index 0000000..3d5419f9 --- /dev/null +++ b/headless/lib/browser/protocol/protocol_unittest.cc
@@ -0,0 +1,59 @@ +// Copyright 2018 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 "headless/lib/browser/protocol/protocol_string.h" + +#include <vector> +#include "testing/gtest/include/gtest/gtest.h" + +namespace headless { +namespace protocol { +namespace { +TEST(ProtocolBinaryTest, base64EmptyArgs) { + EXPECT_EQ(protocol::String(), Binary().toBase64()); + + bool success = false; + Binary decoded = Binary::fromBase64("", &success); + EXPECT_TRUE(success); + EXPECT_EQ( + std::vector<uint8_t>(), + std::vector<uint8_t>(decoded.data(), decoded.data() + decoded.size())); +} + +TEST(ProtocolStringTest, AllBytesBase64Roundtrip) { + std::vector<uint8_t> all_bytes; + for (int ii = 0; ii < 255; ++ii) + all_bytes.push_back(ii); + Binary binary = Binary::fromVector(all_bytes); + bool success = false; + Binary decoded = Binary::fromBase64(binary.toBase64(), &success); + EXPECT_TRUE(success); + std::vector<uint8_t> decoded_bytes(decoded.data(), + decoded.data() + decoded.size()); + EXPECT_EQ(all_bytes, decoded_bytes); +} + +TEST(ProtocolStringTest, HelloWorldBase64Roundtrip) { + const char* kMsg = "Hello, world."; + std::vector<uint8_t> msg(kMsg, kMsg + strlen(kMsg)); + EXPECT_EQ(strlen(kMsg), msg.size()); + + protocol::String encoded = Binary::fromVector(msg).toBase64(); + EXPECT_EQ("SGVsbG8sIHdvcmxkLg==", encoded); + bool success = false; + Binary decoded_binary = Binary::fromBase64(encoded, &success); + EXPECT_TRUE(success); + std::vector<uint8_t> decoded(decoded_binary.data(), + decoded_binary.data() + decoded_binary.size()); + EXPECT_EQ(msg, decoded); +} + +TEST(ProtocolBinaryTest, InvalidBase64Decode) { + bool success = true; + Binary binary = Binary::fromBase64("This is not base64.", &success); + EXPECT_FALSE(success); +} +} // namespace +} // namespace protocol +} // namespace headless
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg index 1925860..40f9f7c 100644 --- a/infra/config/global/cr-buildbucket.cfg +++ b/infra/config/global/cr-buildbucket.cfg
@@ -2159,12 +2159,6 @@ mixins: "libfuzzer" } builders { - name: "WebKit Win Builder" - # This may be obsolete (WebKit Win10 is triggered by Win Builder). - dimensions: "os:Windows-10" - mixins: "webkit-ci" - } - builders { name: "VR Linux" dimensions: "os:Ubuntu-14.04" mixins: "fyi-ci" @@ -2364,12 +2358,6 @@ mixins: "android-fyi-ci" } builders { - name: "WebKit Mac Builder" - # This may be obsolete (WebKit Mac testers are triggered by Mac Builder). - dimensions: "os:Mac-10.12.2" - mixins: "webkit-ci" - } - builders { name: "Linux ChromiumOS MSan Builder" dimensions: "os:Ubuntu-14.04" mixins: "memory-ci"
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg index 552a6cd..49656b8 100644 --- a/infra/config/global/luci-milo.cfg +++ b/infra/config/global/luci-milo.cfg
@@ -695,23 +695,11 @@ short_name: "cfi" } builders { - name: "buildbot/chromium.webkit/WebKit Win Builder" - category: "chromium.webkit|win rel|builder" - short_name: "32" - } - builders { - name: "buildbot/chromium.webkit/WebKit Win10" name: "buildbucket/luci.chromium.ci/WebKit Win10" category: "chromium.webkit|win rel|tester" short_name: "10" } builders { - name: "buildbot/chromium.webkit/WebKit Mac Builder" - category: "chromium.webkit|mac|release" - short_name: "bld" - } - builders { - name: "buildbot/chromium.webkit/WebKit Mac10.13 (retina)" name: "buildbucket/luci.chromium.ci/WebKit Mac10.13 (retina)" category: "chromium.webkit|mac|release" short_name: "13r" @@ -1150,7 +1138,6 @@ short_name: "32" } builders { - name: "buildbot/chromium.webkit/WebKit Win10" name: "buildbucket/luci.chromium.ci/WebKit Win10" category: "win|release|tester" short_name: "10" @@ -1162,7 +1149,6 @@ short_name: "bld" } builders { - name: "buildbot/chromium.webkit/WebKit Mac10.13 (retina)" name: "buildbucket/luci.chromium.ci/WebKit Mac10.13 (retina)" category: "mac|release" short_name: "13r"
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg index 61532c6..8bd4650 100644 --- a/infra/config/global/luci-scheduler.cfg +++ b/infra/config/global/luci-scheduler.cfg
@@ -3681,17 +3681,6 @@ } job { - # This may be obsolete (WebKit Mac testers are triggered by Mac Builder). - id: "WebKit Mac Builder" - acl_sets: "default" - buildbucket: { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "WebKit Mac Builder" - } -} - -job { id: "WebKit Mac10.13 (retina)" # Triggered by "Mac Builder" acl_sets: "triggered-by-parent-builders" @@ -3703,17 +3692,6 @@ } job { - id: "WebKit Win Builder" - # This may be obsolete (WebKit Win10 is triggered by Win Builder). - acl_sets: "default" - buildbucket: { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.ci" - builder: "WebKit Win Builder" - } -} - -job { id: "WebKit Win10" # Triggered by "Win Builder" acl_sets: "triggered-by-parent-builders"
diff --git a/ios/build/bots/tests/eg_tests.json b/ios/build/bots/tests/eg_tests.json index 7ea59225..e6249baa 100644 --- a/ios/build/bots/tests/eg_tests.json +++ b/ios/build/bots/tests/eg_tests.json
@@ -23,13 +23,6 @@ "xctest": true }, { - "app": "ios_chrome_payments_egtests", - "test args": [ - "--enable-features=WebPayments" - ], - "xctest": true - }, - { "app": "ios_chrome_reading_list_egtests", "test args": [ "--enable-reading-list"
diff --git a/ios/chrome/browser/autofill/automation/BUILD.gn b/ios/chrome/browser/autofill/automation/BUILD.gn index b2ae8079..2336f40 100644 --- a/ios/chrome/browser/autofill/automation/BUILD.gn +++ b/ios/chrome/browser/autofill/automation/BUILD.gn
@@ -15,6 +15,7 @@ deps = [ "//base", "//components/autofill/core/browser:browser", + "//components/autofill/ios/browser:autofill_test_bundle_data", "//components/autofill/ios/browser:browser", "//components/strings", "//ios/chrome/app/strings",
diff --git a/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm b/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm index d0fa79a..44be9da 100644 --- a/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm +++ b/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm
@@ -124,19 +124,20 @@ return; } - // If this is a form suggestion view and no suggestions have been triggered - // yet, don't show the custom view. - FormSuggestionView* formSuggestionView = - base::mac::ObjCCast<FormSuggestionView>(view); - if (formSuggestionView) { - int numSuggestions = [[formSuggestionView suggestions] count]; - if (!_suggestionsHaveBeenShown && numSuggestions == 0) { - self.customAccessoryView = nil; - return; + if (!autofill::features::IsPasswordManualFallbackEnabled()) { + // If this is a form suggestion view and no suggestions have been + // triggered yet, don't show the custom view. + FormSuggestionView* formSuggestionView = + base::mac::ObjCCast<FormSuggestionView>(view); + if (formSuggestionView) { + int numSuggestions = [[formSuggestionView suggestions] count]; + if (!_suggestionsHaveBeenShown && numSuggestions == 0) { + self.customAccessoryView = nil; + return; + } } + _suggestionsHaveBeenShown = YES; } - _suggestionsHaveBeenShown = YES; - self.customAccessoryView = [[FormInputAccessoryView alloc] init]; [self.customAccessoryView setUpWithCustomView:view]; [self addCustomAccessoryViewIfNeeded]; @@ -249,7 +250,6 @@ // keyboard view is created by the system, i.e. the first time the keyboard // will appear. if (!IsIPadIdiom()) { - [self addCustomAccessoryViewIfNeeded]; [self addCustomKeyboardViewIfNeeded]; } }
diff --git a/ios/chrome/browser/ui/autofill/BUILD.gn b/ios/chrome/browser/ui/autofill/BUILD.gn index 7a5fbcb..11940562 100644 --- a/ios/chrome/browser/ui/autofill/BUILD.gn +++ b/ios/chrome/browser/ui/autofill/BUILD.gn
@@ -105,6 +105,7 @@ deps = [ ":autofill_ui", "//components/autofill/core/browser", + "//components/autofill/ios/browser:autofill_test_bundle_data", "//components/autofill/ios/browser:test_support", "//components/strings:components_strings_grit", "//ios/chrome/browser/autofill",
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.h b/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.h index 3dbb98d..bc307c20 100644 --- a/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.h +++ b/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.h
@@ -24,7 +24,7 @@ // accessory view elements. @interface FormInputAccessoryCoordinator : ChromeCoordinator -// The delegate for the password coordinator. Must be set before it starts. +// The delegate for the coordinator. Must be set before it starts. @property(nonatomic, weak) id<FormInputAccessoryCoordinatorDelegate> delegate; // Creates a coordinator that uses a |viewController| a |browserState| and
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.mm index 3e49373..34fbd58 100644 --- a/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.mm +++ b/ios/chrome/browser/ui/autofill/form_input_accessory_coordinator.mm
@@ -11,6 +11,7 @@ #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.h" #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.h" #import "ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.h" +#include "ios/chrome/browser/ui/ui_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -97,7 +98,7 @@ [self.childCoordinators removeAllObjects]; } -- (void)startPasswords { +- (void)startPasswordsFromButton:(UIButton*)button { ManualFillPasswordCoordinator* passwordCoordinator = [[ManualFillPasswordCoordinator alloc] initWithBaseViewController:self.baseViewController @@ -105,10 +106,14 @@ webStateList:self.webStateList injectionHandler:self.manualFillInjectionHandler]; passwordCoordinator.delegate = self; - [self.formInputAccessoryViewController - presentView:passwordCoordinator.viewController.view]; - [self.childCoordinators addObject:passwordCoordinator]; + if (IsIPadIdiom()) { + [passwordCoordinator presentFromButton:button]; + } else { + [self.formInputAccessoryViewController + presentView:passwordCoordinator.viewController.view]; + } + [self.childCoordinators addObject:passwordCoordinator]; [self.formInputAccessoryMediator disableSuggestions]; } @@ -129,9 +134,9 @@ // TODO(crbug.com/845472): implement. } -- (void)passwordButtonPressed { +- (void)passwordButtonPressed:(UIButton*)sender { [self stopChildren]; - [self startPasswords]; + [self startPasswordsFromButton:sender]; } #pragma mark - PasswordCoordinatorDelegate @@ -140,4 +145,8 @@ [self.delegate openPasswordSettings]; } +- (void)resetAccessoryView { + [self.manualFillAccessoryViewController reset]; +} + @end
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.mm index 9ed640a..3c2293ed 100644 --- a/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.mm +++ b/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.mm
@@ -131,6 +131,14 @@ selector:@selector(handleTextInputDidBeginEditing:) name:UITextFieldTextDidBeginEditingNotification object:nil]; + [defaultCenter addObserver:self + selector:@selector(handleTextInputDidEndEditing:) + name:UITextFieldTextDidEndEditingNotification + object:nil]; + [defaultCenter addObserver:self + selector:@selector(handleKeyboardWillShow:) + name:UIKeyboardWillShowNotification + object:nil]; _keyboardObserver = [[KeyboardObserverHelper alloc] init]; _keyboardObserver.delegate = self; } @@ -416,13 +424,29 @@ navigationDelegate:self.formInputAccessoryHandler]; } -// When any text field or text view (e.g. omnibox, settings, card unmask dialog) -// begins editing, reset ourselves so that we don't present our custom view over +#pragma mark - Keyboard Notifications + +// When the keyboard is shown, send the last suggestions to the consumer. +- (void)handleKeyboardWillShow:(NSNotification*)notification { + if (self.lastSuggestionView) { + [self updateWithProvider:self.lastProvider + suggestionView:self.lastSuggestionView]; + } +} + +// When any text field or text view (e.g. omnibox, settings search bar) +// begins editing, pause the consumer so it doesn't present the custom view over // the keyboard. - (void)handleTextInputDidBeginEditing:(NSNotification*)notification { [self.consumer pauseCustomKeyboardView]; } +// When any text field or text view (e.g. omnibox, settings, card unmask dialog) +// ends editing, continue presenting. +- (void)handleTextInputDidEndEditing:(NSNotification*)notification { + [self.consumer continueCustomKeyboardView]; +} + #pragma mark - Tests - (void)injectWebState:(web::WebState*)webState {
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn index ad9f099..55b52628 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn +++ b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
@@ -28,9 +28,11 @@ "//ios/chrome/browser/autofill:autofill_shared", "//ios/chrome/browser/autofill/manual_fill:manual_fill", "//ios/chrome/browser/passwords", + "//ios/chrome/browser/ui:ui_util", "//ios/chrome/browser/ui/autofill/manual_fill:manual_fill_ui", "//ios/chrome/browser/ui/coordinators:chrome_coordinators", "//ios/chrome/browser/ui/list_model:list_model", + "//ios/chrome/browser/ui/table_view:presentation", "//ios/chrome/browser/ui/table_view:table_view", "//ios/chrome/browser/web_state_list:web_state_list", "//ios/web/public:public",
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.h b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.h index bae9fc4..935e1f6 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.h +++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.h
@@ -33,7 +33,7 @@ - (void)keyboardButtonPressed; // Invoked after the user touches the `passwords` button. -- (void)passwordButtonPressed; +- (void)passwordButtonPressed:(UIButton*)sender; @end
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.mm index 6d2065e..e685cda 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.mm
@@ -6,6 +6,7 @@ #include "components/autofill/core/common/autofill_features.h" #import "ios/chrome/browser/ui/autofill/manual_fill/uicolor_manualfill.h" +#include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -62,17 +63,21 @@ self.view.translatesAutoresizingMaskIntoConstraints = NO; UIColor* tintColor = [self activeTintColor]; + NSMutableArray<UIView*>* icons = [[NSMutableArray alloc] init]; - self.keyboardButton = [UIButton buttonWithType:UIButtonTypeSystem]; - UIImage* keyboardImage = [UIImage imageNamed:@"ic_keyboard"]; - [self.keyboardButton setImage:keyboardImage forState:UIControlStateNormal]; - self.keyboardButton.tintColor = tintColor; - self.keyboardButton.translatesAutoresizingMaskIntoConstraints = NO; - [self.keyboardButton addTarget:self - action:@selector(keyboardButtonPressed) - forControlEvents:UIControlEventTouchUpInside]; - self.keyboardButton.accessibilityIdentifier = - manual_fill::AccessoryKeyboardAccessibilityIdentifier; + if (!IsIPadIdiom()) { + self.keyboardButton = [UIButton buttonWithType:UIButtonTypeSystem]; + UIImage* keyboardImage = [UIImage imageNamed:@"ic_keyboard"]; + [self.keyboardButton setImage:keyboardImage forState:UIControlStateNormal]; + self.keyboardButton.tintColor = tintColor; + self.keyboardButton.translatesAutoresizingMaskIntoConstraints = NO; + [self.keyboardButton addTarget:self + action:@selector(keyboardButtonPressed) + forControlEvents:UIControlEventTouchUpInside]; + self.keyboardButton.accessibilityIdentifier = + manual_fill::AccessoryKeyboardAccessibilityIdentifier; + [icons addObject:self.keyboardButton]; + } self.passwordButton = [UIButton buttonWithType:UIButtonTypeSystem]; UIImage* keyImage = [UIImage imageNamed:@"ic_vpn_key"]; @@ -80,12 +85,12 @@ self.passwordButton.tintColor = tintColor; self.passwordButton.translatesAutoresizingMaskIntoConstraints = NO; [self.passwordButton addTarget:self - action:@selector(passwordButtonPressed) + action:@selector(passwordButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; self.passwordButton.accessibilityIdentifier = manual_fill::AccessoryPasswordAccessibilityIdentifier; + [icons addObject:self.passwordButton]; - NSArray* views; if (autofill::features::IsAutofillManualFallbackEnabled()) { self.cardsButton = [UIButton buttonWithType:UIButtonTypeSystem]; UIImage* cardImage = [UIImage imageNamed:@"ic_credit_card"]; @@ -97,6 +102,7 @@ forControlEvents:UIControlEventTouchUpInside]; self.cardsButton.accessibilityIdentifier = manual_fill::AccessoryCreditCardAccessibilityIdentifier; + [icons addObject:self.cardsButton]; self.accountButton = [UIButton buttonWithType:UIButtonTypeSystem]; UIImage* accountImage = [UIImage imageNamed:@"addresses"]; @@ -108,15 +114,9 @@ forControlEvents:UIControlEventTouchUpInside]; self.accountButton.accessibilityIdentifier = manual_fill::AccessoryAddressAccessibilityIdentifier; - - views = @[ - self.keyboardButton, self.passwordButton, self.accountButton, - self.cardsButton - ]; - } else { - views = @[ self.keyboardButton, self.passwordButton ]; + [icons addObject:self.accountButton]; } - UIStackView* stackView = [[UIStackView alloc] initWithArrangedSubviews:views]; + UIStackView* stackView = [[UIStackView alloc] initWithArrangedSubviews:icons]; stackView.spacing = 10; stackView.axis = UILayoutConstraintAxisHorizontal; stackView.translatesAutoresizingMaskIntoConstraints = NO; @@ -177,11 +177,11 @@ [self.delegate keyboardButtonPressed]; } -- (void)passwordButtonPressed { +- (void)passwordButtonPressed:(UIButton*)sender { [self animateKeyboardButtonHidden:NO]; [self resetTintColors]; [self.passwordButton setTintColor:UIColor.cr_manualFillTintColor]; - [self.delegate passwordButtonPressed]; + [self.delegate passwordButtonPressed:sender]; } - (void)cardButtonPressed {
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.h b/ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.h index 914fa26..ac218d5 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.h +++ b/ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.h
@@ -10,9 +10,18 @@ @class ManualFillInjectionHandler; class WebStateList; +namespace manual_fill { + +extern NSString* const PasswordDoneButtonAccessibilityIdentifier; + +} // namespace manual_fill + // Delegate for the coordinator actions. @protocol PasswordCoordinatorDelegate<NSObject> +// Resets the accessory view. +- (void)resetAccessoryView; + // Opens the passwords settings. - (void)openPasswordSettings; @@ -43,6 +52,9 @@ (ios::ChromeBrowserState*)browserState NS_UNAVAILABLE; +// Presents the password view controller as a popover from the passed button. +- (void)presentFromButton:(UIButton*)button; + @end #endif // IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_PASSWORD_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.mm b/ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.mm index fe37eb30..d8b7b6c 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.mm
@@ -11,12 +11,26 @@ #import "ios/chrome/browser/ui/autofill/manual_fill/password_list_delegate.h" #import "ios/chrome/browser/ui/autofill/manual_fill/password_mediator.h" #import "ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.h" +#import "ios/chrome/browser/ui/table_view/table_view_animator.h" +#import "ios/chrome/browser/ui/table_view/table_view_navigation_controller.h" +#import "ios/chrome/browser/ui/table_view/table_view_presentation_controller.h" +#include "ios/chrome/browser/ui/ui_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -@interface ManualFillPasswordCoordinator ()<PasswordListDelegate> +namespace manual_fill { + +NSString* const PasswordDoneButtonAccessibilityIdentifier = + @"kManualFillPasswordDoneButtonAccessibilityIdentifier"; + +} // namespace manual_fill + +@interface ManualFillPasswordCoordinator ()< + PasswordListDelegate, + UIViewControllerTransitioningDelegate, + UIPopoverPresentationControllerDelegate> // Fetches and filters the passwords for the view controller. @property(nonatomic, strong) ManualFillPasswordMediator* passwordMediator; @@ -34,6 +48,10 @@ @property(nonatomic, strong) ManualFillInjectionHandler* manualFillInjectionHandler; +// Button presenting this coordinator in a popover. Used for continuation after +// dismissing any presented view controller. iPad only. +@property(nonatomic, weak) UIButton* presentingButton; + @end @implementation ManualFillPasswordCoordinator @@ -69,7 +87,12 @@ } - (void)stop { - [self.passwordViewController.view removeFromSuperview]; + if (IsIPadIdiom() && self.passwordViewController.presentingViewController) { + [self.passwordViewController dismissViewControllerAnimated:true + completion:nil]; + } else { + [self.passwordViewController.view removeFromSuperview]; + } [self.allPasswordsViewController dismissViewControllerAnimated:YES completion:nil]; } @@ -78,9 +101,88 @@ return self.passwordViewController; } +- (void)presentFromButton:(UIButton*)button { + self.presentingButton = button; + self.passwordViewController.modalPresentationStyle = + UIModalPresentationPopover; + + // The |button.window.rootViewController| is used in order to present above + // the keyboard. This way the popover will be dismissed on keyboard + // interaction and it won't be covered when the keyboard is near the top of + // the screen. + [button.window.rootViewController + presentViewController:self.passwordViewController + animated:YES + completion:nil]; + + UIPopoverPresentationController* popoverPresentationController = + self.passwordViewController.popoverPresentationController; + popoverPresentationController.sourceView = button; + popoverPresentationController.sourceRect = button.bounds; + popoverPresentationController.permittedArrowDirections = + UIPopoverArrowDirectionUp | UIMenuControllerArrowDown; + popoverPresentationController.delegate = self; +} + +#pragma mark - UIViewControllerTransitioningDelegate + +- (UIPresentationController*) +presentationControllerForPresentedViewController:(UIViewController*)presented + presentingViewController:(UIViewController*)presenting + sourceViewController:(UIViewController*)source { + TableViewPresentationController* presentationController = + [[TableViewPresentationController alloc] + initWithPresentedViewController:presented + presentingViewController:presenting]; + presentationController.position = TablePresentationPositionLeading; + return presentationController; +} + +- (id<UIViewControllerAnimatedTransitioning>) +animationControllerForPresentedController:(UIViewController*)presented + presentingController:(UIViewController*)presenting + sourceController:(UIViewController*)source { + UITraitCollection* traitCollection = presenting.traitCollection; + if (traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact && + traitCollection.verticalSizeClass != UIUserInterfaceSizeClassCompact) { + // Use the default animator for fullscreen presentations. + return nil; + } + + TableViewAnimator* animator = [[TableViewAnimator alloc] init]; + animator.presenting = YES; + animator.direction = TableAnimatorDirectionFromLeading; + return animator; +} + +- (id<UIViewControllerAnimatedTransitioning>) +animationControllerForDismissedController:(UIViewController*)dismissed { + UITraitCollection* traitCollection = dismissed.traitCollection; + if (traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact && + traitCollection.verticalSizeClass != UIUserInterfaceSizeClassCompact) { + // Use the default animator for fullscreen presentations. + return nil; + } + + TableViewAnimator* animator = [[TableViewAnimator alloc] init]; + animator.presenting = NO; + animator.direction = TableAnimatorDirectionFromLeading; + return animator; +} + #pragma mark - PasswordListDelegate - (void)openAllPasswordsList { + // On iPad, first dismiss the popover before the new view is presented. + __weak __typeof(self) weakSelf = self; + if (IsIPadIdiom() && self.passwordViewController.presentingViewController) { + [self.passwordViewController + dismissViewControllerAnimated:true + completion:^{ + [weakSelf openAllPasswordsList]; + }]; + return; + } UISearchController* searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; searchController.searchResultsUpdater = self.passwordMediator; @@ -89,26 +191,57 @@ [PasswordViewController alloc] initWithSearchController:searchController]; self.passwordMediator.disableFilter = YES; self.passwordMediator.consumer = allPasswordsViewController; - - UINavigationController* navigationController = [[UINavigationController alloc] - initWithRootViewController:allPasswordsViewController]; - if (@available(iOS 11, *)) { - navigationController.navigationBar.prefersLargeTitles = YES; - } + UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemDone + target:self + action:@selector(dismissPresentedViewController)]; + doneButton.accessibilityIdentifier = + manual_fill::PasswordDoneButtonAccessibilityIdentifier; + allPasswordsViewController.navigationItem.rightBarButtonItem = doneButton; self.allPasswordsViewController = allPasswordsViewController; + + TableViewNavigationController* navigationController = + [[TableViewNavigationController alloc] + initWithTable:allPasswordsViewController]; + navigationController.transitioningDelegate = self; + [navigationController setModalPresentationStyle:UIModalPresentationCustom]; + [self.baseViewController presentViewController:navigationController animated:YES completion:nil]; } - (void)dismissPresentedViewController { + // Dismiss the full screen view controller and present the pop over. + __weak __typeof(self) weakSelf = self; [self.allPasswordsViewController.presentingViewController dismissViewControllerAnimated:YES - completion:nil]; + completion:^{ + if (weakSelf.presentingButton) { + [weakSelf + presentFromButton:weakSelf.presentingButton]; + } + }]; } - (void)openPasswordSettings { + // On iPad, dismiss the popover before the settings are presented. + if (IsIPadIdiom() && self.passwordViewController.presentingViewController) { + [self.passwordViewController + dismissViewControllerAnimated:true + completion:^{ + [self openPasswordSettings]; + }]; + return; + } [self.delegate openPasswordSettings]; } +#pragma mark - UIPopoverPresentationControllerDelegate + +- (void)popoverPresentationControllerDidDismissPopover: + (UIPopoverPresentationController*)popoverPresentationController { + [self.delegate resetAccessoryView]; +} + @end
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_list_delegate.h b/ios/chrome/browser/ui/autofill/manual_fill/password_list_delegate.h index 9e7fc6b6..ed1ffc6 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/password_list_delegate.h +++ b/ios/chrome/browser/ui/autofill/manual_fill/password_list_delegate.h
@@ -7,12 +7,17 @@ // Delegate for actions in manual fallback's passwords list. @protocol PasswordListDelegate -// Dismisses the presented view controller. + +// Dismisses the presented view controller and continues as pop over on iPads +// or above the keyboard else. - (void)dismissPresentedViewController; + // Requests to open the list of all passwords. - (void)openAllPasswordsList; + // Opens passwords settings. - (void)openPasswordSettings; + @end #endif // IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_PASSWORD_LIST_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.h b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.h index c1539a0..83d9d7771 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.h +++ b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.h
@@ -14,6 +14,7 @@ extern NSString* const PasswordSearchBarAccessibilityIdentifier; extern NSString* const PasswordTableViewAccessibilityIdentifier; +extern NSString* const PasswordDoneButtonAccessibilityIdentifier; } // namespace manual_fill
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.mm b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.mm index e5a60c9..9b498ea 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.mm
@@ -8,6 +8,7 @@ #import "ios/chrome/browser/ui/autofill/manual_fill/action_cell.h" #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_password_cell.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" +#include "ios/chrome/browser/ui/ui_util.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -31,6 +32,12 @@ ActionsSectionIdentifier, }; +// This is the width used for |self.preferredContentSize|. +constexpr float PopoverPreferredWidth = 320; + +// This is the maximum height used for |self.preferredContentSize|. +constexpr float PopoverMaxHeight = 250; + } // namespace @interface PasswordViewController () @@ -80,10 +87,6 @@ NSString* titleString = l10n_util::GetNSString(IDS_IOS_MANUAL_FALLBACK_USE_OTHER_PASSWORD); self.title = titleString; - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] - initWithBarButtonSystemItem:UIBarButtonSystemItemDone - target:self - action:@selector(handleDoneNavigationItemTap)]; if (!base::ios::IsRunningOnIOS11OrLater()) { // On iOS 11 this is not needed since the cell constrains are updated by the @@ -108,11 +111,6 @@ #pragma mark - Private -// Callback for the "Done" navigation item. -- (void)handleDoneNavigationItemTap { - [self dismissViewControllerAnimated:YES completion:nil]; -} - // Presents |items| in the respective section. Handles creating or deleting the // section accordingly. - (void)presentItems:(NSArray<TableViewItem*>*)items @@ -145,6 +143,15 @@ } } [self.tableView reloadData]; + if (IsIPadIdiom()) { + // Update the preffered content size on iPad so the popover shows the right + // size. + [self.tableView layoutIfNeeded]; + CGSize systemLayoutSize = self.tableView.contentSize; + CGFloat preferredHeight = MIN(systemLayoutSize.height, PopoverMaxHeight); + self.preferredContentSize = + CGSizeMake(PopoverPreferredWidth, preferredHeight); + } } @end
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm index 4d8b1f88..6ee50dd 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
@@ -16,6 +16,7 @@ #include "components/password_manager/core/browser/password_store_consumer.h" #include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h" #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_accessory_view_controller.h" +#import "ios/chrome/browser/ui/autofill/manual_fill/password_coordinator.h" #import "ios/chrome/browser/ui/autofill/manual_fill/password_mediator.h" #import "ios/chrome/browser/ui/autofill/manual_fill/password_view_controller.h" #import "ios/chrome/browser/ui/ui_util.h" @@ -48,6 +49,11 @@ manual_fill::AccessoryPasswordAccessibilityIdentifier); } +id<GREYMatcher> KeyboardIconMatcher() { + return grey_accessibilityID( + manual_fill::AccessoryKeyboardAccessibilityIdentifier); +} + // Returns a matcher for the password table view in manual fallback. id<GREYMatcher> PasswordTableViewMatcher() { return grey_accessibilityID( @@ -73,6 +79,11 @@ manual_fill::OtherPasswordsAccessibilityIdentifier); } +id<GREYMatcher> OtherPasswordsDismissMatcher() { + return grey_accessibilityID( + manual_fill::PasswordDoneButtonAccessibilityIdentifier); +} + // Returns a matcher for the example username in the list. id<GREYMatcher> UsernameButtonMatcher() { return grey_buttonTitle(base::SysUTF8ToNSString(kExampleUsername)); @@ -88,6 +99,13 @@ return grey_accessibilityID(@"SettingsSearchCellTextField"); } +// Returns a matcher for the PasswordTableView window. +id<GREYMatcher> PasswordTableViewWindowMatcher() { + id<GREYMatcher> classMatcher = grey_kindOfClass([UIWindow class]); + id<GREYMatcher> parentMatcher = grey_descendant(PasswordTableViewMatcher()); + return grey_allOf(classMatcher, parentMatcher, nil); +} + // Gets the current password store. scoped_refptr<password_manager::PasswordStore> GetPasswordStore() { // ServiceAccessType governs behaviour in Incognito: only modifications with @@ -208,12 +226,8 @@ [super tearDown]; } -// Test that the passwords view controller appears on screen. +// Tests that the passwords view controller appears on screen. - (void)testPasswordsViewControllerIsPresented { - // TODO:(https://crbug.com/878388) Enable on iPad when supported. - if (IsIPadIdiom()) - return; - // Bring up the keyboard. [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] performAction:chrome_test_util::TapWebElement(kFormElementUsername)]; @@ -227,13 +241,9 @@ assertWithMatcher:grey_sufficientlyVisible()]; } -// Test that the passwords view controller contains the "Manage Passwords..." +// Tests that the passwords view controller contains the "Manage Passwords..." // action. - (void)testPasswordsViewControllerContainsManagePasswordsAction { - // TODO:(https://crbug.com/878388) Enable on iPad when supported. - if (IsIPadIdiom()) - return; - // Bring up the keyboard. [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] performAction:chrome_test_util::TapWebElement(kFormElementUsername)]; @@ -247,12 +257,8 @@ assertWithMatcher:grey_interactable()]; } -// Test that the "Manage Passwords..." action works. +// Tests that the "Manage Passwords..." action works. - (void)testManagePasswordsActionOpensPasswordSettings { - // TODO:(https://crbug.com/878388) Enable on iPad when supported. - if (IsIPadIdiom()) - return; - // Bring up the keyboard. [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] performAction:chrome_test_util::TapWebElement(kFormElementUsername)]; @@ -270,12 +276,8 @@ assertWithMatcher:grey_sufficientlyVisible()]; } -// Test that the Password View Controller is not present when presenting UI. +// Tests that the Password View Controller is not present when presenting UI. - (void)testPasswordControllerPauses { - // TODO:(https://crbug.com/878388) Enable on iPad when supported. - if (IsIPadIdiom()) - return; - // For the search bar to appear in password settings at least one password is // needed. SaveExamplePasswordForm(); @@ -293,7 +295,6 @@ performAction:grey_tap()]; // Tap the password search. - [[EarlGrey selectElementWithMatcher:PasswordSettingsSearchMatcher()] performAction:grey_tap()]; @@ -303,13 +304,9 @@ assertWithMatcher:grey_notVisible()]; } -// Test that the Password View Controller is resumed after selecting other +// Tests that the Password View Controller is resumed after selecting other // password. - (void)testPasswordControllerResumes { - // TODO:(https://crbug.com/878388) Enable on iPad when supported. - if (IsIPadIdiom()) - return; - // For this test one password is needed. SaveExamplePasswordForm(); @@ -321,7 +318,7 @@ [[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] performAction:grey_tap()]; - // Tap the "Manage Passwords..." action. + // Tap the "Other Passwords..." action. [[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()] performAction:grey_tap()]; @@ -334,18 +331,145 @@ [[EarlGrey selectElementWithMatcher:UsernameButtonMatcher()] performAction:grey_tap()]; - // Only on iOS 12 it is certain that on iPhones the keyboard is back. On iOS - // 11, it varies by device and version. - if (base::ios::IsRunningOnIOS12OrLater()) { - // Verify the password controller table view and the keyboard are visible. - GREYAssertTrue([GREYKeyboard isKeyboardShown], @"Keyboard Should be Shown"); + // Wait for the password list to disappear. Using the search bar, since the + // popover doesn't have it. + [[EarlGrey selectElementWithMatcher:PasswordSearchBarMatcher()] + assertWithMatcher:grey_notVisible()]; + + // Only on iOS 11.3 it is certain that on iPhones the keyboard is back. On iOS + // 11.0-11.2, it varies by device and version. + if ([GREYKeyboard isKeyboardShown]) { [[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] assertWithMatcher:grey_sufficientlyVisible()]; - } else if (!base::ios::IsRunningOnIOS11OrLater()) { - // On iOS 10 the keyboard is hidden. - GREYAssertFalse([GREYKeyboard isKeyboardShown], - @"Keyboard Should be Hidden"); + [[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] + assertWithMatcher:grey_sufficientlyVisible()]; } } +// Tests that the Password View Controller is resumed after dismissing "Other +// Passwords". +- (void)testPasswordControllerResumesWhenOtherPasswordsDismiss { + // Bring up the keyboard. + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] + performAction:chrome_test_util::TapWebElement(kFormElementUsername)]; + + // Tap on the passwords icon. + [[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] + performAction:grey_tap()]; + + // Tap the "Other Passwords..." action. + [[EarlGrey selectElementWithMatcher:OtherPasswordsMatcher()] + performAction:grey_tap()]; + + // Dismiss the Other Passwords view. + [[EarlGrey selectElementWithMatcher:OtherPasswordsDismissMatcher()] + performAction:grey_tap()]; + + // Wait for the password list to disappear. Using the search bar, since the + // popover doesn't have it. + [[EarlGrey selectElementWithMatcher:PasswordSearchBarMatcher()] + assertWithMatcher:grey_notVisible()]; + + // Only on iOS 11.3 it is certain that on iPhones the keyboard is back. On iOS + // 11.0-11.2, it varies by device and version. + if ([GREYKeyboard isKeyboardShown]) { + [[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] + assertWithMatcher:grey_sufficientlyVisible()]; + } +} + +// Tests that the Password View Controller is dismissed when tapping the +// keyboard icon. +- (void)testKeyboardIconDismissPasswordController { + if (IsIPadIdiom()) { + // The keyboard icon is never present in iPads. + return; + } + // Bring up the keyboard. + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] + performAction:chrome_test_util::TapWebElement(kFormElementUsername)]; + + // Tap on the passwords icon. + [[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] + performAction:grey_tap()]; + + // Verify the password controller table view is visible. + [[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] + assertWithMatcher:grey_sufficientlyVisible()]; + + // Tap on the keyboard icon. + [[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()] + performAction:grey_tap()]; + + // Verify the password controller table view and the password icon is NOT + // visible. + [[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] + assertWithMatcher:grey_notVisible()]; + [[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()] + assertWithMatcher:grey_notVisible()]; +} + +// Tests that the Password View Controller is dismissed when tapping the outside +// the popover on iPad. +- (void)testIPadTappingOutsidePopOverDismissPasswordController { + if (!IsIPadIdiom()) { + return; + } + // Bring up the keyboard. + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] + performAction:chrome_test_util::TapWebElement(kFormElementUsername)]; + + // Tap on the passwords icon. + [[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] + performAction:grey_tap()]; + + // Verify the password controller table view is visible. + [[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] + assertWithMatcher:grey_sufficientlyVisible()]; + + // Tap on a point outside of the popover. + // The way EarlGrey taps doesn't go through the window hierarchy. Because of + // this, the tap needs to be done in the same window as the popover. + [[EarlGrey selectElementWithMatcher:PasswordTableViewWindowMatcher()] + performAction:grey_tapAtPoint(CGPointMake(0, 0))]; + + // Verify the password controller table view and the password icon is NOT + // visible. + [[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] + assertWithMatcher:grey_notVisible()]; + [[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()] + assertWithMatcher:grey_notVisible()]; +} + +// Tests that the Password View Controller is dismissed when tapping the +// keyboard. +- (void)testTappingKeyboardDismissPasswordControllerPopOver { + if (!IsIPadIdiom()) { + return; + } + // Bring up the keyboard. + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] + performAction:chrome_test_util::TapWebElement(kFormElementUsername)]; + + // Tap on the passwords icon. + [[EarlGrey selectElementWithMatcher:PasswordIconMatcher()] + performAction:grey_tap()]; + + // Verify the password controller table view is visible. + [[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] + assertWithMatcher:grey_sufficientlyVisible()]; + + [[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] + performAction:grey_typeText(@"text")]; + + // Verify the password controller table view and the password icon is NOT + // visible. + [[EarlGrey selectElementWithMatcher:PasswordTableViewMatcher()] + assertWithMatcher:grey_notVisible()]; + [[EarlGrey selectElementWithMatcher:KeyboardIconMatcher()] + assertWithMatcher:grey_notVisible()]; +} + @end
diff --git a/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm b/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm index 985c134..af1f525 100644 --- a/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm +++ b/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm
@@ -157,6 +157,11 @@ personal_data_manager_->RemoveByGUID(creditCard->guid()); } + // Clear existing profiles. + for (const auto* profile : personal_data_manager_->GetProfiles()) { + personal_data_manager_->RemoveByGUID(profile->guid()); + } + [super tearDown]; } @@ -409,6 +414,10 @@ // Google Payments, and UMA metrics are correctly logged if the user accepts // upload. - (void)testUMA_Upstream_UserAccepts { + // TODO(crbug.com/895687): Re-enable this test after eliminating the need for + // disabling EarlGrey synchronization. + EARL_GREY_TEST_DISABLED(@"Test disabled."); + base::HistogramTester histogram_tester; [ChromeEarlGrey
diff --git a/ios/chrome/browser/ui/payments/BUILD.gn b/ios/chrome/browser/ui/payments/BUILD.gn index 64aa0fd..3ecf90f 100644 --- a/ios/chrome/browser/ui/payments/BUILD.gn +++ b/ios/chrome/browser/ui/payments/BUILD.gn
@@ -258,6 +258,7 @@ "//components/autofill/core/browser:test_support", "//components/image_fetcher/core", "//components/payments/core", + "//components/payments/core:payments_test_bundle_data", "//components/payments/mojom", "//components/prefs", "//components/strings",
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index deb8ccc..294c12b 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -8,7 +8,6 @@ testonly = true deps = [ ":ios_chrome_autofill_automation_egtests", - ":ios_chrome_autofill_egtests", ":ios_chrome_bookmarks_egtests", ":ios_chrome_device_check_egtests", ":ios_chrome_external_url_egtests", @@ -16,7 +15,6 @@ ":ios_chrome_integration_egtests", ":ios_chrome_manual_fill_egtests", ":ios_chrome_multitasking_egtests", - ":ios_chrome_payments_egtests", ":ios_chrome_perf_egtests", ":ios_chrome_reading_list_egtests", ":ios_chrome_settings_egtests", @@ -43,18 +41,8 @@ ] } -chrome_ios_eg_test("ios_chrome_autofill_egtests") { - deps = [ - ":test_support", - "//components/autofill/ios/browser:autofill_test_bundle_data", - "//ios/chrome/browser/ui/autofill:eg_tests", - ] -} - chrome_ios_eg_test("ios_chrome_autofill_automation_egtests") { deps = [ - ":test_support", - "//components/autofill/ios/browser:autofill_test_bundle_data", "//ios/chrome/browser/autofill/automation:eg_tests", ] } @@ -66,14 +54,6 @@ ] } -chrome_ios_eg_test("ios_chrome_payments_egtests") { - deps = [ - ":test_support", - "//components/payments/core:payments_test_bundle_data", - "//ios/chrome/browser/ui/payments:eg_tests", - ] -} - chrome_ios_eg_test("ios_chrome_reading_list_egtests") { deps = [ ":test_support", @@ -106,6 +86,7 @@ "//ios/chrome/browser/ui:eg_tests", "//ios/chrome/browser/ui/activity_services:eg_tests", "//ios/chrome/browser/ui/alert_coordinator:eg_tests", + "//ios/chrome/browser/ui/autofill:eg_tests", "//ios/chrome/browser/ui/content_suggestions:eg_tests", "//ios/chrome/browser/ui/dialogs:eg_tests", "//ios/chrome/browser/ui/download:eg_tests", @@ -115,6 +96,7 @@ "//ios/chrome/browser/ui/history:eg_tests", "//ios/chrome/browser/ui/infobars:eg_tests", "//ios/chrome/browser/ui/ntp:eg_tests", + "//ios/chrome/browser/ui/payments:eg_tests", "//ios/chrome/browser/ui/popup_menu:eg_tests", "//ios/chrome/browser/ui/print:eg_tests", "//ios/chrome/browser/ui/qr_scanner:eg_tests",
diff --git a/ios/web/net/cookies/wk_http_system_cookie_store.mm b/ios/web/net/cookies/wk_http_system_cookie_store.mm index dfbb178..205c2d1 100644 --- a/ios/web/net/cookies/wk_http_system_cookie_store.mm +++ b/ios/web/net/cookies/wk_http_system_cookie_store.mm
@@ -48,6 +48,22 @@ return canonical_cookie.IncludeForRequestURL(url, options); } +// Prioritizes queued WKHTTPCookieStore completion handlers to run as soon as +// possible. This function is needed because some of WKHTTPCookieStore methods +// completion handlers are not called until there is a WKWebView on the view +// hierarchy. +void PrioritizeWKHTTPCookieStoreCallbacks() { + // TODO(crbug.com/885218): Currently this hack is needed to fix + // crbug.com/885218. Remove when the behavior of + // [WKHTTPCookieStore getAllCookies:] changes. + NSSet* data_types = [NSSet setWithObject:WKWebsiteDataTypeCookies]; + [[WKWebsiteDataStore defaultDataStore] + removeDataOfTypes:data_types + modifiedSince:[NSDate distantFuture] + completionHandler:^{ + }]; +} + } // namespace WKHTTPSystemCookieStore::WKHTTPSystemCookieStore( @@ -89,6 +105,7 @@ RunSystemCookieCallbackForCookies(std::move(shared_callback), weak_time_manager, result); }]; + PrioritizeWKHTTPCookieStoreCallbacks(); } else { net::ReportGetCookiesForURLResult( net::SystemCookieStoreType::kWKHTTPSystemCookieStore, false); @@ -115,6 +132,7 @@ RunSystemCookieCallbackForCookies(std::move(shared_callback), weak_time_manager, cookies); }]; + PrioritizeWKHTTPCookieStoreCallbacks(); } else { RunSystemCookieCallbackForCookies(std::move(shared_callback), weak_time_manager, @[]);
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn index b616e028..2e862882 100644 --- a/ios/web_view/BUILD.gn +++ b/ios/web_view/BUILD.gn
@@ -84,6 +84,8 @@ "public/cwv_autofill_suggestion.h", "public/cwv_credit_card.h", "public/cwv_credit_card_verifier.h", + "public/cwv_credit_card_verifier_data_source.h", + "public/cwv_credit_card_verifier_delegate.h", "public/cwv_preferences_autofill.h", "public/cwv_web_view_autofill.h", "public/cwv_web_view_configuration_autofill.h",
diff --git a/ios/web_view/internal/autofill/cwv_autofill_client_ios_bridge.h b/ios/web_view/internal/autofill/cwv_autofill_client_ios_bridge.h index 9d7bde75..addb2131 100644 --- a/ios/web_view/internal/autofill/cwv_autofill_client_ios_bridge.h +++ b/ios/web_view/internal/autofill/cwv_autofill_client_ios_bridge.h
@@ -33,6 +33,9 @@ - (void)didReceiveUnmaskVerificationResult: (autofill::AutofillClient::PaymentsRpcResult)result; +// Bridge for AutofillClient's method |LoadRiskData|. +- (void)loadRiskData:(base::OnceCallback<void(const std::string&)>)callback; + @end #endif // IOS_WEB_VIEW_INTERNAL_AUTOFILL_CWV_AUTOFILL_CLIENT_IOS_BRIDGE_H_
diff --git a/ios/web_view/internal/autofill/cwv_autofill_controller.mm b/ios/web_view/internal/autofill/cwv_autofill_controller.mm index de2c3bd7..b46ea20 100644 --- a/ios/web_view/internal/autofill/cwv_autofill_controller.mm +++ b/ios/web_view/internal/autofill/cwv_autofill_controller.mm
@@ -368,6 +368,10 @@ [_verifier didReceiveUnmaskVerificationResult:result]; } +- (void)loadRiskData:(base::OnceCallback<void(const std::string&)>)callback { + [_verifier loadRiskData:std::move(callback)]; +} + #pragma mark - AutofillDriverIOSBridge - (void)onFormDataFilled:(uint16_t)query_id
diff --git a/ios/web_view/internal/autofill/cwv_credit_card_verifier.mm b/ios/web_view/internal/autofill/cwv_credit_card_verifier.mm index ea3417f..c9ec2de6 100644 --- a/ios/web_view/internal/autofill/cwv_credit_card_verifier.mm +++ b/ios/web_view/internal/autofill/cwv_credit_card_verifier.mm
@@ -11,12 +11,39 @@ #include "components/autofill/core/browser/ui/card_unmask_prompt_controller_impl.h" #include "components/autofill/core/browser/ui/card_unmask_prompt_view.h" #import "ios/web_view/internal/autofill/cwv_credit_card_internal.h" +#import "ios/web_view/public/cwv_credit_card_verifier_data_source.h" +#import "ios/web_view/public/cwv_credit_card_verifier_delegate.h" #include "ui/base/resource/resource_bundle.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif +NSErrorDomain const CWVCreditCardVerifierErrorDomain = + @"org.chromium.chromewebview.CreditCardVerifierErrorDomain"; +NSString* const CWVCreditCardVerifierErrorMessageKey = @"error_message"; +NSString* const CWVCreditCardVerifierRetryAllowedKey = @"retry_allowed"; + +namespace { +// Converts an autofill::AutofillClient::PaymentsRpcResult to a +// CWVCreditCardVerificationError. +CWVCreditCardVerificationError CWVConvertPaymentsRPCResult( + autofill::AutofillClient::PaymentsRpcResult result) { + switch (result) { + case autofill::AutofillClient::NONE: + case autofill::AutofillClient::SUCCESS: + NOTREACHED(); + return CWVCreditCardVerificationErrorNone; + case autofill::AutofillClient::TRY_AGAIN_FAILURE: + return CWVCreditCardVerificationErrorTryAgainFailure; + case autofill::AutofillClient::PERMANENT_FAILURE: + return CWVCreditCardVerificationErrorPermanentFailure; + case autofill::AutofillClient::NETWORK_ERROR: + return CWVCreditCardVerificationErrorNetworkFailure; + } +} +} // namespace + @interface CWVCreditCardVerifier () // Used to receive |GotVerificationResult| from WebViewCardUnmaskPromptView. @@ -60,10 +87,10 @@ _unmaskingController; // Used to interface with |_unmaskingController|. std::unique_ptr<ios_web_view::WebViewCardUnmaskPromptView> _unmaskingView; - // Completion handler for verification results. This is provided by the - // client and copied internally to be invoked later from - // |didReceiveVerificationResultWithErrorMessage:retryAllowed:|. - void (^_completionHandler)(NSString* errorMessage, BOOL retryAllowed); + // Data source to provide risk data. + __weak id<CWVCreditCardVerifierDataSource> _dataSource; + // Delegate to receive callbacks. + __weak id<CWVCreditCardVerifierDelegate> _delegate; } @synthesize creditCard = _creditCard; @@ -131,16 +158,17 @@ } - (void)verifyWithCVC:(NSString*)CVC - expirationMonth:(NSString*)expirationMonth - expirationYear:(NSString*)expirationYear + expirationMonth:(nullable NSString*)expirationMonth + expirationYear:(nullable NSString*)expirationYear storeLocally:(BOOL)storeLocally - completionHandler: - (void (^)(NSString* errorMessage, BOOL retryAllowed))completionHandler { - DCHECK(!_completionHandler); + dataSource:(__weak id<CWVCreditCardVerifierDataSource>)dataSource + delegate: + (nullable __weak id<CWVCreditCardVerifierDelegate>)delegate { + _dataSource = dataSource; + _delegate = delegate; _unmaskingController->OnUnmaskResponse( base::SysNSStringToUTF16(CVC), base::SysNSStringToUTF16(expirationMonth), base::SysNSStringToUTF16(expirationYear), storeLocally); - _completionHandler = completionHandler; } - (BOOL)isCVCValid:(NSString*)CVC { @@ -156,9 +184,24 @@ - (void)didReceiveVerificationResultWithErrorMessage:(NSString*)errorMessage retryAllowed:(BOOL)retryAllowed { - DCHECK(_completionHandler); - _completionHandler(errorMessage, retryAllowed); - _completionHandler = nil; + if ([_delegate respondsToSelector:@selector + (creditCardVerifier:didFinishVerificationWithError:)]) { + NSError* error; + autofill::AutofillClient::PaymentsRpcResult result = + _unmaskingController->GetVerificationResult(); + if (errorMessage.length > 0 && result != autofill::AutofillClient::NONE && + result != autofill::AutofillClient::SUCCESS) { + NSDictionary* userInfo = @{ + CWVCreditCardVerifierErrorMessageKey : errorMessage, + CWVCreditCardVerifierRetryAllowedKey : @(retryAllowed), + }; + error = [NSError errorWithDomain:CWVCreditCardVerifierErrorDomain + code:CWVConvertPaymentsRPCResult(result) + userInfo:userInfo]; + } + + [_delegate creditCardVerifier:self didFinishVerificationWithError:error]; + } } #pragma mark - Internal Methods @@ -168,4 +211,13 @@ _unmaskingController->OnVerificationResult(result); } +- (void)loadRiskData:(base::OnceCallback<void(const std::string&)>)callback { + __block base::OnceCallback<void(const std::string&)> blockCallback = + std::move(callback); + [_dataSource creditCardVerifier:self + getRiskDataWithCompletionHandler:^(NSString* _Nonnull riskData) { + std::move(blockCallback).Run(base::SysNSStringToUTF8(riskData)); + }]; +} + @end
diff --git a/ios/web_view/internal/autofill/cwv_credit_card_verifier_internal.h b/ios/web_view/internal/autofill/cwv_credit_card_verifier_internal.h index ba8c707..76c242d 100644 --- a/ios/web_view/internal/autofill/cwv_credit_card_verifier_internal.h +++ b/ios/web_view/internal/autofill/cwv_credit_card_verifier_internal.h
@@ -38,6 +38,10 @@ - (void)didReceiveUnmaskVerificationResult: (autofill::AutofillClient::PaymentsRpcResult)result; +// Use to notify CWVCreditCardVerifier that it needs to obtain risk data for +// credit card verification and to pass it back in |callback|. +- (void)loadRiskData:(base::OnceCallback<void(const std::string&)>)callback; + @end NS_ASSUME_NONNULL_END
diff --git a/ios/web_view/internal/autofill/cwv_credit_card_verifier_unittest.mm b/ios/web_view/internal/autofill/cwv_credit_card_verifier_unittest.mm index 4dce241..a27b2e2 100644 --- a/ios/web_view/internal/autofill/cwv_credit_card_verifier_unittest.mm +++ b/ios/web_view/internal/autofill/cwv_credit_card_verifier_unittest.mm
@@ -9,6 +9,7 @@ #include "base/base_paths.h" #include "base/bind.h" +#include "base/callback.h" #include "base/memory/weak_ptr.h" #include "base/path_service.h" #include "base/run_loop.h" @@ -25,9 +26,12 @@ #include "ios/web/public/web_task_traits.h" #include "ios/web/public/web_thread.h" #import "ios/web_view/internal/autofill/cwv_credit_card_internal.h" +#import "ios/web_view/public/cwv_credit_card_verifier_data_source.h" +#import "ios/web_view/public/cwv_credit_card_verifier_delegate.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" #include "testing/platform_test.h" +#import "third_party/ocmock/OCMock/OCMock.h" #include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/resource/resource_bundle.h" @@ -171,24 +175,17 @@ // Tests CWVCreditCardVerifier's verification method. TEST_F(CWVCreditCardVerifierTest, VerifyCard) { - __block bool completion_handler_called = false; + id unused_data_source = + OCMProtocolMock(@protocol(CWVCreditCardVerifierDataSource)); NSString* cvc = @"123"; BOOL store_locally = YES; [credit_card_verifier_ - verifyWithCVC:cvc - expirationMonth:@"" // Expiration dates are ignored here because - expirationYear:@"" // |needsUpdateForExpirationDate| is NO. - storeLocally:store_locally - completionHandler:^(NSString* errorMessage, BOOL retryAllowed) { - EXPECT_FALSE(errorMessage.length > 0); - EXPECT_TRUE(retryAllowed); - completion_handler_called = true; - }]; - - EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^bool { - base::RunLoop().RunUntilIdle(); - return completion_handler_called; - })); + verifyWithCVC:cvc + expirationMonth:@"" // Expiration dates are ignored here because + expirationYear:@"" // |needsUpdateForExpirationDate| is NO. + storeLocally:store_locally + dataSource:unused_data_source + delegate:nil]; EXPECT_TRUE(credit_card_verifier_.lastStoreLocallyValue); const FakeCardUnmaskDelegate::UnmaskResponse& unmask_response_ = @@ -197,4 +194,66 @@ EXPECT_EQ(store_locally, unmask_response_.should_store_pan); } +// Tests CWVCreditCardVerifier properly invokes its delegate. +TEST_F(CWVCreditCardVerifierTest, DelegateCallbacks) { + id unused_data_source = + OCMProtocolMock(@protocol(CWVCreditCardVerifierDataSource)); + id delegate = OCMProtocolMock(@protocol(CWVCreditCardVerifierDelegate)); + [credit_card_verifier_ verifyWithCVC:@"123" + expirationMonth:@"" + expirationYear:@"" + storeLocally:NO + dataSource:unused_data_source + delegate:delegate]; + + [[delegate expect] + creditCardVerifier:credit_card_verifier_ + didFinishVerificationWithError:[OCMArg checkWithBlock:^BOOL( + NSError* error) { + return + [error.domain isEqualToString:CWVCreditCardVerifierErrorDomain] && + error.code == CWVCreditCardVerificationErrorTryAgainFailure && + error.userInfo[CWVCreditCardVerifierErrorMessageKey] != nil && + error.userInfo[CWVCreditCardVerifierRetryAllowedKey] && + [error.userInfo[CWVCreditCardVerifierRetryAllowedKey] boolValue]; + }]]; + [credit_card_verifier_ didReceiveUnmaskVerificationResult: + autofill::AutofillClient::TRY_AGAIN_FAILURE]; + [delegate verify]; +} + +// Tests CWVCreditCardVerifier properly invokes its data source. +TEST_F(CWVCreditCardVerifierTest, DataSourceCallbacks) { + id data_source = OCMProtocolMock(@protocol(CWVCreditCardVerifierDataSource)); + [credit_card_verifier_ verifyWithCVC:@"123" + expirationMonth:@"" + expirationYear:@"" + storeLocally:NO + dataSource:data_source + delegate:nil]; + + [[data_source expect] + creditCardVerifier:credit_card_verifier_ + getRiskDataWithCompletionHandler:[OCMArg checkWithBlock:^BOOL(id arg) { + void (^completionHandler)(NSString*) = arg; + completionHandler(@"dummy-risk-data"); + return YES; + }]]; + __block bool callback_called = false; + base::OnceCallback<void(const std::string&)> callback = base::BindOnce( + [](bool* callback_called, const std::string& risk_data) -> void { + *callback_called = true; + EXPECT_EQ("dummy-risk-data", risk_data); + }, + &callback_called); + [credit_card_verifier_ loadRiskData:std::move(callback)]; + + EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^bool { + base::RunLoop().RunUntilIdle(); + return callback_called; + })); + + [data_source verify]; +} + } // namespace ios_web_view
diff --git a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm index c5806e5a..ef11a0c 100644 --- a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm +++ b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm
@@ -139,7 +139,9 @@ const base::Closure& callback) {} void WebViewAutofillClientIOS::LoadRiskData( - base::OnceCallback<void(const std::string&)> callback) {} + base::OnceCallback<void(const std::string&)> callback) { + [bridge_ loadRiskData:std::move(callback)]; +} bool WebViewAutofillClientIOS::HasCreditCardScanFeature() { return false;
diff --git a/ios/web_view/public/cwv_credit_card_verifier.h b/ios/web_view/public/cwv_credit_card_verifier.h index 5445aed4..d3f47d45 100644 --- a/ios/web_view/public/cwv_credit_card_verifier.h +++ b/ios/web_view/public/cwv_credit_card_verifier.h
@@ -12,6 +12,31 @@ NS_ASSUME_NONNULL_BEGIN @class CWVCreditCard; +@protocol CWVCreditCardVerifierDataSource; +@protocol CWVCreditCardVerifierDelegate; + +// The error domain for credit card verification errors. +FOUNDATION_EXPORT CWV_EXPORT + NSErrorDomain const CWVCreditCardVerifierErrorDomain; +// The key for the error message value in the error's |userInfo| dictionary. +FOUNDATION_EXPORT CWV_EXPORT + NSString* const CWVCreditCardVerifierErrorMessageKey; +// The key for the retry allowed value in the error's |userInfo| dictionary. +FOUNDATION_EXPORT CWV_EXPORT + NSString* const CWVCreditCardVerifierRetryAllowedKey; + +// Possible error codes during credit card verification. +typedef NS_ENUM(NSInteger, CWVCreditCardVerificationError) { + // No errors. + CWVCreditCardVerificationErrorNone = 0, + // Request failed; try again. + CWVCreditCardVerificationErrorTryAgainFailure = -100, + // Request failed; don't try again. + CWVCreditCardVerificationErrorPermanentFailure = -200, + // Unable to connect to Payments servers. Prompt user to check internet + // connection. + CWVCreditCardVerificationErrorNetworkFailure = -300, +}; CWV_EXPORT // Helps with verifying credit cards for autofill, updating expired expiration @@ -53,22 +78,22 @@ // Attempts |creditCard| verification. // |CVC| Card verification code. e.g. 3 digit code on the back of Visa cards or // 4 digit code in the front of American Express cards. -// |month| 1 or 2 digit expiration month. e.g. 8 or 08 for August. Ignored if +// |month| 1 or 2 digit expiration month. e.g. 8 or 08 for August. Can be nil if // |needsUpdateForExpirationDate| is NO. -// |year| 2 or 4 digit expiration year. e.g. 19 or 2019. Ignored if +// |year| 2 or 4 digit expiration year. e.g. 19 or 2019. Can be nil if // |needsUpdateForExpirationDate| is NO. // |storeLocally| Whether or not to save |creditCard| locally. If YES, user will // not be asked again to verify this card. Ignored if |canSaveLocally| is NO. -// |completionHandler| Use to receive verification results. Must wait for -// handler to return before attempting another verification. -// |error| Contains the error message if unsuccessful. Empty if successful. -// |retryAllowed| YES if user may attempt verification again. +// |dataSource| will be asked to return risk data needed for verification. +// |delegate| will be passed the verification result. Must wait for |delegate| +// methods before attempting to verify again. - (void)verifyWithCVC:(NSString*)CVC - expirationMonth:(NSString*)expirationMonth - expirationYear:(NSString*)expirationYear + expirationMonth:(nullable NSString*)expirationMonth + expirationYear:(nullable NSString*)expirationYear storeLocally:(BOOL)storeLocally - completionHandler: - (void (^)(NSString* errorMessage, BOOL retryAllowed))completionHandler; + dataSource:(__weak id<CWVCreditCardVerifierDataSource>)dataSource + delegate: + (nullable __weak id<CWVCreditCardVerifierDelegate>)delegate; // Returns YES if |CVC| is all digits and matches |expectedCVCLength|. - (BOOL)isCVCValid:(NSString*)CVC;
diff --git a/ios/web_view/public/cwv_credit_card_verifier_data_source.h b/ios/web_view/public/cwv_credit_card_verifier_data_source.h new file mode 100644 index 0000000..ef4f5c58 --- /dev/null +++ b/ios/web_view/public/cwv_credit_card_verifier_data_source.h
@@ -0,0 +1,29 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_WEB_VIEW_PUBLIC_CWV_CREDIT_CARD_VERIFIER_DATA_SOURCE_H_ +#define IOS_WEB_VIEW_PUBLIC_CWV_CREDIT_CARD_VERIFIER_DATA_SOURCE_H_ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +@class CWVCreditCardVerifier; + +// Data source for CWVCreditCardVerifer. +@protocol CWVCreditCardVerifierDataSource<NSObject> + +// Called when CWVCreditCardVerifier needs risk data before it can continue with +// credit card verification. The client must obtain and return the risk data +// needed for 1st party integration with the internal payments API. +// See go/risk-eng.g3doc for more details. +- (void)creditCardVerifier:(CWVCreditCardVerifier*)creditCardVerifier + getRiskDataWithCompletionHandler: + (void (^)(NSString* riskData))completionHandler; + +@end + +NS_ASSUME_NONNULL_END + +#endif // IOS_WEB_VIEW_PUBLIC_CWV_CREDIT_CARD_VERIFIER_DATA_SOURCE_H_
diff --git a/ios/web_view/public/cwv_credit_card_verifier_delegate.h b/ios/web_view/public/cwv_credit_card_verifier_delegate.h new file mode 100644 index 0000000..edb71d3 --- /dev/null +++ b/ios/web_view/public/cwv_credit_card_verifier_delegate.h
@@ -0,0 +1,30 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_WEB_VIEW_PUBLIC_CWV_CREDIT_CARD_VERIFIER_DELEGATE_H_ +#define IOS_WEB_VIEW_PUBLIC_CWV_CREDIT_CARD_VERIFIER_DELEGATE_H_ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +@class CWVCreditCardVerifier; + +// Delegate of CWVCreditCardVerifier. +@protocol CWVCreditCardVerifierDelegate<NSObject> + +@optional + +// Called when CWVCreditCardVerifier could not verify the credit card. +// |error| nil if successful, non-nil if unsuccessful. User info will contain +// key CWVCreditCardVerifierErrorMessageKey indicating the reason and +// CWVCreditCardVerifierRetryAllowedKey indicating if user can try again. +- (void)creditCardVerifier:(CWVCreditCardVerifier*)creditCardVerifier + didFinishVerificationWithError:(nullable NSError*)error; + +@end + +NS_ASSUME_NONNULL_END + +#endif // IOS_WEB_VIEW_PUBLIC_CWV_CREDIT_CARD_VERIFIER_DELEGATE_H_
diff --git a/mojo/core/multiprocess_message_pipe_unittest.cc b/mojo/core/multiprocess_message_pipe_unittest.cc index b69af36..df3d5924 100644 --- a/mojo/core/multiprocess_message_pipe_unittest.cc +++ b/mojo/core/multiprocess_message_pipe_unittest.cc
@@ -1331,9 +1331,13 @@ , MultiprocessMessagePipeTestWithPeerSupport, testing::Values(test::MojoTestBase::LaunchType::CHILD, - test::MojoTestBase::LaunchType::PEER, + test::MojoTestBase::LaunchType::PEER +#if !defined(OS_FUCHSIA) + , test::MojoTestBase::LaunchType::NAMED_CHILD, - test::MojoTestBase::LaunchType::NAMED_PEER)); + test::MojoTestBase::LaunchType::NAMED_PEER +#endif // !defined(OS_FUCHSIA) + )); } // namespace } // namespace core } // namespace mojo
diff --git a/mojo/core/test/multiprocess_test_helper.cc b/mojo/core/test/multiprocess_test_helper.cc index 7181520..df7f4eb 100644 --- a/mojo/core/test/multiprocess_test_helper.cc +++ b/mojo/core/test/multiprocess_test_helper.cc
@@ -109,24 +109,29 @@ mojo::PlatformChannel channel; mojo::NamedPlatformChannel::ServerName server_name; base::LaunchOptions options; - if (launch_type == LaunchType::CHILD || launch_type == LaunchType::PEER) { - channel.PrepareToPassRemoteEndpoint(&options, &command_line); - } else if (launch_type == LaunchType::NAMED_CHILD || - launch_type == LaunchType::NAMED_PEER) { -#if defined(OS_FUCHSIA) - // TODO(fuchsia): Implement named channels. See crbug.com/754038. - NOTREACHED(); -#elif defined(OS_POSIX) - base::FilePath temp_dir; - CHECK(base::PathService::Get(base::DIR_TEMP, &temp_dir)); - server_name = - temp_dir.AppendASCII(base::NumberToString(base::RandUint64())).value(); + switch (launch_type) { + case LaunchType::CHILD: + case LaunchType::PEER: + channel.PrepareToPassRemoteEndpoint(&options, &command_line); + break; +#if !defined(OS_FUCHSIA) + case LaunchType::NAMED_CHILD: + case LaunchType::NAMED_PEER: { +#if defined(OS_POSIX) + base::FilePath temp_dir; + CHECK(base::PathService::Get(base::DIR_TEMP, &temp_dir)); + server_name = + temp_dir.AppendASCII(base::NumberToString(base::RandUint64())) + .value(); #elif defined(OS_WIN) - server_name = base::NumberToString16(base::RandUint64()); + server_name = base::NumberToString16(base::RandUint64()); #else #error "Platform not yet supported." #endif - command_line.AppendSwitchNative(kNamedPipeName, server_name); + command_line.AppendSwitchNative(kNamedPipeName, server_name); + break; + } +#endif // !defined(OS_FUCHSIA) } if (!switch_string.empty()) { @@ -146,35 +151,49 @@ // the pipe path can race with child's connection to the pipe. PlatformChannelEndpoint local_channel_endpoint; PlatformChannelServerEndpoint server_endpoint; - if (launch_type == LaunchType::CHILD || launch_type == LaunchType::PEER) { - local_channel_endpoint = channel.TakeLocalEndpoint(); - } else if (launch_type == LaunchType::NAMED_CHILD || - launch_type == LaunchType::NAMED_PEER) { - NamedPlatformChannel::Options options; - options.server_name = server_name; - NamedPlatformChannel named_channel(options); - server_endpoint = named_channel.TakeServerEndpoint(); - } + switch (launch_type) { + case LaunchType::CHILD: + case LaunchType::PEER: + local_channel_endpoint = channel.TakeLocalEndpoint(); + break; +#if !defined(OS_FUCHSIA) + case LaunchType::NAMED_CHILD: + case LaunchType::NAMED_PEER: { + NamedPlatformChannel::Options options; + options.server_name = server_name; + NamedPlatformChannel named_channel(options); + server_endpoint = named_channel.TakeServerEndpoint(); + break; + } +#endif // !defined(OS_FUCHSIA) + }; OutgoingInvitation child_invitation; ScopedMessagePipeHandle pipe; - if (launch_type == LaunchType::CHILD || - launch_type == LaunchType::NAMED_CHILD) { - pipe = child_invitation.AttachMessagePipe(kTestChildMessagePipeName); - command_line.AppendSwitch(kRunAsBrokerClient); - } else if (launch_type == LaunchType::PEER || - launch_type == LaunchType::NAMED_PEER) { - isolated_connection_ = std::make_unique<IsolatedConnection>(); - if (local_channel_endpoint.is_valid()) { - pipe = isolated_connection_->Connect(std::move(local_channel_endpoint)); - } else { -#if defined(OS_POSIX) || defined(OS_WIN) - DCHECK(server_endpoint.is_valid()); - pipe = isolated_connection_->Connect(std::move(server_endpoint)); -#else - NOTREACHED(); + switch (launch_type) { + case LaunchType::CHILD: +#if !defined(OS_FUCHSIA) + case LaunchType::NAMED_CHILD: #endif - } + pipe = child_invitation.AttachMessagePipe(kTestChildMessagePipeName); + command_line.AppendSwitch(kRunAsBrokerClient); + break; + case LaunchType::PEER: +#if !defined(OS_FUCHSIA) + case LaunchType::NAMED_PEER: +#endif + isolated_connection_ = std::make_unique<IsolatedConnection>(); + if (local_channel_endpoint.is_valid()) { + pipe = isolated_connection_->Connect(std::move(local_channel_endpoint)); + } else { +#if defined(OS_POSIX) || defined(OS_WIN) + DCHECK(server_endpoint.is_valid()); + pipe = isolated_connection_->Connect(std::move(server_endpoint)); +#else + NOTREACHED(); +#endif + } + break; } test_child_ = @@ -187,12 +206,15 @@ OutgoingInvitation::Send(std::move(child_invitation), test_child_.Handle(), std::move(local_channel_endpoint), mojo::ProcessErrorCallback()); - } else if (launch_type == LaunchType::NAMED_CHILD) { + } +#if !defined(OS_FUCHSIA) + else if (launch_type == LaunchType::NAMED_CHILD) { DCHECK(server_endpoint.is_valid()); OutgoingInvitation::Send(std::move(child_invitation), test_child_.Handle(), std::move(server_endpoint), mojo::ProcessErrorCallback()); } +#endif // !defined(OS_FUCHSIA) CHECK(test_child_.IsValid()); return pipe;
diff --git a/mojo/core/test/multiprocess_test_helper.h b/mojo/core/test/multiprocess_test_helper.h index e7be8355..becc74c6 100644 --- a/mojo/core/test/multiprocess_test_helper.h +++ b/mojo/core/test/multiprocess_test_helper.h
@@ -12,6 +12,7 @@ #include "base/process/process.h" #include "base/test/multiprocess_test.h" #include "base/test/test_timeouts.h" +#include "build/build_config.h" #include "mojo/public/cpp/system/message_pipe.h" #include "testing/multiprocess_func_list.h" @@ -33,6 +34,7 @@ // Launch the child process as an unrelated peer process in the mojo system. PEER, +#if !defined(OS_FUCHSIA) // Launch the child process as a child in the mojo system, using a named // pipe. NAMED_CHILD, @@ -40,6 +42,7 @@ // Launch the child process as an unrelated peer process in the mojo // system, using a named pipe. NAMED_PEER, +#endif // !defined(OS_FUCHSIA) }; MultiprocessTestHelper();
diff --git a/mojo/public/cpp/bindings/BUILD.gn b/mojo/public/cpp/bindings/BUILD.gn index 2715283..86d57ca 100644 --- a/mojo/public/cpp/bindings/BUILD.gn +++ b/mojo/public/cpp/bindings/BUILD.gn
@@ -208,6 +208,7 @@ # TODO(yzshen): crbug.com/617718 Consider moving this into blink. source_set("wtf_support") { sources = [ + "array_traits_web_vector.h", "array_traits_wtf_vector.h", "lib/string_traits_wtf.cc", "lib/wtf_clone_equals_util.h", @@ -219,6 +220,7 @@ public_deps = [ ":bindings", + "//third_party/blink/public:blink_headers", "//third_party/blink/renderer/platform:platform_export", "//third_party/blink/renderer/platform/wtf", ]
diff --git a/mojo/public/cpp/bindings/DEPS b/mojo/public/cpp/bindings/DEPS index 4633930..4a2a9b7 100644 --- a/mojo/public/cpp/bindings/DEPS +++ b/mojo/public/cpp/bindings/DEPS
@@ -1,3 +1,4 @@ include_rules = [ + "+third_party/blink/public/platform/web_vector.h", "+third_party/blink/renderer/platform/wtf", ]
diff --git a/mojo/public/cpp/bindings/array_traits_web_vector.h b/mojo/public/cpp/bindings/array_traits_web_vector.h new file mode 100644 index 0000000..9e17892 --- /dev/null +++ b/mojo/public/cpp/bindings/array_traits_web_vector.h
@@ -0,0 +1,56 @@ +// Copyright 2018 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 MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_WEB_VECTOR_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_WEB_VECTOR_H_ + +#include "mojo/public/cpp/bindings/array_traits.h" +#include "third_party/blink/public/platform/web_vector.h" + +namespace mojo { + +template <typename U> +struct ArrayTraits<blink::WebVector<U>> { + using Element = U; + + static bool IsNull(const blink::WebVector<U>& input) { + // blink::WebVector<> is always converted to non-null mojom array. + return false; + } + + static void SetToNull(blink::WebVector<U>* output) { + // blink::WebVector<> doesn't support null state. Set it to empty instead. + output->Clear(); + } + + static size_t GetSize(const blink::WebVector<U>& input) { + return input.size(); + } + + static U* GetData(blink::WebVector<U>& input) { return input.Data(); } + + static const U* GetData(const blink::WebVector<U>& input) { + return input.Data(); + } + + static U& GetAt(blink::WebVector<U>& input, size_t index) { + return input[index]; + } + + static const U& GetAt(const blink::WebVector<U>& input, size_t index) { + return input[index]; + } + + static bool Resize(blink::WebVector<U>& input, size_t size) { + // WebVector DCHECKs if the new size is larger than capacity(). Call + // reserve() first to be safe. + input.reserve(size); + input.resize(size); + return true; + } +}; + +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_WEB_VECTOR_H_
diff --git a/net/BUILD.gn b/net/BUILD.gn index d4d9e35..3cad52a 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1534,8 +1534,6 @@ "third_party/quic/platform/api/quic_string.h", "third_party/quic/platform/api/quic_string_piece.h", "third_party/quic/platform/api/quic_text_utils.h", - "third_party/quic/platform/api/quic_url.cc", - "third_party/quic/platform/api/quic_url.h", "third_party/quic/platform/impl/quic_aligned_impl.h", "third_party/quic/platform/impl/quic_arraysize_impl.h", "third_party/quic/platform/impl/quic_bug_tracker_impl.h", @@ -1579,8 +1577,6 @@ "third_party/quic/platform/impl/quic_string_impl.h", "third_party/quic/platform/impl/quic_string_piece_impl.h", "third_party/quic/platform/impl/quic_text_utils_impl.h", - "third_party/quic/platform/impl/quic_url_impl.cc", - "third_party/quic/platform/impl/quic_url_impl.h", "third_party/quic/quartc/quartc_factory.cc", "third_party/quic/quartc/quartc_factory.h", "third_party/quic/quartc/quartc_packet_writer.cc", @@ -3259,6 +3255,8 @@ "third_party/quic/tools/quic_simple_server_stream.h", "third_party/quic/tools/quic_spdy_client_base.cc", "third_party/quic/tools/quic_spdy_client_base.h", + "third_party/quic/tools/quic_url.cc", + "third_party/quic/tools/quic_url.h", "tools/quic/quic_client_message_loop_network_helper.cc", "tools/quic/quic_client_message_loop_network_helper.h", "tools/quic/quic_http_proxy_backend.cc", @@ -5146,7 +5144,6 @@ "third_party/quic/platform/api/quic_singleton_test.cc", "third_party/quic/platform/api/quic_str_cat_test.cc", "third_party/quic/platform/api/quic_text_utils_test.cc", - "third_party/quic/platform/api/quic_url_test.cc", "third_party/quic/platform/impl/quic_chromium_clock_test.cc", "third_party/quic/platform/impl/quic_uint128_impl_unittest.cc", "third_party/quic/quartc/quartc_session_test.cc", @@ -5329,6 +5326,7 @@ "third_party/quic/tools/quic_server_test.cc", "third_party/quic/tools/quic_simple_server_session_test.cc", "third_party/quic/tools/quic_simple_server_stream_test.cc", + "third_party/quic/tools/quic_url_test.cc", "tools/quic/quic_http_proxy_backend_stream_test.cc", "tools/quic/quic_http_proxy_backend_test.cc", "tools/quic/quic_simple_server_session_helper_test.cc",
diff --git a/net/http/http_util.cc b/net/http/http_util.cc index d8cf8e5..0097c9b 100644 --- a/net/http/http_util.cc +++ b/net/http/http_util.cc
@@ -13,6 +13,7 @@ #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" +#include "base/strings/string_split.h" #include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -34,6 +35,46 @@ --(*end); } +// Helper class that builds the list of languages for the Accept-Language +// headers. +// The output is a comma-separated list of languages as string. +// Duplicates are removed. +class AcceptLanguageBuilder { + public: + // Adds a language to the string. + // Duplicates are ignored. + void AddLanguageCode(const std::string& language) { + // No Q score supported, only supports ASCII. + DCHECK_EQ(std::string::npos, language.find_first_of("; ")); + DCHECK(base::IsStringASCII(language)); + if (seen_.find(language) == seen_.end()) { + if (str_.empty()) { + base::StringAppendF(&str_, "%s", language.c_str()); + } else { + base::StringAppendF(&str_, ",%s", language.c_str()); + } + seen_.insert(language); + } + } + + // Returns the string constructed up to this point. + std::string GetString() const { return str_; } + + private: + // The string that contains the list of languages, comma-separated. + std::string str_; + // Set the remove duplicates. + std::unordered_set<std::string> seen_; +}; + +// Extract the base language code from a language code. +// If there is no '-' in the code, the original code is returned. +std::string GetBaseLanguageCode(const std::string& language_code) { + const std::vector<std::string> tokens = base::SplitString( + language_code, "-", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + return tokens.empty() ? "" : tokens[0]; +} + } // namespace // HttpUtil ------------------------------------------------------------------- @@ -773,6 +814,34 @@ return disassembled_headers; } +std::string HttpUtil::ExpandLanguageList(const std::string& language_prefs) { + const std::vector<std::string> languages = base::SplitString( + language_prefs, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + + if (languages.empty()) + return ""; + + AcceptLanguageBuilder builder; + + const int size = languages.size(); + for (int i = 0; i < size; ++i) { + const std::string& language = languages[i]; + builder.AddLanguageCode(language); + + // Extract the base language + const std::string& base_language = GetBaseLanguageCode(language); + + // Look ahead and add the base language if the next language is not part + // of the same family. + const int j = i + 1; + if (j >= size || GetBaseLanguageCode(languages[j]) != base_language) { + builder.AddLanguageCode(base_language); + } + } + + return builder.GetString(); +} + // TODO(jungshik): This function assumes that the input is a comma separated // list without any whitespace. As long as it comes from the preference and // a user does not manually edit the preference file, it's the case. Still,
diff --git a/net/http/http_util.h b/net/http/http_util.h index 0bcb45fa..b4dd8ef0 100644 --- a/net/http/http_util.h +++ b/net/http/http_util.h
@@ -204,6 +204,14 @@ // consists of status line and then one line for each header. static std::string ConvertHeadersBackToHTTPResponse(const std::string& str); + // Given a comma separated ordered list of language codes, return an expanded + // list by adding the base language from language-region pair if it doesn't + // already exist. This increases the chances of language matching in many + // cases as explained at this w3c doc: + // https://www.w3.org/International/questions/qa-lang-priorities#langtagdetail + // Note that we do not support Q values (e.g. ;q=0.9) in |language_prefs|. + static std::string ExpandLanguageList(const std::string& language_prefs); + // Given a comma separated ordered list of language codes, return // the list with a qvalue appended to each language. // The way qvalues are assigned is rather simple. The qvalue
diff --git a/net/http/http_util_unittest.cc b/net/http/http_util_unittest.cc index cce5d34..d0b59ca 100644 --- a/net/http/http_util_unittest.cc +++ b/net/http/http_util_unittest.cc
@@ -1570,4 +1570,28 @@ } } +// Test the expansion of the Language List. +TEST(HttpUtilTest, ExpandLanguageList) { + EXPECT_EQ("", HttpUtil::ExpandLanguageList("")); + EXPECT_EQ("en-US,en", HttpUtil::ExpandLanguageList("en-US")); + EXPECT_EQ("fr", HttpUtil::ExpandLanguageList("fr")); + + // The base language is added after all regional codes... + EXPECT_EQ("en-US,en-CA,en", HttpUtil::ExpandLanguageList("en-US,en-CA")); + + // ... but before other language families. + EXPECT_EQ("en-US,en-CA,en,fr", + HttpUtil::ExpandLanguageList("en-US,en-CA,fr")); + EXPECT_EQ("en-US,en-CA,en,fr,en-AU", + HttpUtil::ExpandLanguageList("en-US,en-CA,fr,en-AU")); + EXPECT_EQ("en-US,en-CA,en,fr-CA,fr", + HttpUtil::ExpandLanguageList("en-US,en-CA,fr-CA")); + + // Add a base language even if it's already in the list. + EXPECT_EQ("en-US,en,fr-CA,fr,it,es-AR,es,it-IT", + HttpUtil::ExpandLanguageList("en-US,fr-CA,it,fr,es-AR,it-IT")); + // Trims a whitespace. + EXPECT_EQ("en-US,en,fr", HttpUtil::ExpandLanguageList("en-US, fr")); +} + } // namespace net
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc index 16d1bef..e32c6f4d 100644 --- a/net/nqe/network_quality_estimator.cc +++ b/net/nqe/network_quality_estimator.cc
@@ -239,7 +239,6 @@ transport_rtt_observation_count_last_ect_computation_(0), new_rtt_observations_since_last_ect_computation_(0), new_throughput_observations_since_last_ect_computation_(0), - increase_in_transport_rtt_updater_posted_(false), effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), cached_estimate_applied_(false), net_log_(NetLogWithSource::Make( @@ -929,120 +928,6 @@ bandwidth_delay_product_kbits_.value()); } -void NetworkQualityEstimator::IncreaseInTransportRTTUpdater() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - increase_in_transport_rtt_ = ComputeIncreaseInTransportRTT(); - - // Stop the timer if there was no recent data and |increase_in_transport_rtt_| - // could not be computed. This is fine because |increase_in_transport_rtt| can - // only be computed if there is recent transport RTT data, and the timer is - // restarted when there is a new observation. - if (!increase_in_transport_rtt_) { - increase_in_transport_rtt_updater_posted_ = false; - return; - } - - increase_in_transport_rtt_updater_posted_ = true; - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::Bind(&NetworkQualityEstimator::IncreaseInTransportRTTUpdater, - weak_ptr_factory_.GetWeakPtr()), - params_->increase_in_transport_rtt_logging_interval()); -} - -base::Optional<int32_t> NetworkQualityEstimator::ComputeIncreaseInTransportRTT() - const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - base::TimeTicks now = tick_clock_->NowTicks(); - - // The time after which the observations are considered to be recent enough to - // be a good proxy for the current level of congestion. - base::TimeTicks recent_start_time = now - params_->recent_time_threshold(); - - // Get the median transport RTT observed over the last 5 seconds for each - // remote host. This is an estimate of the current RTT which will be compared - // to the baseline obtained from historical data to detect an increase in RTT. - std::map<nqe::internal::IPHash, int32_t> recent_median_rtts; - std::map<nqe::internal::IPHash, size_t> recent_observation_counts; - rtt_ms_observations_[nqe::internal::OBSERVATION_CATEGORY_TRANSPORT] - .GetPercentileForEachHostWithCounts(recent_start_time, 50, base::nullopt, - &recent_median_rtts, - &recent_observation_counts); - - if (recent_median_rtts.empty()) - return base::nullopt; - - // The time after which the observations are used to calculate the baseline. - // This is needed because the general network characteristics could have - // changed over time. - base::TimeTicks history_start_time = - now - params_->historical_time_threshold(); - - // Create a set of the remote hosts seen in the recent observations so that - // the data can be filtered while calculating the percentiles. - std::set<nqe::internal::IPHash> recent_hosts_set; - for (const auto& recent_median_rtts_for_host : recent_median_rtts) - recent_hosts_set.insert(recent_median_rtts_for_host.first); - - // Get the minimum transport RTT observed over 1 minute for each remote host. - // This is an estimate of the true RTT which will be used as a baseline value - // to detect an increase in RTT. The minimum value is used here because the - // observed values cannot be lower than the true RTT. The median is used for - // the recent data to reduce noise in the calculation. - std::map<nqe::internal::IPHash, int32_t> historical_min_rtts; - std::map<nqe::internal::IPHash, size_t> historical_observation_counts; - rtt_ms_observations_[nqe::internal::OBSERVATION_CATEGORY_TRANSPORT] - .GetPercentileForEachHostWithCounts( - history_start_time, 0, recent_hosts_set, &historical_min_rtts, - &historical_observation_counts); - - // Calculate the total observation counts for the hosts common to the recent - // data and the historical data. - size_t total_historical_count = 0; - size_t total_recent_count = 0; - for (const auto& recent_median_rtts_for_host : recent_median_rtts) { - nqe::internal::IPHash host = recent_median_rtts_for_host.first; - total_historical_count += historical_observation_counts[host]; - total_recent_count += recent_observation_counts[host]; - } - - // Compute the increases in transport RTT for each remote host. Also compute - // the weight for each remote host based on the number of observations. - double total_weight = 0.0; - std::vector<nqe::internal::WeightedObservation> weighted_rtts; - for (auto& host : recent_hosts_set) { - // The relative weight signifies the amount of confidence in the data. The - // weight is higher if there were more observations. A regularization term - // of |1 / recent_hosts_set.size()| is added so that if one particular - // remote host has a lot of observations, the results do not get skewed. - double weight = - 1.0 / recent_hosts_set.size() + - std::min(static_cast<double>(recent_observation_counts[host]) / - total_recent_count, - static_cast<double>(historical_observation_counts[host]) / - total_historical_count); - weighted_rtts.push_back(nqe::internal::WeightedObservation( - recent_median_rtts[host] - historical_min_rtts[host], weight)); - total_weight += weight; - } - - // Sort the increases in RTT for percentile computation. - std::sort(weighted_rtts.begin(), weighted_rtts.end()); - - // Calculate the weighted 50th percentile increase in transport RTT. - double desired_weight = 0.5 * total_weight; - for (nqe::internal::WeightedObservation wo : weighted_rtts) { - desired_weight -= wo.weight; - if (desired_weight <= 0) - return wo.value; - } - - // Calculation will reach here when the 50th percentile is the last value. - return weighted_rtts.back().value; -} - void NetworkQualityEstimator::ComputeEffectiveConnectionType() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -1530,11 +1415,6 @@ current_network_id_.signal_strength, ProtocolSourceToObservationSource(protocol), host); AddAndNotifyObserversOfRTT(observation); - - // Post a task to compute and update the increase in RTT if not already - // posted. - if (!increase_in_transport_rtt_updater_posted_) - IncreaseInTransportRTTUpdater(); } void NetworkQualityEstimator::AddAndNotifyObserversOfRTT(
diff --git a/net/nqe/network_quality_estimator.h b/net/nqe/network_quality_estimator.h index 626f25c0..a3dbd14 100644 --- a/net/nqe/network_quality_estimator.h +++ b/net/nqe/network_quality_estimator.h
@@ -372,10 +372,6 @@ // |observed_http_rtt| with the expected HTTP and transport RTT. bool IsHangingRequest(base::TimeDelta observed_http_rtt) const; - base::Optional<int32_t> ComputeIncreaseInTransportRTTForTests() { - return ComputeIncreaseInTransportRTT(); - } - // Returns the current network signal strength by querying the platform APIs. // Set to INT32_MIN when the value is unavailable. Otherwise, must be between // 0 and 4 (both inclusive). This may take into account many different radio @@ -422,11 +418,6 @@ ForceEffectiveConnectionTypeThroughFieldTrial); FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestBDPComputation); FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, - TestComputeIncreaseInTransportRTTFullHostsOverlap); - FRIEND_TEST_ALL_PREFIXES( - NetworkQualityEstimatorTest, - TestComputeIncreaseInTransportRTTPartialHostsOverlap); - FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ObservationDiscardedIfCachedEstimateAvailable); FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestRttThroughputObservers); @@ -528,17 +519,6 @@ // |GetBandwidthDelayProductKbits|. void ComputeBandwidthDelayProduct(); - // Computes the current increase in transport RTT in milliseconds over the - // baseline transport RTT due to congestion. This value can be interpreted as - // the additional delay caused due to an increase in queue length in the last - // mile. The baseline is computed using the transport RTT observations in the - // past 60 seconds. The current RTT is computed using the observations in the - // past 5 seconds. Returns an empty optional when there was no recent data. - base::Optional<int32_t> ComputeIncreaseInTransportRTT() const; - - // Periodically updates |increase_in_transport_rtt_| by posting delayed tasks. - void IncreaseInTransportRTTUpdater(); - // Gathers metrics for the next connection type. Called when there is a change // in the connection type. void GatherEstimatesForNextConnectionType(); @@ -648,12 +628,6 @@ // Current estimate of the bandwidth delay product (BDP) in kilobits. base::Optional<int32_t> bandwidth_delay_product_kbits_; - // Current estimate of the increase in the transport RTT due to congestion. - base::Optional<int32_t> increase_in_transport_rtt_; - - // This is true if there is a task posted for |IncreaseInTransportRTTUpdater|. - bool increase_in_transport_rtt_updater_posted_; - // Current effective connection type. It is updated on connection change // events. It is also updated every time there is network traffic (provided // the last computation was more than
diff --git a/net/nqe/network_quality_estimator_unittest.cc b/net/nqe/network_quality_estimator_unittest.cc index 65ad922f..1bb16ee 100644 --- a/net/nqe/network_quality_estimator_unittest.cc +++ b/net/nqe/network_quality_estimator_unittest.cc
@@ -2716,87 +2716,6 @@ (int32_t)(std::pow(2, 2) * std::pow(3, 8) / 1000)); } -TEST_F(NetworkQualityEstimatorTest, - TestComputeIncreaseInTransportRTTFullHostsOverlap) { - base::SimpleTestTickClock tick_clock; - tick_clock.Advance(base::TimeDelta::FromMinutes(1)); - - std::map<std::string, std::string> variation_params; - variation_params["add_default_platform_observations"] = "false"; - TestNetworkQualityEstimator estimator(variation_params); - estimator.SetTickClockForTesting(&tick_clock); - - base::TimeTicks now = tick_clock.NowTicks(); - base::TimeTicks recent = now - base::TimeDelta::FromMilliseconds(2500); - base::TimeTicks historical = now - base::TimeDelta::FromSeconds(20); - - // Add historical observations. The 0 percentile for |host| is |10 * host| - // ms. - for (int host = 1; host <= 3; ++host) { - for (int rtt = 10 * host; rtt <= 10 * host + 20; ++rtt) { - estimator - .rtt_ms_observations_[nqe::internal::OBSERVATION_CATEGORY_TRANSPORT] - .AddObservation(NetworkQualityEstimator::Observation( - rtt, historical, INT32_MIN, - NETWORK_QUALITY_OBSERVATION_SOURCE_TCP, - static_cast<uint64_t>(host))); - } - } - - // Add recent observations. The 50 percentile for |host| is |10 * host + 10| - // ms. The difference between them is expected to be 10 ms. - for (int host = 1; host <= 3; ++host) { - for (int rtt = 10 * host + 5; rtt <= 10 * host + 15; ++rtt) { - estimator - .rtt_ms_observations_[nqe::internal::OBSERVATION_CATEGORY_TRANSPORT] - .AddObservation(NetworkQualityEstimator::Observation( - rtt, recent, INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_TCP, - static_cast<uint64_t>(host))); - } - } - - EXPECT_EQ(10, estimator.ComputeIncreaseInTransportRTTForTests().value_or(0)); -} - -TEST_F(NetworkQualityEstimatorTest, - TestComputeIncreaseInTransportRTTPartialHostsOverlap) { - base::SimpleTestTickClock tick_clock; - tick_clock.Advance(base::TimeDelta::FromMinutes(1)); - - std::map<std::string, std::string> variation_params; - variation_params["add_default_platform_observations"] = "false"; - TestNetworkQualityEstimator estimator(variation_params); - estimator.SetTickClockForTesting(&tick_clock); - - base::TimeTicks now = tick_clock.NowTicks(); - base::TimeTicks recent = now - base::TimeDelta::FromMilliseconds(2500); - base::TimeTicks historical = now - base::TimeDelta::FromSeconds(20); - - // Add historical observations for hosts 1 and 2 with minimum RTT as - // |10 * host|. - for (int host = 1; host <= 2; ++host) { - for (int rtt = 10 * host; rtt <= 10 * host + 20; ++rtt) { - estimator.AddAndNotifyObserversOfRTT(NetworkQualityEstimator::Observation( - rtt, historical, INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_TCP, - static_cast<uint64_t>(host))); - } - } - - // Add recent observations, with median RTT as |10 + host| over the - // historical minimum for hosts 2 and 3. - for (int host = 2; host <= 3; ++host) { - for (int rtt = 11 * host + 5; rtt <= 11 * host + 15; ++rtt) { - estimator.AddAndNotifyObserversOfRTT(NetworkQualityEstimator::Observation( - rtt, recent, INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_TCP, - static_cast<uint64_t>(host))); - } - } - - // Only host 2 should have contributed to the calculation. Hence, the median - // should be |10 + 2 = 12|. - EXPECT_EQ(12, estimator.ComputeIncreaseInTransportRTTForTests().value_or(0)); -} - // Verifies that when the cached network qualities from the prefs are available, // then estimates from the platform or the external estimate provider are not // used.
diff --git a/net/nqe/observation_buffer.cc b/net/nqe/observation_buffer.cc index 4fa1687d..8332ba3 100644 --- a/net/nqe/observation_buffer.cc +++ b/net/nqe/observation_buffer.cc
@@ -112,62 +112,6 @@ return weighted_observations.at(weighted_observations.size() - 1).value; } -void ObservationBuffer::GetPercentileForEachHostWithCounts( - base::TimeTicks begin_timestamp, - int percentile, - const base::Optional<std::set<IPHash>>& host_filter, - std::map<IPHash, int32_t>* host_keyed_percentiles, - std::map<IPHash, size_t>* host_keyed_counts) const { - DCHECK_GE(Capacity(), Size()); - DCHECK_LE(0, percentile); - DCHECK_GE(100, percentile); - - host_keyed_percentiles->clear(); - host_keyed_counts->clear(); - - // Filter the observations based on timestamp, and the - // presence of a valid host tag. Split the observations into a map keyed by - // the remote host to make it easy to calculate percentiles for each host. - std::map<IPHash, std::vector<int32_t>> host_keyed_observations; - for (const auto& observation : observations_) { - // Look at only those observations which have a |host|. - if (!observation.host()) - continue; - - IPHash host = observation.host().value(); - if (host_filter && (host_filter->find(host) == host_filter->end())) - continue; - - // Filter the observations recorded before |begin_timestamp|. - if (observation.timestamp() < begin_timestamp) - continue; - - // Skip 0 values of RTT. - if (observation.value() < 1) - continue; - - // Create the map entry if it did not already exist. Does nothing if - // |host| was seen before. - host_keyed_observations.emplace(host, std::vector<int32_t>()); - host_keyed_observations[host].push_back(observation.value()); - } - - if (host_keyed_observations.empty()) - return; - - // Calculate the percentile values for each host. - for (auto& host_observations : host_keyed_observations) { - IPHash host = host_observations.first; - auto& observations = host_observations.second; - std::sort(observations.begin(), observations.end()); - size_t count = observations.size(); - DCHECK_GT(count, 0u); - (*host_keyed_counts)[host] = count; - int percentile_index = ((count - 1) * percentile) / 100; - (*host_keyed_percentiles)[host] = observations[percentile_index]; - } -} - void ObservationBuffer::RemoveObservationsWithSource( bool deleted_observation_sources[NETWORK_QUALITY_OBSERVATION_SOURCE_MAX]) { base::EraseIf(observations_,
diff --git a/net/nqe/observation_buffer.h b/net/nqe/observation_buffer.h index 1527360..d3526581 100644 --- a/net/nqe/observation_buffer.h +++ b/net/nqe/observation_buffer.h
@@ -83,19 +83,6 @@ tick_clock_ = tick_clock; } - // Computes percentiles separately for each host. Observations without - // a host tag are skipped. Only data from the hosts present in |host_filter| - // are considered. Observations before |begin_timestamp| are skipped. The - // percentile value for each host is returned in |host_keyed_percentiles|. The - // number of valid observations for each host used for the computation is - // returned in |host_keyed_counts|. - void GetPercentileForEachHostWithCounts( - base::TimeTicks begin_timestamp, - int percentile, - const base::Optional<std::set<IPHash>>& host_filter, - std::map<IPHash, int32_t>* host_keyed_percentiles, - std::map<IPHash, size_t>* host_keyed_counts) const; - // Removes all observations from the buffer whose corresponding entry in // |deleted_observation_sources| is set to true. For example, if index 1 and // 3 in |deleted_observation_sources| are set to true, then all observations
diff --git a/net/nqe/observation_buffer_unittest.cc b/net/nqe/observation_buffer_unittest.cc index 8e5d4e1..f5d946f 100644 --- a/net/nqe/observation_buffer_unittest.cc +++ b/net/nqe/observation_buffer_unittest.cc
@@ -370,174 +370,6 @@ } } -// Test that time filtering works and the remote hosts are split correctly. -TEST(NetworkQualityObservationBufferTest, - RestGetPercentileForEachRemoteHostSinceTimeStamp) { - std::map<std::string, std::string> variation_params; - NetworkQualityEstimatorParams params(variation_params); - base::SimpleTestTickClock tick_clock; - tick_clock.Advance(base::TimeDelta::FromMinutes(1)); - const uint64_t new_host = 0x101010UL; - const int32_t new_host_observation = 1000; - const size_t new_host_num_obs = 10; - const uint64_t old_host = 0x202020UL; - const int32_t old_host_observation = 2000; - const size_t old_host_num_obs = 20; - ObservationBuffer buffer(¶ms, &tick_clock, 0.5, 1.0); - base::TimeTicks now = tick_clock.NowTicks(); - for (unsigned int i = 0; i < old_host_num_obs; ++i) { - buffer.AddObservation(Observation( - old_host_observation, now - base::TimeDelta::FromSeconds(100), - INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP, old_host)); - } - - for (unsigned int i = 0; i < new_host_num_obs; ++i) { - buffer.AddObservation(Observation(new_host_observation, now, INT32_MIN, - NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP, - new_host)); - } - - std::map<uint64_t, int32_t> host_keyed_percentiles; - std::map<uint64_t, size_t> host_keyed_counts; - buffer.GetPercentileForEachHostWithCounts( - now - base::TimeDelta::FromSeconds(50), 50, base::nullopt, - &host_keyed_percentiles, &host_keyed_counts); - EXPECT_EQ(1u, host_keyed_percentiles.size()); - EXPECT_EQ(1u, host_keyed_counts.size()); - EXPECT_EQ(new_host_observation, host_keyed_percentiles[new_host]); - EXPECT_EQ(new_host_num_obs, host_keyed_counts[new_host]); - - host_keyed_percentiles.clear(); - host_keyed_counts.clear(); - - buffer.GetPercentileForEachHostWithCounts( - now - base::TimeDelta::FromSeconds(150), 50, base::nullopt, - &host_keyed_percentiles, &host_keyed_counts); - EXPECT_EQ(2u, host_keyed_percentiles.size()); - EXPECT_EQ(2u, host_keyed_counts.size()); - EXPECT_EQ(new_host_observation, host_keyed_percentiles[new_host]); - EXPECT_EQ(new_host_num_obs, host_keyed_counts[new_host]); - EXPECT_EQ(old_host_observation, host_keyed_percentiles[old_host]); - EXPECT_EQ(old_host_num_obs, host_keyed_counts[old_host]); -} - -// Test that the result is split correctly for multiple remote hosts and that -// the count for each host is correct. -TEST(NetworkQualityObservationBufferTest, - RestGetPercentileForEachRemoteHostCounts) { - std::map<std::string, std::string> variation_params; - NetworkQualityEstimatorParams params(variation_params); - base::SimpleTestTickClock tick_clock; - tick_clock.Advance(base::TimeDelta::FromMinutes(1)); - ObservationBuffer buffer(¶ms, &tick_clock, 0.5, 1.0); - base::TimeTicks now = tick_clock.NowTicks(); - const size_t num_remote_hosts = 5; - - // Add |2*i| observations having value |4*i| for host |i|. - for (unsigned int host_index = 1; host_index <= num_remote_hosts; - ++host_index) { - for (unsigned int count = 1; count <= 2 * host_index; ++count) { - buffer.AddObservation(Observation(4 * host_index, now, INT32_MIN, - NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP, - static_cast<uint64_t>(host_index))); - } - } - - std::map<uint64_t, int32_t> host_keyed_percentiles; - std::map<uint64_t, size_t> host_keyed_counts; - buffer.GetPercentileForEachHostWithCounts( - base::TimeTicks(), 50, base::nullopt, &host_keyed_percentiles, - &host_keyed_counts); - EXPECT_EQ(num_remote_hosts, host_keyed_percentiles.size()); - EXPECT_EQ(num_remote_hosts, host_keyed_counts.size()); - - for (unsigned int host_index = 1; host_index <= num_remote_hosts; - ++host_index) { - EXPECT_EQ(2u * host_index, - host_keyed_counts[static_cast<uint64_t>(host_index)]); - EXPECT_EQ(static_cast<int32_t>(4 * host_index), - host_keyed_percentiles[static_cast<uint64_t>(host_index)]); - } -} - -// Test that the percentiles are computed correctly for different remote hosts. -TEST(NetworkQualityObservationBufferTest, - RestGetPercentileForEachRemoteHostComputation) { - std::map<std::string, std::string> variation_params; - NetworkQualityEstimatorParams params(variation_params); - base::SimpleTestTickClock tick_clock; - tick_clock.Advance(base::TimeDelta::FromMinutes(1)); - ObservationBuffer buffer(¶ms, &tick_clock, 0.5, 1.0); - base::TimeTicks now = tick_clock.NowTicks(); - const size_t num_hosts = 3; - - // For three different remote hosts, add observations such that the 50 - // percentiles are different. - for (unsigned int host_index = 1; host_index <= num_hosts; host_index++) { - // Add |20 * host_index + 1| observations for host |host_index|. - for (unsigned int observation_value = 90 * host_index; - observation_value <= 110 * host_index; observation_value++) { - buffer.AddObservation(Observation(observation_value, now, INT32_MIN, - NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP, - static_cast<uint64_t>(host_index))); - } - } - std::map<uint64_t, int32_t> host_keyed_percentiles; - std::map<uint64_t, size_t> host_keyed_counts; - - // Test the computation of the median. - buffer.GetPercentileForEachHostWithCounts( - base::TimeTicks(), 50, base::nullopt, &host_keyed_percentiles, - &host_keyed_counts); - - EXPECT_EQ(num_hosts, host_keyed_percentiles.size()); - EXPECT_EQ(num_hosts, host_keyed_counts.size()); - - // The median must be equal to |100 * i| and the count must be equal to - // |20 * i + 1| for host |i|. - for (unsigned int host_index = 1; host_index <= num_hosts; host_index++) { - EXPECT_EQ(100u * host_index, - static_cast<uint32_t>( - host_keyed_percentiles[static_cast<uint64_t>(host_index)])); - EXPECT_EQ(static_cast<size_t>(20 * host_index + 1), - host_keyed_counts[static_cast<uint64_t>(host_index)]); - } - - // Test the computation of 0th percentile. - buffer.GetPercentileForEachHostWithCounts(base::TimeTicks(), 0, base::nullopt, - &host_keyed_percentiles, - &host_keyed_counts); - - EXPECT_EQ(num_hosts, host_keyed_percentiles.size()); - EXPECT_EQ(num_hosts, host_keyed_counts.size()); - - // The 0 percentile must be equal to |90 * i| and the count must be equal to - // |20 * i| for host |i|. - for (unsigned int host_index = 1; host_index <= num_hosts; host_index++) { - EXPECT_EQ(90u * host_index, - static_cast<uint32_t>( - host_keyed_percentiles[static_cast<uint64_t>(host_index)])); - EXPECT_EQ(static_cast<size_t>(20 * host_index + 1), - host_keyed_counts[static_cast<uint64_t>(host_index)]); - } - - // Test the computation of 100th percentile. - buffer.GetPercentileForEachHostWithCounts( - base::TimeTicks(), 100, base::nullopt, &host_keyed_percentiles, - &host_keyed_counts); - - EXPECT_EQ(num_hosts, host_keyed_percentiles.size()); - EXPECT_EQ(num_hosts, host_keyed_counts.size()); - - // The 0 percentile must be equal to |90 * i| and the count must be equal to - // |20 * i| for host |i|. - for (int host_index = 1; host_index <= 3; host_index++) { - EXPECT_EQ(110 * host_index, - host_keyed_percentiles[static_cast<uint64_t>(host_index)]); - EXPECT_EQ(static_cast<size_t>(20 * host_index + 1), - host_keyed_counts[static_cast<uint64_t>(host_index)]); - } -} } // namespace
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h index 4ebd7d6d..292ac7f 100644 --- a/net/quic/quic_flags_list.h +++ b/net/quic/quic_flags_list.h
@@ -253,13 +253,6 @@ FLAGS_quic_reloadable_flag_quic_deprecate_post_process_after_data, true) -// If true, QuicSpdyClientSessionBase::OnPromiseHeaderList() will close the -// connection if the stream id referenced indicates a static stream. -QUIC_FLAG( - bool, - FLAGS_quic_reloadable_flag_quic_check_stream_nonstatic_on_promised_headers, - false) - // When the STMP connection option is sent by the client, timestamps in the QUIC // ACK frame are sent and processed. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_send_timestamps, false) @@ -270,3 +263,8 @@ // When true, don't arm the path degrading alarm on the server side and stop // using HasUnackedPackets to decide when to arm it. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_path_degrading_alarm, false) + +// When true, QUIC server push uses a unidirectional stream. +QUIC_FLAG(bool, + FLAGS_quic_reloadable_flag_quic_unidirectional_server_push_stream, + false)
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index ca102cdd..656d0e1b 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc
@@ -4945,9 +4945,25 @@ 3}, }; +namespace { +namespace test_default { +#include "net/http/transport_security_state_static_unittest_default.h" +} // namespace test_default +} // namespace + class TLS13DowngradeMetricsTest : public SSLClientSocketTest, - public ::testing::WithParamInterface<TLS13DowngradeMetricsParams> {}; + public ::testing::WithParamInterface<TLS13DowngradeMetricsParams> { + public: + TLS13DowngradeMetricsTest() { + // Switch the static preload list, so the tests using mail.google.com below + // do not trip the usual pins. + SetTransportSecurityStateSourceForTesting(&test_default::kHSTSSource); + } + ~TLS13DowngradeMetricsTest() { + SetTransportSecurityStateSourceForTesting(nullptr); + } +}; INSTANTIATE_TEST_CASE_P(/* no prefix */, TLS13DowngradeMetricsTest,
diff --git a/net/third_party/quic/core/http/quic_spdy_client_session_base.cc b/net/third_party/quic/core/http/quic_spdy_client_session_base.cc index 3e11c67..dd0502b 100644 --- a/net/third_party/quic/core/http/quic_spdy_client_session_base.cc +++ b/net/third_party/quic/core/http/quic_spdy_client_session_base.cc
@@ -6,7 +6,6 @@ #include "net/third_party/quic/core/http/quic_client_promised_info.h" #include "net/third_party/quic/core/http/spdy_utils.h" -#include "net/third_party/quic/platform/api/quic_flag_utils.h" #include "net/third_party/quic/platform/api/quic_flags.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_string.h" @@ -61,15 +60,11 @@ QuicStreamId promised_stream_id, size_t frame_len, const QuicHeaderList& header_list) { - if (GetQuicReloadableFlag(quic_check_stream_nonstatic_on_promised_headers)) { - QUIC_FLAG_COUNT( - quic_reloadable_flag_quic_check_stream_nonstatic_on_promised_headers); - if (QuicContainsKey(static_streams(), stream_id)) { - connection()->CloseConnection( - QUIC_INVALID_HEADERS_STREAM_DATA, "stream is static", - ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); - return; - } + if (QuicContainsKey(static_streams(), stream_id)) { + connection()->CloseConnection( + QUIC_INVALID_HEADERS_STREAM_DATA, "stream is static", + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); + return; } if (promised_stream_id != kInvalidStreamId && promised_stream_id <= largest_promised_stream_id_) {
diff --git a/net/third_party/quic/core/http/quic_spdy_client_session_test.cc b/net/third_party/quic/core/http/quic_spdy_client_session_test.cc index dcb4567..6c27b55 100644 --- a/net/third_party/quic/core/http/quic_spdy_client_session_test.cc +++ b/net/third_party/quic/core/http/quic_spdy_client_session_test.cc
@@ -326,8 +326,6 @@ TEST_P(QuicSpdyClientSessionTest, OnPromiseHeaderListWithStaticStream) { // Test situation where OnPromiseHeaderList is called by stream with static // id. - FLAGS_quic_reloadable_flag_quic_check_stream_nonstatic_on_promised_headers = - true; CompleteCryptoHandshake(); QuicHeaderList trailers;
diff --git a/net/third_party/quic/core/http/quic_spdy_session.h b/net/third_party/quic/core/http/quic_spdy_session.h index 1bea32e9..83762be5 100644 --- a/net/third_party/quic/core/http/quic_spdy_session.h +++ b/net/third_party/quic/core/http/quic_spdy_session.h
@@ -139,8 +139,8 @@ // CreateOutgoingUnidirectionalStream() with QuicSpdyStream return type to // make sure that all data streams are QuicSpdyStreams. QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override = 0; - QuicSpdyStream* CreateOutgoingBidirectionalStream() override = 0; - QuicSpdyStream* CreateOutgoingUnidirectionalStream() override = 0; + virtual QuicSpdyStream* CreateOutgoingBidirectionalStream() = 0; + virtual QuicSpdyStream* CreateOutgoingUnidirectionalStream() = 0; QuicSpdyStream* GetSpdyDataStream(const QuicStreamId stream_id); @@ -148,6 +148,10 @@ virtual bool ShouldCreateIncomingStream(QuicStreamId id) = 0; // If an outgoing stream can be created, return true. + // TODO(fayang): In IETF QUIC, there are different stream limits on + // unidirectional v.s. bidirectional outgoing streams. Need to split this + // method to ShouldCreateOutgoingUnidirectionalStream and + // ShouldCreateOutgoingBidirectionalStream. virtual bool ShouldCreateOutgoingStream() = 0; // This was formerly QuicHeadersStream::WriteHeaders. Needs to be
diff --git a/net/third_party/quic/core/quic_connection.cc b/net/third_party/quic/core/quic_connection.cc index b25f0923..3d39eb8 100644 --- a/net/third_party/quic/core/quic_connection.cc +++ b/net/third_party/quic/core/quic_connection.cc
@@ -450,6 +450,7 @@ config.HasClientSentConnectionOption(kSTMP, perspective_)) { QUIC_FLAG_COUNT(quic_reloadable_flag_quic_send_timestamps); framer_.set_process_timestamps(true); + received_packet_manager_.set_save_timestamps(true); } }
diff --git a/net/third_party/quic/core/quic_packet_generator_test.cc b/net/third_party/quic/core/quic_packet_generator_test.cc index cd523e9f..7a6960de 100644 --- a/net/third_party/quic/core/quic_packet_generator_test.cc +++ b/net/third_party/quic/core/quic_packet_generator_test.cc
@@ -27,7 +27,6 @@ #include "net/third_party/quic/test_tools/simple_data_producer.h" #include "net/third_party/quic/test_tools/simple_quic_framer.h" -using std::string; using testing::_; using testing::InSequence; using testing::Return; @@ -1097,7 +1096,7 @@ frame->error_code = QUIC_PACKET_WRITE_ERROR; char buf[2000] = {}; QuicStringPiece error_details(buf, 2000); - frame->error_details = string(error_details); + frame->error_details = QuicString(error_details); generator_.AddControlFrame(QuicFrame(frame)); EXPECT_TRUE(generator_.HasQueuedFrames()); EXPECT_TRUE(generator_.HasRetransmittableFrames());
diff --git a/net/third_party/quic/core/quic_received_packet_manager.cc b/net/third_party/quic/core/quic_received_packet_manager.cc index ed280968..53f1043 100644 --- a/net/third_party/quic/core/quic_received_packet_manager.cc +++ b/net/third_party/quic/core/quic_received_packet_manager.cc
@@ -29,6 +29,7 @@ ack_frame_updated_(false), max_ack_ranges_(0), time_largest_observed_(QuicTime::Zero()), + save_timestamps_(false), stats_(stats) {} QuicReceivedPacketManager::~QuicReceivedPacketManager() {} @@ -60,8 +61,19 @@ } ack_frame_.packets.Add(packet_number); - ack_frame_.received_packet_times.push_back( - std::make_pair(packet_number, receipt_time)); + if (save_timestamps_) { + // The timestamp format only handles packets in time order. + if (!ack_frame_.received_packet_times.empty() && + ack_frame_.received_packet_times.back().second > receipt_time) { + LOG(WARNING) + << "Receive time went backwards from: " + << ack_frame_.received_packet_times.back().second.ToDebuggingValue() + << " to " << receipt_time.ToDebuggingValue(); + } else { + ack_frame_.received_packet_times.push_back( + std::make_pair(packet_number, receipt_time)); + } + } } bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) {
diff --git a/net/third_party/quic/core/quic_received_packet_manager.h b/net/third_party/quic/core/quic_received_packet_manager.h index 4438194..21fe690f 100644 --- a/net/third_party/quic/core/quic_received_packet_manager.h +++ b/net/third_party/quic/core/quic_received_packet_manager.h
@@ -72,6 +72,10 @@ max_ack_ranges_ = max_ack_ranges; } + void set_save_timestamps(bool save_timestamps) { + save_timestamps_ = save_timestamps; + } + private: friend class test::QuicConnectionPeer; @@ -94,6 +98,9 @@ // Needed for calculating ack_delay_time. QuicTime time_largest_observed_; + // If true, save timestamps in the ack_frame_. + bool save_timestamps_; + QuicConnectionStats* stats_; };
diff --git a/net/third_party/quic/core/quic_received_packet_manager_test.cc b/net/third_party/quic/core/quic_received_packet_manager_test.cc index 3191cd3..cfa42ff 100644 --- a/net/third_party/quic/core/quic_received_packet_manager_test.cc +++ b/net/third_party/quic/core/quic_received_packet_manager_test.cc
@@ -38,7 +38,9 @@ class QuicReceivedPacketManagerTest : public QuicTestWithParam<TestParams> { protected: - QuicReceivedPacketManagerTest() : received_manager_(&stats_) {} + QuicReceivedPacketManagerTest() : received_manager_(&stats_) { + received_manager_.set_save_timestamps(true); + } void RecordPacketReceipt(QuicPacketNumber packet_number) { RecordPacketReceipt(packet_number, QuicTime::Zero()); @@ -141,6 +143,18 @@ } } +TEST_P(QuicReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) { + EXPECT_FALSE(received_manager_.ack_frame_updated()); + RecordPacketReceipt(1, QuicTime::Zero()); + EXPECT_TRUE(received_manager_.ack_frame_updated()); + EXPECT_EQ(1u, received_manager_.ack_frame().received_packet_times.size()); + RecordPacketReceipt(2, + QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1)); + EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size()); + RecordPacketReceipt(3, QuicTime::Zero()); + EXPECT_EQ(2u, received_manager_.ack_frame().received_packet_times.size()); +} + } // namespace } // namespace test } // namespace quic
diff --git a/net/third_party/quic/core/quic_session.h b/net/third_party/quic/core/quic_session.h index da9bd76..1b1d7d5 100644 --- a/net/third_party/quic/core/quic_session.h +++ b/net/third_party/quic/core/quic_session.h
@@ -358,16 +358,6 @@ // Returns nullptr and does error handling if the stream can not be created. virtual QuicStream* CreateIncomingStream(QuicStreamId id) = 0; - // Create a new stream to handle a locally-initiated bidirectional stream. - // Caller does not own the returned stream. - // Returns nullptr if max streams have already been opened. - virtual QuicStream* CreateOutgoingBidirectionalStream() = 0; - - // Create a new stream to handle a locally-initiated write unidirectional - // stream. Caller does not own the returned stream. Returns nullptr if max - // streams have already been opened. - virtual QuicStream* CreateOutgoingUnidirectionalStream() = 0; - // Return the reserved crypto stream. virtual QuicCryptoStream* GetMutableCryptoStream() = 0;
diff --git a/net/third_party/quic/core/quic_session_test.cc b/net/third_party/quic/core/quic_session_test.cc index d0d61f7..f983472 100644 --- a/net/third_party/quic/core/quic_session_test.cc +++ b/net/third_party/quic/core/quic_session_test.cc
@@ -144,14 +144,14 @@ return &crypto_stream_; } - TestStream* CreateOutgoingBidirectionalStream() override { + TestStream* CreateOutgoingBidirectionalStream() { TestStream* stream = new TestStream(GetNextOutgoingStreamId(), this, BIDIRECTIONAL); ActivateStream(QuicWrapUnique(stream)); return stream; } - TestStream* CreateOutgoingUnidirectionalStream() override { + TestStream* CreateOutgoingUnidirectionalStream() { TestStream* stream = new TestStream(GetNextOutgoingStreamId(), this, WRITE_UNIDIRECTIONAL); ActivateStream(QuicWrapUnique(stream));
diff --git a/net/third_party/quic/core/quic_stream.h b/net/third_party/quic/core/quic_stream.h index c132ac07..2ff6d68 100644 --- a/net/third_party/quic/core/quic_stream.h +++ b/net/third_party/quic/core/quic_stream.h
@@ -274,6 +274,8 @@ QuicByteCount data_length, bool fin) const; + StreamType type() const { return type_; } + protected: // Sends as many bytes in the first |count| buffers of |iov| to the connection // as the connection will consume. If FIN is consumed, the write side is
diff --git a/net/third_party/quic/platform/api/quic_url.cc b/net/third_party/quic/platform/api/quic_url.cc deleted file mode 100644 index 31953fd4..0000000 --- a/net/third_party/quic/platform/api/quic_url.cc +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright (c) 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/third_party/quic/platform/api/quic_url.h" -#include "net/third_party/quic/platform/api/quic_string.h" - -namespace quic { - -QuicUrl::QuicUrl(QuicStringPiece url) : impl_(url) {} - -QuicUrl::QuicUrl(QuicStringPiece url, QuicStringPiece default_scheme) - : impl_(url, default_scheme) {} - -QuicUrl::QuicUrl(const QuicUrl& url) : impl_(url.impl()) {} - -bool QuicUrl::IsValid() const { - return impl_.IsValid(); -} - -QuicString QuicUrl::ToString() const { - return impl_.ToStringIfValid(); -} - -QuicString QuicUrl::HostPort() const { - return impl_.HostPort(); -} - -QuicString QuicUrl::PathParamsQuery() const { - return impl_.PathParamsQuery(); -} - -QuicString QuicUrl::host() const { - return impl_.host(); -} - -QuicString QuicUrl::path() const { - return impl_.path(); -} - -QuicString QuicUrl::scheme() const { - return impl_.scheme(); -} - -uint16_t QuicUrl::port() const { - return impl_.port(); -} - -} // namespace quic
diff --git a/net/third_party/quic/platform/api/quic_url.h b/net/third_party/quic/platform/api/quic_url.h deleted file mode 100644 index 3725adb..0000000 --- a/net/third_party/quic/platform/api/quic_url.h +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright (c) 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_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_URL_H_ -#define NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_URL_H_ - -#include "net/third_party/quic/platform/api/quic_export.h" -#include "net/third_party/quic/platform/api/quic_string.h" -#include "net/third_party/quic/platform/api/quic_string_piece.h" -#include "net/third_party/quic/platform/impl/quic_url_impl.h" - -namespace quic { - -// QuicUrl stores a representation of a URL. -class QUIC_EXPORT_PRIVATE QuicUrl { - public: - // Constructs an empty QuicUrl. - QuicUrl() = default; - - // Constructs a QuicUrl from the url string |url|. - // NOTE: If |url| doesn't have a scheme, it will have an empty scheme - // field. If that's not what you want, use the QuicUrlImpl(url, - // default_scheme) form below. - explicit QuicUrl(QuicStringPiece url); - - // Constructs a QuicUrl from |url|, assuming that the scheme for the QuicUrl - // is |default_scheme| if there is no scheme specified in |url|. - QuicUrl(QuicStringPiece url, QuicStringPiece default_scheme); - - QuicUrl(const QuicUrl& url); - - // Returns false if any of these conditions occur: - // No scheme specified - // Host name too long (the maximum hostname length is platform-dependent) - // Invalid characters in host name, path or params - // Invalid port number (e.g. greater than 65535) - bool IsValid() const; - - // PLEASE NOTE: ToString(), HostPort(), PathParamsQuery(), scheme(), host(), - // path() and port() functions should be only called on a valid QuicUrl. - // Return values are platform-dependent if called on a invalid QuicUrl. - - // Returns full text of the QuicUrl. - QuicString ToString() const; - - // Returns host:port. - // If the host is empty, it will return an empty string. - // If the host is an IPv6 address, it will be bracketed. - // If port is not present or is equal to default_port of scheme (e.g., port - // 80 for HTTP), it won't be returned. - QuicString HostPort() const; - - // Returns a string assembles path, parameters and query. - QuicString PathParamsQuery() const; - - QuicString scheme() const; - QuicString host() const; - QuicString path() const; - uint16_t port() const; - - const QuicUrlImpl& impl() const { return impl_; } - - private: - QuicUrlImpl impl_; -}; - -} // namespace quic - -#endif // NET_THIRD_PARTY_QUIC_PLATFORM_API_QUIC_URL_H_
diff --git a/net/third_party/quic/platform/impl/quic_url_impl.cc b/net/third_party/quic/platform/impl/quic_url_impl.cc deleted file mode 100644 index d9c1fd8d..0000000 --- a/net/third_party/quic/platform/impl/quic_url_impl.cc +++ /dev/null
@@ -1,106 +0,0 @@ -// Copyright (c) 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/third_party/quic/platform/impl/quic_url_impl.h" - -#include "net/third_party/quic/platform/api/quic_text_utils.h" - -using std::string; - -namespace quic { - -QuicUrlImpl::QuicUrlImpl(QuicStringPiece url) : url_(url) {} - -QuicUrlImpl::QuicUrlImpl(QuicStringPiece url, QuicStringPiece default_scheme) - : url_(url) { - if (url_.has_scheme()) { - return; - } - string buffer = default_scheme.as_string() + "://" + url.as_string(); - url_ = GURL(buffer); -} - -QuicUrlImpl::QuicUrlImpl(const QuicUrlImpl& url) : url_(url.url()) {} - -string QuicUrlImpl::ToStringIfValid() const { - if (IsValid()) { - return url_.spec(); - } - return ""; -} - -bool QuicUrlImpl::IsValid() const { - if (!url_.is_valid() || !url_.has_scheme()) { - return false; - } - - if (url_.has_host() && url_.host().length() > kMaxHostNameLength) { - return false; - } - - return true; -} - -string QuicUrlImpl::HostPort() const { - if (!IsValid() || !url_.has_host()) { - return ""; - } - - string buffer = url_.host(); - int port = url_.IntPort(); - string scheme = url_.scheme(); - if (port == url::PORT_UNSPECIFIED || - (url_.IsStandard() && - port == url::DefaultPortForScheme(scheme.c_str(), scheme.length()))) { - return buffer; - } - buffer = buffer + ":" + std::to_string(port); - return buffer; -} - -string QuicUrlImpl::PathParamsQuery() const { - if (!IsValid() || !url_.has_path()) { - return "/"; - } - - return url_.PathForRequest(); -} - -string QuicUrlImpl::scheme() const { - if (!IsValid()) { - return ""; - } - - return url_.scheme(); -} - -string QuicUrlImpl::host() const { - if (!IsValid()) { - return ""; - } - - return url_.HostNoBrackets(); -} - -string QuicUrlImpl::path() const { - if (!IsValid()) { - return ""; - } - - return url_.path(); -} - -uint16_t QuicUrlImpl::port() const { - if (!IsValid()) { - return 0; - } - - int port = url_.EffectiveIntPort(); - if (port == url::PORT_UNSPECIFIED) { - return 0; - } - return port; -} - -} // namespace quic
diff --git a/net/third_party/quic/platform/impl/quic_url_impl.h b/net/third_party/quic/platform/impl/quic_url_impl.h deleted file mode 100644 index d435dd56..0000000 --- a/net/third_party/quic/platform/impl/quic_url_impl.h +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright (c) 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_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_URL_IMPL_H_ -#define NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_URL_IMPL_H_ - -#include "net/third_party/quic/platform/api/quic_export.h" -#include "net/third_party/quic/platform/api/quic_string_piece.h" -#include "url/gurl.h" - -namespace quic { - -class QUIC_EXPORT_PRIVATE QuicUrlImpl { - public: - static const size_t kMaxHostNameLength = 256; - - // Constructs an empty QuicUrl. - QuicUrlImpl() = default; - - // Constructs a QuicUrlImpl from the url string |url|. - // NOTE: If |url| doesn't have a scheme, it will have an empty scheme - // field. If that's not what you want, use the QuicUrlImpl(url, - // default_scheme) form below. - explicit QuicUrlImpl(QuicStringPiece url); - - // Constructs a QuicUrlImpl from |url|, assuming that the scheme for the URL - // is |default_scheme| if there is no scheme specified in |url|. - QuicUrlImpl(QuicStringPiece url, QuicStringPiece default_scheme); - - QuicUrlImpl(const QuicUrlImpl& url); - - // Returns false if any of these conditions occur: - // No scheme specified - // Host name too long (> 256 bytes) - // Invalid characters in host name, path or params - // Invalid port number (e.g. greater than 65535) - bool IsValid() const; - - // Returns full text of the QuicUrlImpl if it is valid. Return empty string - // otherwise. - std::string ToStringIfValid() const; - - // Returns host:port. - // If the host is empty, it will return an empty std::string. - // If the host is an IPv6 address, it will be bracketed. - // If port is not present or is equal to default_port of scheme (e.g., port - // 80 for HTTP), it won't be returned. - std::string HostPort() const; - - // Returns a string assembles path, parameters and query. - std::string PathParamsQuery() const; - - std::string scheme() const; - std::string host() const; - std::string path() const; - uint16_t port() const; - - const GURL& url() const { return url_; } - - private: - GURL url_; -}; - -} // namespace quic - -#endif // NET_THIRD_PARTY_QUIC_PLATFORM_IMPL_QUIC_URL_IMPL_H_
diff --git a/net/third_party/quic/quartc/quartc_session.cc b/net/third_party/quic/quartc/quartc_session.cc index c08e0c9..5e0ff17 100644 --- a/net/third_party/quic/quartc/quartc_session.cc +++ b/net/third_party/quic/quartc/quartc_session.cc
@@ -177,11 +177,6 @@ QuicStream::kDefaultPriority)); } -QuartcStream* QuartcSession::CreateOutgoingUnidirectionalStream() { - DCHECK(false); - return nullptr; -} - void QuartcSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) { QuicSession::OnCryptoHandshakeEvent(event); if (event == HANDSHAKE_CONFIRMED) {
diff --git a/net/third_party/quic/quartc/quartc_session.h b/net/third_party/quic/quartc/quartc_session.h index 742d9da..204ad07d 100644 --- a/net/third_party/quic/quartc/quartc_session.h +++ b/net/third_party/quic/quartc/quartc_session.h
@@ -51,9 +51,7 @@ const QuicCryptoStream* GetCryptoStream() const override; - QuartcStream* CreateOutgoingBidirectionalStream() override; - - QuartcStream* CreateOutgoingUnidirectionalStream() override; + QuartcStream* CreateOutgoingBidirectionalStream(); void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override;
diff --git a/net/third_party/quic/quartc/quartc_stream_test.cc b/net/third_party/quic/quartc/quartc_stream_test.cc index f2ff1c4..45258606 100644 --- a/net/third_party/quic/quartc/quartc_stream_test.cc +++ b/net/third_party/quic/quartc/quartc_stream_test.cc
@@ -62,12 +62,6 @@ return nullptr; } - QuartcStream* CreateOutgoingBidirectionalStream() override { return nullptr; } - - QuartcStream* CreateOutgoingUnidirectionalStream() override { - return nullptr; - } - const QuicCryptoStream* GetCryptoStream() const override { return nullptr; } QuicCryptoStream* GetMutableCryptoStream() override { return nullptr; }
diff --git a/net/third_party/quic/test_tools/quic_test_client.cc b/net/third_party/quic/test_tools/quic_test_client.cc index 10bb8ea2..c6c4e03f 100644 --- a/net/third_party/quic/test_tools/quic_test_client.cc +++ b/net/third_party/quic/test_tools/quic_test_client.cc
@@ -20,14 +20,13 @@ #include "net/third_party/quic/platform/api/quic_ptr_util.h" #include "net/third_party/quic/platform/api/quic_stack_trace.h" #include "net/third_party/quic/platform/api/quic_text_utils.h" -#include "net/third_party/quic/platform/api/quic_url.h" #include "net/third_party/quic/test_tools/crypto_test_utils.h" #include "net/third_party/quic/test_tools/quic_client_peer.h" #include "net/third_party/quic/test_tools/quic_connection_peer.h" #include "net/third_party/quic/test_tools/quic_spdy_session_peer.h" #include "net/third_party/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quic/test_tools/quic_test_utils.h" - +#include "net/third_party/quic/tools/quic_url.h" namespace quic { namespace test {
diff --git a/net/third_party/quic/test_tools/quic_test_utils.h b/net/third_party/quic/test_tools/quic_test_utils.h index 30a2d6c6..356f919 100644 --- a/net/third_party/quic/test_tools/quic_test_utils.h +++ b/net/third_party/quic/test_tools/quic_test_utils.h
@@ -558,8 +558,6 @@ const QuicString& error_details, ConnectionCloseSource source)); MOCK_METHOD1(CreateIncomingStream, QuicStream*(QuicStreamId id)); - MOCK_METHOD0(CreateOutgoingBidirectionalStream, QuicStream*()); - MOCK_METHOD0(CreateOutgoingUnidirectionalStream, QuicStream*()); MOCK_METHOD1(ShouldCreateIncomingStream2, bool(QuicStreamId id)); MOCK_METHOD0(ShouldCreateOutgoingStream2, bool()); MOCK_METHOD5(WritevData,
diff --git a/net/third_party/quic/test_tools/simulator/actor.cc b/net/third_party/quic/test_tools/simulator/actor.cc index cd6e536..98aaca6 100644 --- a/net/third_party/quic/test_tools/simulator/actor.cc +++ b/net/third_party/quic/test_tools/simulator/actor.cc
@@ -5,12 +5,10 @@ #include "net/third_party/quic/test_tools/simulator/actor.h" #include "net/third_party/quic/test_tools/simulator/simulator.h" -using std::string; - namespace quic { namespace simulator { -Actor::Actor(Simulator* simulator, string name) +Actor::Actor(Simulator* simulator, QuicString name) : simulator_(simulator), clock_(simulator->GetClock()), name_(std::move(name)) {
diff --git a/net/third_party/quic/test_tools/simulator/actor.h b/net/third_party/quic/test_tools/simulator/actor.h index 514e8f0..17b90d0 100644 --- a/net/third_party/quic/test_tools/simulator/actor.h +++ b/net/third_party/quic/test_tools/simulator/actor.h
@@ -29,7 +29,7 @@ // will not be called again unless Schedule() is called. class Actor { public: - Actor(Simulator* simulator, std::string name); + Actor(Simulator* simulator, QuicString name); virtual ~Actor(); // Trigger all the events the actor can potentially handle at this point. @@ -37,7 +37,7 @@ // to schedule the next call manually. virtual void Act() = 0; - inline std::string name() const { return name_; } + inline QuicString name() const { return name_; } inline Simulator* simulator() const { return simulator_; } protected: @@ -49,7 +49,7 @@ Simulator* simulator_; const QuicClock* clock_; - std::string name_; + QuicString name_; private: // Since the Actor object registers itself with a simulator using a pointer to
diff --git a/net/third_party/quic/test_tools/simulator/alarm_factory.cc b/net/third_party/quic/test_tools/simulator/alarm_factory.cc index bb9921e1..04ea6fb0 100644 --- a/net/third_party/quic/test_tools/simulator/alarm_factory.cc +++ b/net/third_party/quic/test_tools/simulator/alarm_factory.cc
@@ -6,8 +6,6 @@ #include "net/third_party/quic/core/quic_alarm.h" #include "net/third_party/quic/platform/api/quic_str_cat.h" -using std::string; - namespace quic { namespace simulator { @@ -16,7 +14,7 @@ class Alarm : public QuicAlarm { public: Alarm(Simulator* simulator, - string name, + QuicString name, QuicArenaScopedPtr<QuicAlarm::Delegate> delegate) : QuicAlarm(std::move(delegate)), adapter_(simulator, name, this) {} ~Alarm() override {} @@ -34,7 +32,7 @@ // interfaces. class Adapter : public Actor { public: - Adapter(Simulator* simulator, string name, Alarm* parent) + Adapter(Simulator* simulator, QuicString name, Alarm* parent) : Actor(simulator, name), parent_(parent) {} ~Adapter() override {} @@ -52,12 +50,12 @@ Adapter adapter_; }; -AlarmFactory::AlarmFactory(Simulator* simulator, string name) +AlarmFactory::AlarmFactory(Simulator* simulator, QuicString name) : simulator_(simulator), name_(std::move(name)), counter_(0) {} AlarmFactory::~AlarmFactory() {} -string AlarmFactory::GetNewAlarmName() { +QuicString AlarmFactory::GetNewAlarmName() { ++counter_; return QuicStringPrintf("%s (alarm %i)", name_.c_str(), counter_); }
diff --git a/net/third_party/quic/test_tools/simulator/alarm_factory.h b/net/third_party/quic/test_tools/simulator/alarm_factory.h index 33d7e099..8ec6d1e 100644 --- a/net/third_party/quic/test_tools/simulator/alarm_factory.h +++ b/net/third_party/quic/test_tools/simulator/alarm_factory.h
@@ -14,7 +14,7 @@ // AlarmFactory allows to schedule QuicAlarms using the simulation event queue. class AlarmFactory : public QuicAlarmFactory { public: - AlarmFactory(Simulator* simulator, std::string name); + AlarmFactory(Simulator* simulator, QuicString name); AlarmFactory(const AlarmFactory&) = delete; AlarmFactory& operator=(const AlarmFactory&) = delete; ~AlarmFactory() override; @@ -26,10 +26,10 @@ private: // Automatically generate a name for a new alarm. - std::string GetNewAlarmName(); + QuicString GetNewAlarmName(); Simulator* simulator_; - std::string name_; + QuicString name_; int counter_; };
diff --git a/net/third_party/quic/test_tools/simulator/link.cc b/net/third_party/quic/test_tools/simulator/link.cc index 433583b..d33fd028 100644 --- a/net/third_party/quic/test_tools/simulator/link.cc +++ b/net/third_party/quic/test_tools/simulator/link.cc
@@ -7,8 +7,6 @@ #include "net/third_party/quic/platform/api/quic_str_cat.h" #include "net/third_party/quic/test_tools/simulator/simulator.h" -using std::string; - namespace quic { namespace simulator { @@ -16,7 +14,7 @@ const uint64_t kMaxRandomDelayUs = 10; OneWayLink::OneWayLink(Simulator* simulator, - string name, + QuicString name, UnconstrainedPortInterface* sink, QuicBandwidth bandwidth, QuicTime::Delta propagation_delay) @@ -87,7 +85,7 @@ } SymmetricLink::SymmetricLink(Simulator* simulator, - string name, + QuicString name, UnconstrainedPortInterface* sink_a, UnconstrainedPortInterface* sink_b, QuicBandwidth bandwidth,
diff --git a/net/third_party/quic/test_tools/simulator/link.h b/net/third_party/quic/test_tools/simulator/link.h index 64dfabdc..3f097bd 100644 --- a/net/third_party/quic/test_tools/simulator/link.h +++ b/net/third_party/quic/test_tools/simulator/link.h
@@ -20,7 +20,7 @@ class OneWayLink : public Actor, public ConstrainedPortInterface { public: OneWayLink(Simulator* simulator, - std::string name, + QuicString name, UnconstrainedPortInterface* sink, QuicBandwidth bandwidth, QuicTime::Delta propagation_delay); @@ -66,7 +66,7 @@ class SymmetricLink { public: SymmetricLink(Simulator* simulator, - std::string name, + QuicString name, UnconstrainedPortInterface* sink_a, UnconstrainedPortInterface* sink_b, QuicBandwidth bandwidth,
diff --git a/net/third_party/quic/test_tools/simulator/packet_filter.cc b/net/third_party/quic/test_tools/simulator/packet_filter.cc index 1e2e18b..069d5c7 100644 --- a/net/third_party/quic/test_tools/simulator/packet_filter.cc +++ b/net/third_party/quic/test_tools/simulator/packet_filter.cc
@@ -4,12 +4,12 @@ #include "net/third_party/quic/test_tools/simulator/packet_filter.h" -using std::string; - namespace quic { namespace simulator { -PacketFilter::PacketFilter(Simulator* simulator, string name, Endpoint* input) +PacketFilter::PacketFilter(Simulator* simulator, + QuicString name, + Endpoint* input) : Endpoint(simulator, name), input_(input) { input_->SetTxPort(this); }
diff --git a/net/third_party/quic/test_tools/simulator/packet_filter.h b/net/third_party/quic/test_tools/simulator/packet_filter.h index e769db1..dc31ce8 100644 --- a/net/third_party/quic/test_tools/simulator/packet_filter.h +++ b/net/third_party/quic/test_tools/simulator/packet_filter.h
@@ -39,7 +39,7 @@ public: // Initialize the filter by wrapping around |input|. Does not take the // ownership of |input|. - PacketFilter(Simulator* simulator, std::string name, Endpoint* input); + PacketFilter(Simulator* simulator, QuicString name, Endpoint* input); PacketFilter(const PacketFilter&) = delete; PacketFilter& operator=(const PacketFilter&) = delete; ~PacketFilter() override;
diff --git a/net/third_party/quic/test_tools/simulator/port.cc b/net/third_party/quic/test_tools/simulator/port.cc index 5d5de94..b90f80b 100644 --- a/net/third_party/quic/test_tools/simulator/port.cc +++ b/net/third_party/quic/test_tools/simulator/port.cc
@@ -4,8 +4,6 @@ #include "net/third_party/quic/test_tools/simulator/port.h" -using std::string; - namespace quic { namespace simulator { @@ -16,7 +14,7 @@ Packet::Packet(const Packet& packet) = default; -Endpoint::Endpoint(Simulator* simulator, string name) +Endpoint::Endpoint(Simulator* simulator, QuicString name) : Actor(simulator, name) {} } // namespace simulator
diff --git a/net/third_party/quic/test_tools/simulator/port.h b/net/third_party/quic/test_tools/simulator/port.h index c98cb6b8..80bbc34 100644 --- a/net/third_party/quic/test_tools/simulator/port.h +++ b/net/third_party/quic/test_tools/simulator/port.h
@@ -19,11 +19,11 @@ ~Packet(); Packet(const Packet& packet); - std::string source; - std::string destination; + QuicString source; + QuicString destination; QuicTime tx_timestamp; - std::string contents; + QuicString contents; QuicByteCount size; }; @@ -57,7 +57,7 @@ virtual void SetTxPort(ConstrainedPortInterface* port) = 0; protected: - Endpoint(Simulator* simulator, std::string name); + Endpoint(Simulator* simulator, QuicString name); }; } // namespace simulator
diff --git a/net/third_party/quic/test_tools/simulator/queue.cc b/net/third_party/quic/test_tools/simulator/queue.cc index 967c3b0..c7a141d 100644 --- a/net/third_party/quic/test_tools/simulator/queue.cc +++ b/net/third_party/quic/test_tools/simulator/queue.cc
@@ -7,14 +7,12 @@ #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/test_tools/simulator/simulator.h" -using std::string; - namespace quic { namespace simulator { Queue::ListenerInterface::~ListenerInterface() {} -Queue::Queue(Simulator* simulator, string name, QuicByteCount capacity) +Queue::Queue(Simulator* simulator, QuicString name, QuicByteCount capacity) : Actor(simulator, name), capacity_(capacity), bytes_queued_(0),
diff --git a/net/third_party/quic/test_tools/simulator/queue.h b/net/third_party/quic/test_tools/simulator/queue.h index e9641d30..5de086e 100644 --- a/net/third_party/quic/test_tools/simulator/queue.h +++ b/net/third_party/quic/test_tools/simulator/queue.h
@@ -23,7 +23,7 @@ virtual void OnPacketDequeued() = 0; }; - Queue(Simulator* simulator, std::string name, QuicByteCount capacity); + Queue(Simulator* simulator, QuicString name, QuicByteCount capacity); Queue(const Queue&) = delete; Queue& operator=(const Queue&) = delete; ~Queue() override;
diff --git a/net/third_party/quic/test_tools/simulator/quic_endpoint.cc b/net/third_party/quic/test_tools/simulator/quic_endpoint.cc index af0d65fb..0edddf2 100644 --- a/net/third_party/quic/test_tools/simulator/quic_endpoint.cc +++ b/net/third_party/quic/test_tools/simulator/quic_endpoint.cc
@@ -16,8 +16,6 @@ #include "net/third_party/quic/test_tools/quic_test_utils.h" #include "net/third_party/quic/test_tools/simulator/simulator.h" -using std::string; - namespace quic { namespace simulator { @@ -26,8 +24,8 @@ const char kStreamDataContents = 'Q'; // Takes a SHA-1 hash of the name and converts it into five 32-bit integers. -static std::vector<uint32_t> HashNameIntoFive32BitIntegers(string name) { - const string hash = test::Sha1Hash(name); +static std::vector<uint32_t> HashNameIntoFive32BitIntegers(QuicString name) { + const QuicString hash = test::Sha1Hash(name); std::vector<uint32_t> output; uint32_t current_number = 0; @@ -42,14 +40,14 @@ return output; } -QuicSocketAddress GetAddressFromName(string name) { +QuicSocketAddress GetAddressFromName(QuicString name) { const std::vector<uint32_t> hash = HashNameIntoFive32BitIntegers(name); // Generate a random port between 1025 and 65535. const uint16_t port = 1025 + hash[0] % (65535 - 1025 + 1); // Generate a random 10.x.x.x address, where x is between 1 and 254. - string ip_address{"\xa\0\0\0", 4}; + QuicString ip_address{"\xa\0\0\0", 4}; for (size_t i = 1; i < 4; i++) { ip_address[i] = 1 + hash[i] % 254; } @@ -59,8 +57,8 @@ } QuicEndpoint::QuicEndpoint(Simulator* simulator, - string name, - string peer_name, + QuicString name, + QuicString peer_name, Perspective perspective, QuicConnectionId connection_id) : Endpoint(simulator, name), @@ -106,7 +104,7 @@ // primarily because // - this enables pacing, and // - this sets the non-handshake timeouts. - std::string error; + QuicString error; CryptoHandshakeMessage peer_hello; peer_hello.SetValue(kICSL, static_cast<uint32_t>(kMaximumIdleTimeoutSecs - 1)); @@ -125,7 +123,7 @@ const char* perspective_prefix = connection_.perspective() == Perspective::IS_CLIENT ? "C" : "S"; - string identifier = + QuicString identifier = QuicStrCat(perspective_prefix, connection_.connection_id()); QuicRecordTestOutput(identifier, trace_visitor_->trace()->SerializeAsString()); @@ -305,7 +303,7 @@ packet->destination = endpoint_->peer_name_; packet->tx_timestamp = endpoint_->clock_->Now(); - packet->contents = string(buffer, buf_len); + packet->contents = QuicString(buffer, buf_len); packet->size = buf_len; endpoint_->nic_tx_queue_.AcceptPacket(std::move(packet)); @@ -380,7 +378,7 @@ } QuicEndpointMultiplexer::QuicEndpointMultiplexer( - string name, + QuicString name, std::initializer_list<QuicEndpoint*> endpoints) : Endpoint((*endpoints.begin())->simulator(), name) { for (QuicEndpoint* endpoint : endpoints) {
diff --git a/net/third_party/quic/test_tools/simulator/quic_endpoint.h b/net/third_party/quic/test_tools/simulator/quic_endpoint.h index 5daacf80..88f4c45 100644 --- a/net/third_party/quic/test_tools/simulator/quic_endpoint.h +++ b/net/third_party/quic/test_tools/simulator/quic_endpoint.h
@@ -26,7 +26,7 @@ // Generate a random local network host-port tuple based on the name of the // endpoint. -QuicSocketAddress GetAddressFromName(std::string name); +QuicSocketAddress GetAddressFromName(QuicString name); // A QUIC connection endpoint. Wraps around QuicConnection. In order to // initiate a transfer, the caller has to call AddBytesToTransfer(). The data @@ -40,8 +40,8 @@ public SessionNotifierInterface { public: QuicEndpoint(Simulator* simulator, - std::string name, - std::string peer_name, + QuicString name, + QuicString peer_name, Perspective perspective, QuicConnectionId connection_id); ~QuicEndpoint() override; @@ -91,7 +91,7 @@ void OnGoAway(const QuicGoAwayFrame& frame) override {} void OnMessageReceived(QuicStringPiece message) override {} void OnConnectionClosed(QuicErrorCode error, - const std::string& error_details, + const QuicString& error_details, ConnectionCloseSource source) override {} void OnWriteBlocked() override {} void OnSuccessfulVersionNegotiation( @@ -163,7 +163,7 @@ // write-blocked. void WriteStreamData(); - std::string peer_name_; + QuicString peer_name_; Writer writer_; DataProducer producer_; @@ -197,7 +197,7 @@ class QuicEndpointMultiplexer : public Endpoint, public UnconstrainedPortInterface { public: - QuicEndpointMultiplexer(std::string name, + QuicEndpointMultiplexer(QuicString name, std::initializer_list<QuicEndpoint*> endpoints); ~QuicEndpointMultiplexer() override; @@ -212,7 +212,7 @@ void Act() override {} private: - QuicUnorderedMap<std::string, QuicEndpoint*> mapping_; + QuicUnorderedMap<QuicString, QuicEndpoint*> mapping_; }; } // namespace simulator
diff --git a/net/third_party/quic/test_tools/simulator/simulator.h b/net/third_party/quic/test_tools/simulator/simulator.h index a086eb2..74ed03a 100644 --- a/net/third_party/quic/test_tools/simulator/simulator.h +++ b/net/third_party/quic/test_tools/simulator/simulator.h
@@ -126,7 +126,7 @@ // For each actor, maintain the time it is scheduled at. The value for // unscheduled actors is QuicTime::Infinite(). QuicUnorderedMap<Actor*, QuicTime> scheduled_times_; - QuicUnorderedSet<std::string> actor_names_; + QuicUnorderedSet<QuicString> actor_names_; }; template <class TerminationPredicate>
diff --git a/net/third_party/quic/test_tools/simulator/simulator_test.cc b/net/third_party/quic/test_tools/simulator/simulator_test.cc index 19c80a7..fdda91c 100644 --- a/net/third_party/quic/test_tools/simulator/simulator_test.cc +++ b/net/third_party/quic/test_tools/simulator/simulator_test.cc
@@ -16,7 +16,6 @@ #include "net/third_party/quic/test_tools/simulator/switch.h" #include "net/third_party/quic/test_tools/simulator/traffic_policer.h" -using std::string; using testing::_; using testing::Return; using testing::StrictMock; @@ -27,7 +26,7 @@ // A simple counter that increments its value by 1 every specified period. class Counter : public Actor { public: - Counter(Simulator* simulator, string name, QuicTime::Delta period) + Counter(Simulator* simulator, QuicString name, QuicTime::Delta period) : Actor(simulator, name), value_(-1), period_(period) { Schedule(clock_->Now()); } @@ -87,7 +86,7 @@ per_destination_packet_counter_.clear(); } - QuicPacketCount CountPacketsForDestination(string destination) const { + QuicPacketCount CountPacketsForDestination(QuicString destination) const { auto result_it = per_destination_packet_counter_.find(destination); if (result_it == per_destination_packet_counter_.cend()) { return 0; @@ -99,7 +98,7 @@ QuicByteCount bytes_; QuicPacketCount packets_; - QuicUnorderedMap<string, QuicPacketCount> per_destination_packet_counter_; + QuicUnorderedMap<QuicString, QuicPacketCount> per_destination_packet_counter_; }; // Sends the packet to the specified destination at the uplink rate. Provides a @@ -107,9 +106,9 @@ class LinkSaturator : public Endpoint { public: LinkSaturator(Simulator* simulator, - string name, + QuicString name, QuicByteCount packet_size, - string destination) + QuicString destination) : Endpoint(simulator, name), packet_size_(packet_size), destination_(std::move(destination)), @@ -153,7 +152,7 @@ private: QuicByteCount packet_size_; - string destination_; + QuicString destination_; ConstrainedPortInterface* tx_port_; CounterPort rx_port_; @@ -425,7 +424,7 @@ class AlarmToggler : public Actor { public: AlarmToggler(Simulator* simulator, - string name, + QuicString name, QuicAlarm* alarm, QuicTime::Delta interval) : Actor(simulator, name), @@ -589,7 +588,7 @@ class MockPacketFilter : public PacketFilter { public: - MockPacketFilter(Simulator* simulator, string name, Endpoint* endpoint) + MockPacketFilter(Simulator* simulator, QuicString name, Endpoint* endpoint) : PacketFilter(simulator, name, endpoint) {} MOCK_METHOD1(FilterPacket, bool(const Packet&)); };
diff --git a/net/third_party/quic/test_tools/simulator/switch.cc b/net/third_party/quic/test_tools/simulator/switch.cc index b8e5c0bc..a4464043 100644 --- a/net/third_party/quic/test_tools/simulator/switch.cc +++ b/net/third_party/quic/test_tools/simulator/switch.cc
@@ -9,13 +9,11 @@ #include "net/third_party/quic/platform/api/quic_str_cat.h" #include "net/third_party/quic/test_tools/simulator/switch.h" -using std::string; - namespace quic { namespace simulator { Switch::Switch(Simulator* simulator, - string name, + QuicString name, SwitchPortNumber port_count, QuicByteCount queue_capacity) { for (size_t port_number = 1; port_number <= port_count; port_number++) { @@ -29,7 +27,7 @@ Switch::~Switch() {} Switch::Port::Port(Simulator* simulator, - string name, + QuicString name, Switch* parent, SwitchPortNumber port_number, QuicByteCount queue_capacity)
diff --git a/net/third_party/quic/test_tools/simulator/switch.h b/net/third_party/quic/test_tools/simulator/switch.h index 0b272f3..b0164cae 100644 --- a/net/third_party/quic/test_tools/simulator/switch.h +++ b/net/third_party/quic/test_tools/simulator/switch.h
@@ -20,7 +20,7 @@ class Switch { public: Switch(Simulator* simulator, - std::string name, + QuicString name, SwitchPortNumber port_count, QuicByteCount queue_capacity); Switch(const Switch&) = delete; @@ -42,7 +42,7 @@ class Port : public Endpoint, public UnconstrainedPortInterface { public: Port(Simulator* simulator, - std::string name, + QuicString name, Switch* parent, SwitchPortNumber port_number, QuicByteCount queue_capacity); @@ -80,7 +80,7 @@ // This can not be a QuicDeque since pointers into this are // assumed to be stable. std::deque<Port> ports_; - QuicUnorderedMap<std::string, Port*> switching_table_; + QuicUnorderedMap<QuicString, Port*> switching_table_; }; } // namespace simulator
diff --git a/net/third_party/quic/test_tools/simulator/traffic_policer.cc b/net/third_party/quic/test_tools/simulator/traffic_policer.cc index 3e62791..fb93329 100644 --- a/net/third_party/quic/test_tools/simulator/traffic_policer.cc +++ b/net/third_party/quic/test_tools/simulator/traffic_policer.cc
@@ -6,13 +6,11 @@ #include <algorithm> -using std::string; - namespace quic { namespace simulator { TrafficPolicer::TrafficPolicer(Simulator* simulator, - string name, + QuicString name, QuicByteCount initial_bucket_size, QuicByteCount max_bucket_size, QuicBandwidth target_bandwidth,
diff --git a/net/third_party/quic/test_tools/simulator/traffic_policer.h b/net/third_party/quic/test_tools/simulator/traffic_policer.h index fd38fcf..2ebbf4c 100644 --- a/net/third_party/quic/test_tools/simulator/traffic_policer.h +++ b/net/third_party/quic/test_tools/simulator/traffic_policer.h
@@ -20,7 +20,7 @@ class TrafficPolicer : public PacketFilter { public: TrafficPolicer(Simulator* simulator, - std::string name, + QuicString name, QuicByteCount initial_bucket_size, QuicByteCount max_bucket_size, QuicBandwidth target_bandwidth, @@ -45,7 +45,7 @@ QuicTime last_refill_time_; // Maps each destination to the number of tokens it has left. - QuicUnorderedMap<std::string, QuicByteCount> token_buckets_; + QuicUnorderedMap<QuicString, QuicByteCount> token_buckets_; }; } // namespace simulator
diff --git a/net/third_party/quic/tools/quic_backend_response.h b/net/third_party/quic/tools/quic_backend_response.h index 81698d0..743f436 100644 --- a/net/third_party/quic/tools/quic_backend_response.h +++ b/net/third_party/quic/tools/quic_backend_response.h
@@ -6,7 +6,7 @@ #define NET_THIRD_PARTY_QUIC_TOOLS_QUIC_BACKEND_RESPONSE_H_ #include "net/third_party/quic/core/http/spdy_utils.h" -#include "net/third_party/quic/platform/api/quic_url.h" +#include "net/third_party/quic/tools/quic_url.h" namespace quic {
diff --git a/net/third_party/quic/tools/quic_client_base.h b/net/third_party/quic/tools/quic_client_base.h index e722180..60dd7fad3 100644 --- a/net/third_party/quic/tools/quic_client_base.h +++ b/net/third_party/quic/tools/quic_client_base.h
@@ -124,7 +124,7 @@ // This should only be set before the initial Connect() void set_server_id(const QuicServerId& server_id) { server_id_ = server_id; } - void SetUserAgentID(const std::string& user_agent_id) { + void SetUserAgentID(const QuicString& user_agent_id) { crypto_config_.set_user_agent_id(user_agent_id); }
diff --git a/net/third_party/quic/tools/quic_client_bin.cc b/net/third_party/quic/tools/quic_client_bin.cc index 7e17273..297a1e9 100644 --- a/net/third_party/quic/tools/quic_client_bin.cc +++ b/net/third_party/quic/tools/quic_client_bin.cc
@@ -60,8 +60,8 @@ #include "net/third_party/quic/platform/api/quic_str_cat.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" #include "net/third_party/quic/platform/api/quic_text_utils.h" -#include "net/third_party/quic/platform/api/quic_url.h" #include "net/third_party/quic/tools/quic_client.h" +#include "net/third_party/quic/tools/quic_url.h" #include "net/third_party/spdy/core/spdy_header_block.h" #include "net/tools/epoll_server/epoll_server.h" #include "net/tools/quic/synchronous_host_resolver.h"
diff --git a/net/third_party/quic/tools/quic_client_epoll_network_helper.cc b/net/third_party/quic/tools/quic_client_epoll_network_helper.cc index 784282f..dfdf2fc7 100644 --- a/net/third_party/quic/tools/quic_client_epoll_network_helper.cc +++ b/net/third_party/quic/tools/quic_client_epoll_network_helper.cc
@@ -31,7 +31,6 @@ // TODO(rtenneti): Add support for MMSG_MORE. #define MMSG_MORE 0 -using std::string; namespace quic { @@ -59,7 +58,7 @@ CleanUpAllUDPSockets(); } -string QuicClientEpollNetworkHelper::Name() const { +QuicString QuicClientEpollNetworkHelper::Name() const { return "QuicClientEpollNetworkHelper"; }
diff --git a/net/third_party/quic/tools/quic_client_epoll_network_helper.h b/net/third_party/quic/tools/quic_client_epoll_network_helper.h index 2a6d22e3..b5a7d217 100644 --- a/net/third_party/quic/tools/quic_client_epoll_network_helper.h +++ b/net/third_party/quic/tools/quic_client_epoll_network_helper.h
@@ -48,7 +48,7 @@ ~QuicClientEpollNetworkHelper() override; // Return a name describing the class for use in debug/error reporting. - std::string Name() const override; + QuicString Name() const override; // From net::EpollCallbackInterface void OnRegistration(net::EpollServer* eps, int fd, int event_mask) override;
diff --git a/net/third_party/quic/tools/quic_memory_cache_backend.h b/net/third_party/quic/tools/quic_memory_cache_backend.h index ee605a4..454328d 100644 --- a/net/third_party/quic/tools/quic_memory_cache_backend.h +++ b/net/third_party/quic/tools/quic_memory_cache_backend.h
@@ -14,9 +14,9 @@ #include "net/third_party/quic/platform/api/quic_containers.h" #include "net/third_party/quic/platform/api/quic_mutex.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" -#include "net/third_party/quic/platform/api/quic_url.h" #include "net/third_party/quic/tools/quic_backend_response.h" #include "net/third_party/quic/tools/quic_simple_server_backend.h" +#include "net/third_party/quic/tools/quic_url.h" #include "net/third_party/spdy/core/spdy_framer.h" namespace quic {
diff --git a/net/third_party/quic/tools/quic_packet_printer_bin.cc b/net/third_party/quic/tools/quic_packet_printer_bin.cc index b9c3114..4b841c5 100644 --- a/net/third_party/quic/tools/quic_packet_printer_bin.cc +++ b/net/third_party/quic/tools/quic_packet_printer_bin.cc
@@ -41,14 +41,12 @@ #include "net/third_party/quic/core/quic_utils.h" #include "net/third_party/quic/platform/api/quic_text_utils.h" -using std::string; - // If set, specify the QUIC version to use. -string FLAGS_quic_version = ""; +quic::QuicString FLAGS_quic_version = ""; namespace { -string ArgToString(base::CommandLine::StringType arg) { +quic::QuicString ArgToString(base::CommandLine::StringType arg) { #if defined(OS_WIN) return base::UTF16ToASCII(arg); #else @@ -231,7 +229,7 @@ FLAGS_quic_version = line->GetSwitchValueASCII("quic_version"); } - string perspective_string = ArgToString(args[0]); + quic::QuicString perspective_string = ArgToString(args[0]); quic::Perspective perspective; if (perspective_string == "client") { perspective = quic::Perspective::IS_CLIENT; @@ -242,7 +240,7 @@ << " Usage: " << args[0] << " client|server <hex>\n"; return 1; } - string hex = quic::QuicTextUtils::HexDecode(argv[2]); + quic::QuicString hex = quic::QuicTextUtils::HexDecode(argv[2]); quic::ParsedQuicVersionVector versions = quic::AllSupportedVersions(); // Fake a time since we're not actually generating acks. quic::QuicTime start(quic::QuicTime::Zero());
diff --git a/net/third_party/quic/tools/quic_server.h b/net/third_party/quic/tools/quic_server.h index c181a49..77e31f4a 100644 --- a/net/third_party/quic/tools/quic_server.h +++ b/net/third_party/quic/tools/quic_server.h
@@ -47,7 +47,7 @@ ~QuicServer() override; - std::string Name() const override { return "QuicServer"; } + QuicString Name() const override { return "QuicServer"; } // Start listening on the specified address. bool CreateUDPSocketAndListen(const QuicSocketAddress& address);
diff --git a/net/third_party/quic/tools/quic_spdy_client_base.cc b/net/third_party/quic/tools/quic_spdy_client_base.cc index 01ff7cb..f13ee93 100644 --- a/net/third_party/quic/tools/quic_spdy_client_base.cc +++ b/net/third_party/quic/tools/quic_spdy_client_base.cc
@@ -13,7 +13,6 @@ #include "net/third_party/quic/platform/api/quic_text_utils.h" using base::StringToInt; -using std::string; namespace quic { @@ -133,7 +132,7 @@ } void QuicSpdyClientBase::SendRequestsAndWaitForResponse( - const std::vector<string>& url_list) { + const std::vector<QuicString>& url_list) { for (size_t i = 0; i < url_list.size(); ++i) { spdy::SpdyHeaderBlock headers; if (!SpdyUtils::PopulateHeaderBlockFromUrl(url_list[i], &headers)) { @@ -244,12 +243,12 @@ return latest_response_code_; } -const string& QuicSpdyClientBase::latest_response_headers() const { +const QuicString& QuicSpdyClientBase::latest_response_headers() const { QUIC_BUG_IF(!store_response_) << "Response not stored!"; return latest_response_headers_; } -const string& QuicSpdyClientBase::preliminary_response_headers() const { +const QuicString& QuicSpdyClientBase::preliminary_response_headers() const { QUIC_BUG_IF(!store_response_) << "Response not stored!"; return preliminary_response_headers_; } @@ -260,12 +259,12 @@ return latest_response_header_block_; } -const string& QuicSpdyClientBase::latest_response_body() const { +const QuicString& QuicSpdyClientBase::latest_response_body() const { QUIC_BUG_IF(!store_response_) << "Response not stored!"; return latest_response_body_; } -const string& QuicSpdyClientBase::latest_response_trailers() const { +const QuicString& QuicSpdyClientBase::latest_response_trailers() const { QUIC_BUG_IF(!store_response_) << "Response not stored!"; return latest_response_trailers_; }
diff --git a/net/third_party/quic/tools/quic_spdy_client_base.h b/net/third_party/quic/tools/quic_spdy_client_base.h index edb2003..fb5f149 100644 --- a/net/third_party/quic/tools/quic_spdy_client_base.h +++ b/net/third_party/quic/tools/quic_spdy_client_base.h
@@ -37,7 +37,7 @@ virtual void OnCompleteResponse( QuicStreamId id, const spdy::SpdyHeaderBlock& response_headers, - const std::string& response_body) = 0; + const QuicString& response_body) = 0; }; // The client uses these objects to keep track of any data to resend upon @@ -99,7 +99,7 @@ // Sends a request simple GET for each URL in |url_list|, and then waits for // each to complete. - void SendRequestsAndWaitForResponse(const std::vector<std::string>& url_list); + void SendRequestsAndWaitForResponse(const std::vector<QuicString>& url_list); // Returns a newly created QuicSpdyClientStream. QuicSpdyClientStream* CreateClientStream(); @@ -126,11 +126,11 @@ void set_store_response(bool val) { store_response_ = val; } size_t latest_response_code() const; - const std::string& latest_response_headers() const; - const std::string& preliminary_response_headers() const; + const QuicString& latest_response_headers() const; + const QuicString& preliminary_response_headers() const; const spdy::SpdyHeaderBlock& latest_response_header_block() const; - const std::string& latest_response_body() const; - const std::string& latest_response_trailers() const; + const QuicString& latest_response_body() const; + const QuicString& latest_response_trailers() const; void set_response_listener(std::unique_ptr<ResponseListener> listener) { response_listener_ = std::move(listener); @@ -190,15 +190,15 @@ // HTTP response code from most recent response. int latest_response_code_; // HTTP/2 headers from most recent response. - std::string latest_response_headers_; + QuicString latest_response_headers_; // preliminary 100 Continue HTTP/2 headers from most recent response, if any. - std::string preliminary_response_headers_; + QuicString preliminary_response_headers_; // HTTP/2 headers from most recent response. spdy::SpdyHeaderBlock latest_response_header_block_; // Body of most recent response. - std::string latest_response_body_; + QuicString latest_response_body_; // HTTP/2 trailers from most recent response. - std::string latest_response_trailers_; + QuicString latest_response_trailers_; // Listens for full responses. std::unique_ptr<ResponseListener> response_listener_;
diff --git a/net/third_party/quic/tools/quic_url.cc b/net/third_party/quic/tools/quic_url.cc new file mode 100644 index 0000000..f7f6b2a --- /dev/null +++ b/net/third_party/quic/tools/quic_url.cc
@@ -0,0 +1,101 @@ +// 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 "net/third_party/quic/tools/quic_url.h" + +#include "net/third_party/quic/platform/api/quic_str_cat.h" +#include "net/third_party/quic/platform/api/quic_text_utils.h" + +namespace quic { + +static constexpr size_t kMaxHostNameLength = 256; + +QuicUrl::QuicUrl(QuicStringPiece url) : url_(static_cast<QuicString>(url)) {} + +QuicUrl::QuicUrl(QuicStringPiece url, QuicStringPiece default_scheme) + : QuicUrl(url) { + if (url_.has_scheme()) { + return; + } + + url_ = GURL(QuicStrCat(default_scheme, "://", url)); +} + +QuicString QuicUrl::ToString() const { + if (IsValid()) { + return url_.spec(); + } + return ""; +} + +bool QuicUrl::IsValid() const { + if (!url_.is_valid() || !url_.has_scheme()) { + return false; + } + + if (url_.has_host() && url_.host().length() > kMaxHostNameLength) { + return false; + } + + return true; +} + +QuicString QuicUrl::HostPort() const { + if (!IsValid() || !url_.has_host()) { + return ""; + } + + QuicString host = url_.host(); + int port = url_.IntPort(); + if (port == url::PORT_UNSPECIFIED) { + return host; + } + return QuicStrCat(host, ":", port); +} + +QuicString QuicUrl::PathParamsQuery() const { + if (!IsValid() || !url_.has_path()) { + return "/"; + } + + return url_.PathForRequest(); +} + +QuicString QuicUrl::scheme() const { + if (!IsValid()) { + return ""; + } + + return url_.scheme(); +} + +QuicString QuicUrl::host() const { + if (!IsValid()) { + return ""; + } + + return url_.HostNoBrackets(); +} + +QuicString QuicUrl::path() const { + if (!IsValid()) { + return ""; + } + + return url_.path(); +} + +uint16_t QuicUrl::port() const { + if (!IsValid()) { + return 0; + } + + int port = url_.EffectiveIntPort(); + if (port == url::PORT_UNSPECIFIED) { + return 0; + } + return port; +} + +} // namespace quic
diff --git a/net/third_party/quic/tools/quic_url.h b/net/third_party/quic/tools/quic_url.h new file mode 100644 index 0000000..ccda449 --- /dev/null +++ b/net/third_party/quic/tools/quic_url.h
@@ -0,0 +1,60 @@ +// 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 NET_THIRD_PARTY_QUIC_TOOLS_QUIC_URL_H_ +#define NET_THIRD_PARTY_QUIC_TOOLS_QUIC_URL_H_ + +#include "net/third_party/quic/platform/api/quic_export.h" +#include "net/third_party/quic/platform/api/quic_string.h" +#include "net/third_party/quic/platform/api/quic_string_piece.h" +#include "url/gurl.h" + +namespace quic { + +// A utility class that wraps GURL. +class QuicUrl { + public: + // Constructs an empty QuicUrl. + QuicUrl() = default; + + // Constructs a QuicUrl from the url string |url|. + // + // NOTE: If |url| doesn't have a scheme, it will have an empty scheme + // field. If that's not what you want, use the QuicUrlImpl(url, + // default_scheme) form below. + explicit QuicUrl(QuicStringPiece url); + + // Constructs a QuicUrlImpl from |url|, assuming that the scheme for the URL + // is |default_scheme| if there is no scheme specified in |url|. + QuicUrl(QuicStringPiece url, QuicStringPiece default_scheme); + + // Returns false if the URL is not valid. + bool IsValid() const; + + // Returns full text of the QuicUrl if it is valid. Return empty string + // otherwise. + QuicString ToString() const; + + // Returns host:port. + // If the host is empty, it will return an empty string. + // If the host is an IPv6 address, it will be bracketed. + // If port is not present or is equal to default_port of scheme (e.g., port + // 80 for HTTP), it won't be returned. + QuicString HostPort() const; + + // Returns a string assembles path, parameters and query. + QuicString PathParamsQuery() const; + + QuicString scheme() const; + QuicString host() const; + QuicString path() const; + uint16_t port() const; + + private: + GURL url_; +}; + +} // namespace quic + +#endif // NET_THIRD_PARTY_QUIC_TOOLS_QUIC_URL_H_
diff --git a/net/third_party/quic/platform/api/quic_url_test.cc b/net/third_party/quic/tools/quic_url_test.cc similarity index 96% rename from net/third_party/quic/platform/api/quic_url_test.cc rename to net/third_party/quic/tools/quic_url_test.cc index fdeb8e62..db76e5f 100644 --- a/net/third_party/quic/platform/api/quic_url_test.cc +++ b/net/third_party/quic/tools/quic_url_test.cc
@@ -1,9 +1,10 @@ -// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// 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 "net/third_party/quic/platform/api/quic_url.h" +#include "net/third_party/quic/tools/quic_url.h" +#include "net/third_party/quic/platform/api/quic_str_cat.h" #include "net/third_party/quic/platform/api/quic_string.h" #include "net/third_party/quic/platform/api/quic_test.h"
diff --git a/net/websockets/websocket_basic_handshake_stream.cc b/net/websockets/websocket_basic_handshake_stream.cc index 266f6aa..1d4bf433 100644 --- a/net/websockets/websocket_basic_handshake_stream.cc +++ b/net/websockets/websocket_basic_handshake_stream.cc
@@ -161,7 +161,7 @@ const base::Feature WebSocketBasicHandshakeStream::kWebSocketHandshakeReuseConnection{ - "WebSocketHandshakeReuseConnection", base::FEATURE_DISABLED_BY_DEFAULT}; + "WebSocketHandshakeReuseConnection", base::FEATURE_ENABLED_BY_DEFAULT}; WebSocketBasicHandshakeStream::WebSocketBasicHandshakeStream( std::unique_ptr<ClientSocketHandle> connection,
diff --git a/net/websockets/websocket_stream_test.cc b/net/websockets/websocket_stream_test.cc index b278e00..501f967 100644 --- a/net/websockets/websocket_stream_test.cc +++ b/net/websockets/websocket_stream_test.cc
@@ -426,28 +426,24 @@ // send the authenticated request on. class CommonAuthTestHelper { public: - CommonAuthTestHelper() : reads1_(), writes1_(), reads2_(), writes2_() {} + CommonAuthTestHelper() : reads_(), writes_() {} - std::unique_ptr<SequencedSocketData> BuildSocketData1( - const std::string& response) { + std::unique_ptr<SequencedSocketData> BuildAuthSocketData( + std::string response1, + std::string request2, + std::string response2) { request1_ = WebSocketStandardRequest("/", "www.example.org", Origin(), "", ""); - writes1_[0] = MockWrite(SYNCHRONOUS, 0, request1_.c_str()); - response1_ = response; - reads1_[0] = MockRead(SYNCHRONOUS, 1, response1_.c_str()); - reads1_[1] = MockRead(SYNCHRONOUS, OK, 2); // Close connection + response1_ = std::move(response1); + request2_ = std::move(request2); + response2_ = std::move(response2); + writes_[0] = MockWrite(SYNCHRONOUS, 0, request1_.c_str()); + reads_[0] = MockRead(SYNCHRONOUS, 1, response1_.c_str()); + writes_[1] = MockWrite(SYNCHRONOUS, 2, request2_.c_str()); + reads_[1] = MockRead(SYNCHRONOUS, 3, response2_.c_str()); + reads_[2] = MockRead(SYNCHRONOUS, OK, 4); // Close connection - return BuildSocketData(reads1_, writes1_); - } - - std::unique_ptr<SequencedSocketData> BuildSocketData2( - const std::string& request, - const std::string& response) { - request2_ = request; - response2_ = response; - writes2_[0] = MockWrite(SYNCHRONOUS, 0, request2_.c_str()); - reads2_[0] = MockRead(SYNCHRONOUS, 1, response2_.c_str()); - return BuildSocketData(reads2_, writes2_); + return BuildSocketData(reads_, writes_); } private: @@ -457,10 +453,8 @@ std::string request2_; std::string response1_; std::string response2_; - MockRead reads1_[2]; - MockWrite writes1_[1]; - MockRead reads2_[1]; - MockWrite writes2_[1]; + MockRead reads_[3]; + MockWrite writes_[2]; DISALLOW_COPY_AND_ASSIGN(CommonAuthTestHelper); }; @@ -471,12 +465,11 @@ void CreateAndConnectAuthHandshake(base::StringPiece url, base::StringPiece base64_user_pass, base::StringPiece response2) { - AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse)); - CreateAndConnectRawExpectations( url, NoSubProtocols(), HttpRequestHeaders(), - helper_.BuildSocketData2(RequestExpectation(base64_user_pass), - response2.as_string())); + helper_.BuildAuthSocketData(kUnauthorizedResponse, + RequestExpectation(base64_user_pass), + response2.as_string())); } static std::string RequestExpectation(base::StringPiece base64_user_pass) { @@ -1479,10 +1472,6 @@ } TEST_P(WebSocketStreamCreateBasicAuthTest, SuccessfulConnectionReuse) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - WebSocketBasicHandshakeStream ::kWebSocketHandshakeReuseConnection); - std::string request1 = WebSocketStandardRequest("/", "www.example.org", Origin(), "", ""); std::string response1 = kUnauthorizedResponse; @@ -1528,8 +1517,11 @@ } TEST_P(WebSocketStreamCreateBasicAuthTest, OnAuthRequiredSetAuth) { - CreateAndConnectCustomResponse("ws://www.example.org/", NoSubProtocols(), {}, - {}, kUnauthorizedResponse); + CreateAndConnectRawExpectations( + "ws://www.example.org/", NoSubProtocols(), HttpRequestHeaders(), + helper_.BuildAuthSocketData(kUnauthorizedResponse, + RequestExpectation("Zm9vOmJheg=="), + WebSocketStandardResponse(std::string()))); EXPECT_FALSE(request_info_); EXPECT_FALSE(response_info_); @@ -1543,12 +1535,6 @@ base::ASCIIToUTF16("baz")); std::move(on_auth_required_callback_).Run(&credentials); - // As we are re-establishing the connection with additional credentials, - // add new expectations. - AddRawExpectations( - helper_.BuildSocketData2(RequestExpectation("Zm9vOmJheg=="), - WebSocketStandardResponse(std::string()))); - WaitUntilConnectDone(); EXPECT_TRUE(stream_); EXPECT_FALSE(has_failed()); @@ -1558,13 +1544,11 @@ // generally assume that whatever works for Basic auth will also work for // Digest. There's just one test here, to confirm that it works at all. TEST_P(WebSocketStreamCreateDigestAuthTest, DigestPasswordInUrl) { - AddRawExpectations(helper_.BuildSocketData1(kUnauthorizedResponse)); - CreateAndConnectRawExpectations( "ws://FooBar:pass@www.example.org/", NoSubProtocols(), HttpRequestHeaders(), - helper_.BuildSocketData2(kAuthorizedRequest, - WebSocketStandardResponse(std::string()))); + helper_.BuildAuthSocketData(kUnauthorizedResponse, kAuthorizedRequest, + WebSocketStandardResponse(std::string()))); WaitUntilConnectDone(); EXPECT_FALSE(has_failed()); EXPECT_TRUE(stream_);
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.cc b/ppapi/proxy/ppapi_command_buffer_proxy.cc index ab29b16..90f4147 100644 --- a/ppapi/proxy/ppapi_command_buffer_proxy.cc +++ b/ppapi/proxy/ppapi_command_buffer_proxy.cc
@@ -171,7 +171,7 @@ } void PpapiCommandBufferProxy::SetLock(base::Lock*) { - NOTREACHED(); + NOTIMPLEMENTED(); } void PpapiCommandBufferProxy::EnsureWorkVisible() { @@ -206,23 +206,22 @@ } bool PpapiCommandBufferProxy::IsFenceSyncReleased(uint64_t release) { - NOTREACHED(); + NOTIMPLEMENTED(); return false; } void PpapiCommandBufferProxy::SignalSyncToken(const gpu::SyncToken& sync_token, base::OnceClosure callback) { - NOTREACHED(); + NOTIMPLEMENTED(); } -// Pepper plugin does not expose or call WaitSyncTokenCHROMIUM. -void PpapiCommandBufferProxy::WaitSyncToken(const gpu::SyncToken& sync_token) { - NOTREACHED(); +void PpapiCommandBufferProxy::WaitSyncTokenHint( + const gpu::SyncToken& sync_token) { + // TODO(sunnyps): Forward sync token dependency hints to the renderer. } bool PpapiCommandBufferProxy::CanWaitUnverifiedSyncToken( const gpu::SyncToken& sync_token) { - NOTREACHED(); return false; } @@ -233,13 +232,13 @@ void PpapiCommandBufferProxy::CreateGpuFence(uint32_t gpu_fence_id, ClientGpuFence source) { - NOTREACHED(); + NOTIMPLEMENTED(); } void PpapiCommandBufferProxy::GetGpuFence( uint32_t gpu_fence_id, base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)> callback) { - NOTREACHED(); + NOTIMPLEMENTED(); } void PpapiCommandBufferProxy::SetGpuControlClient(gpu::GpuControlClient*) {
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.h b/ppapi/proxy/ppapi_command_buffer_proxy.h index 8d4d23c..28588f2 100644 --- a/ppapi/proxy/ppapi_command_buffer_proxy.h +++ b/ppapi/proxy/ppapi_command_buffer_proxy.h
@@ -76,7 +76,7 @@ bool IsFenceSyncReleased(uint64_t release) override; void SignalSyncToken(const gpu::SyncToken& sync_token, base::OnceClosure callback) override; - void WaitSyncToken(const gpu::SyncToken& sync_token) override; + void WaitSyncTokenHint(const gpu::SyncToken& sync_token) override; bool CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) override; private:
diff --git a/ppapi/tests/test_url_loader.cc b/ppapi/tests/test_url_loader.cc index d852353f..9f68aec 100644 --- a/ppapi/tests/test_url_loader.cc +++ b/ppapi/tests/test_url_loader.cc
@@ -874,7 +874,7 @@ loader.GetDownloadProgress(&bytes_received, &total_bytes_to_be_received); if (total_bytes_to_be_received <= 0) return ReportError("URLLoader::GetDownloadProgress total size", - total_bytes_to_be_received); + static_cast<int32_t>(total_bytes_to_be_received)); if (bytes_received == total_bytes_to_be_received) break; // Yield if we're on the main thread, so that URLLoader can receive more
diff --git a/remoting/test/app_remoting_test_driver.cc b/remoting/test/app_remoting_test_driver.cc index 0fbe1f1..310ee4a 100644 --- a/remoting/test/app_remoting_test_driver.cc +++ b/remoting/test/app_remoting_test_driver.cc
@@ -164,6 +164,8 @@ // We do not want to retry failures as a failed test should signify an error // to be investigated. command_line->AppendSwitchASCII(switches::kTestLauncherRetryLimit, "0"); + command_line->AppendSwitchASCII( + switches::kIsolatedScriptTestLauncherRetryLimit, "0"); // We do not want to run the tests in parallel and we do not want to retry // failures. The reason for running in a single process is that some tests
diff --git a/remoting/test/chromoting_test_driver.cc b/remoting/test/chromoting_test_driver.cc index aa7da51..279368f 100644 --- a/remoting/test/chromoting_test_driver.cc +++ b/remoting/test/chromoting_test_driver.cc
@@ -165,6 +165,8 @@ // Do not retry if tests fails. command_line->AppendSwitchASCII(switches::kTestLauncherRetryLimit, "0"); + command_line->AppendSwitchASCII( + switches::kIsolatedScriptTestLauncherRetryLimit, "0"); // Different tests may require access to the same host if run in parallel. // To avoid shared resource contention, tests will be run one at a time.
diff --git a/sandbox/win/src/registry_interception.cc b/sandbox/win/src/registry_interception.cc index 11a7781..4d381a9 100644 --- a/sandbox/win/src/registry_interception.cc +++ b/sandbox/win/src/registry_interception.cc
@@ -67,24 +67,26 @@ CountedParameterSet<OpenKey> params; params[OpenKey::ACCESS] = ParamPickerMake(desired_access_uint32); - wchar_t* full_name = nullptr; - const wchar_t* name_ptr = name.get(); + bool query_broker = false; + { + std::unique_ptr<wchar_t, NtAllocDeleter> full_name; + const wchar_t* name_ptr = name.get(); + const wchar_t* full_name_ptr = nullptr; - if (root_directory) { - ret = - sandbox::AllocAndGetFullPath(root_directory, name.get(), &full_name); - if (!NT_SUCCESS(ret) || !full_name) - break; - params[OpenKey::NAME] = ParamPickerMake(full_name); - } else { - params[OpenKey::NAME] = ParamPickerMake(name_ptr); + if (root_directory) { + ret = sandbox::AllocAndGetFullPath(root_directory, name.get(), + &full_name); + if (!NT_SUCCESS(ret) || !full_name) + break; + full_name_ptr = full_name.get(); + params[OpenKey::NAME] = ParamPickerMake(full_name_ptr); + } else { + params[OpenKey::NAME] = ParamPickerMake(name_ptr); + } + + query_broker = QueryBroker(IPC_NTCREATEKEY_TAG, params.GetBase()); } - bool query_broker = QueryBroker(IPC_NTCREATEKEY_TAG, params.GetBase()); - - if (full_name) - operator delete(full_name, NT_ALLOC); - if (!query_broker) break; @@ -150,24 +152,26 @@ CountedParameterSet<OpenKey> params; params[OpenKey::ACCESS] = ParamPickerMake(desired_access_uint32); - wchar_t* full_name = nullptr; - const wchar_t* name_ptr = name.get(); + bool query_broker = false; + { + std::unique_ptr<wchar_t, NtAllocDeleter> full_name; + const wchar_t* name_ptr = name.get(); + const wchar_t* full_name_ptr = nullptr; - if (root_directory) { - ret = - sandbox::AllocAndGetFullPath(root_directory, name.get(), &full_name); - if (!NT_SUCCESS(ret) || !full_name) - break; - params[OpenKey::NAME] = ParamPickerMake(full_name); - } else { - params[OpenKey::NAME] = ParamPickerMake(name_ptr); + if (root_directory) { + ret = sandbox::AllocAndGetFullPath(root_directory, name.get(), + &full_name); + if (!NT_SUCCESS(ret) || !full_name) + break; + full_name_ptr = full_name.get(); + params[OpenKey::NAME] = ParamPickerMake(full_name_ptr); + } else { + params[OpenKey::NAME] = ParamPickerMake(name_ptr); + } + + query_broker = QueryBroker(IPC_NTOPENKEY_TAG, params.GetBase()); } - bool query_broker = QueryBroker(IPC_NTOPENKEY_TAG, params.GetBase()); - - if (full_name) - operator delete(full_name, NT_ALLOC); - if (!query_broker) break;
diff --git a/sandbox/win/src/sandbox_nt_util.cc b/sandbox/win/src/sandbox_nt_util.cc index b4f6ab9..f71177fd 100644 --- a/sandbox/win/src/sandbox_nt_util.cc +++ b/sandbox/win/src/sandbox_nt_util.cc
@@ -228,14 +228,15 @@ return ret; } -NTSTATUS AllocAndGetFullPath(HANDLE root, wchar_t* path, wchar_t** full_path) { +NTSTATUS AllocAndGetFullPath( + HANDLE root, + const wchar_t* path, + std::unique_ptr<wchar_t, NtAllocDeleter>* full_path) { if (!InitHeap()) return STATUS_NO_MEMORY; DCHECK_NT(full_path); DCHECK_NT(path); - *full_path = nullptr; - OBJECT_NAME_INFORMATION* handle_name = nullptr; NTSTATUS ret = STATUS_UNSUCCESSFUL; __try { do { @@ -247,14 +248,15 @@ // Query the name information a first time to get the size of the name. ret = NtQueryObject(root, ObjectNameInformation, nullptr, 0, &size); + std::unique_ptr<OBJECT_NAME_INFORMATION, NtAllocDeleter> handle_name; if (size) { - handle_name = reinterpret_cast<OBJECT_NAME_INFORMATION*>( - new (NT_ALLOC) BYTE[size]); + handle_name.reset(reinterpret_cast<OBJECT_NAME_INFORMATION*>( + new (NT_ALLOC) BYTE[size])); // Query the name information a second time to get the name of the // object referenced by the handle. - ret = NtQueryObject(root, ObjectNameInformation, handle_name, size, - &size); + ret = NtQueryObject(root, ObjectNameInformation, handle_name.get(), + size, &size); } if (STATUS_SUCCESS != ret) @@ -263,10 +265,10 @@ // Space for path + '\' + name + '\0'. size_t name_length = handle_name->ObjectName.Length + (wcslen(path) + 2) * sizeof(wchar_t); - *full_path = new (NT_ALLOC) wchar_t[name_length / sizeof(wchar_t)]; + full_path->reset(new (NT_ALLOC) wchar_t[name_length / sizeof(wchar_t)]); if (!*full_path) break; - wchar_t* off = *full_path; + wchar_t* off = full_path->get(); ret = CopyData(off, handle_name->ObjectName.Buffer, handle_name->ObjectName.Length); if (!NT_SUCCESS(ret)) @@ -284,16 +286,8 @@ ret = GetExceptionCode(); } - if (!NT_SUCCESS(ret)) { - if (*full_path) { - operator delete(*full_path, NT_ALLOC); - *full_path = nullptr; - } - if (handle_name) { - operator delete(handle_name, NT_ALLOC); - handle_name = nullptr; - } - } + if (!NT_SUCCESS(ret) && *full_path) + full_path->reset(nullptr); return ret; }
diff --git a/sandbox/win/src/sandbox_nt_util.h b/sandbox/win/src/sandbox_nt_util.h index 1e777c7..85743e7 100644 --- a/sandbox/win/src/sandbox_nt_util.h +++ b/sandbox/win/src/sandbox_nt_util.h
@@ -119,7 +119,10 @@ HANDLE* root); // Determine full path name from object root and path. -NTSTATUS AllocAndGetFullPath(HANDLE root, wchar_t* path, wchar_t** full_path); +NTSTATUS AllocAndGetFullPath( + HANDLE root, + const wchar_t* path, + std::unique_ptr<wchar_t, NtAllocDeleter>* full_path); // Initializes our ntdll level heap bool InitHeap();
diff --git a/services/device/bluetooth/OWNERS b/services/device/bluetooth/OWNERS new file mode 100644 index 0000000..b6bdb83b --- /dev/null +++ b/services/device/bluetooth/OWNERS
@@ -0,0 +1,2 @@ +ortuno@chromium.org +reillyg@chromium.org
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc index f7bec193..4ddb8b6 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -7,6 +7,7 @@ #include <map> #include <utility> +#include "base/hash.h" #include "base/json/json_writer.h" #include "base/memory/ref_counted_memory.h" #include "base/no_destructor.h" @@ -127,28 +128,35 @@ trace_packet_handle_ = trace_writer_->NewTracePacket(); event_bundle_ = ChromeEventBundleHandle(trace_packet_handle_->set_chrome_events()); - string_table_.clear(); - next_string_table_index_ = 0; + interned_strings_.clear(); +#if DCHECK_IS_ON() + hash_verifier_.clear(); +#endif } - int GetStringTableIndexForString(const char* str_value) { + uint32_t GetStringTableIndexForString(const char* str_value) { EnsureValidHandles(); - auto it = string_table_.find(reinterpret_cast<intptr_t>(str_value)); - if (it != string_table_.end()) { - CHECK_EQ(std::string(reinterpret_cast<const char*>(it->first)), - std::string(str_value)); + uint32_t string_table_index = base::Hash(str_value, strlen(str_value)); - return it->second; + if (interned_strings_.find(string_table_index) != interned_strings_.end()) { +#if DCHECK_IS_ON() + DCHECK_EQ(hash_verifier_[string_table_index], str_value); +#endif + + return string_table_index; } - int string_table_index = ++next_string_table_index_; - string_table_[reinterpret_cast<intptr_t>(str_value)] = string_table_index; + interned_strings_.insert(string_table_index); auto* new_string_table_entry = event_bundle_->add_string_table(); new_string_table_entry->set_value(str_value); new_string_table_entry->set_index(string_table_index); +#if DCHECK_IS_ON() + hash_verifier_[string_table_index] = str_value; +#endif + return string_table_index; } @@ -176,9 +184,11 @@ EnsureValidHandles(); - int name_index = 0; - int category_name_index = 0; - int arg_name_indices[base::trace_event::kTraceMaxNumArgs] = {0}; + uint32_t name_index = 0; + uint32_t category_name_index = 0; + uint32_t arg_name_indices[base::trace_event::kTraceMaxNumArgs] = {0}; + + char phase = trace_event.phase(); // Populate any new string table parts first; has to be done before // the add_trace_events() call (as the string table is part of the outer @@ -188,9 +198,18 @@ // the string every time. bool string_table_enabled = !(trace_event.flags() & TRACE_EVENT_FLAG_COPY); if (string_table_enabled) { - name_index = GetStringTableIndexForString(trace_event.name()); - category_name_index = GetStringTableIndexForString( - TraceLog::GetCategoryGroupName(trace_event.category_group_enabled())); + // Optimization: If it's an _END event, we know that the string table + // entries for the name and the category have already been emitted. + if (phase == TRACE_EVENT_PHASE_END) { + name_index = base::Hash(trace_event.name()); + category_name_index = base::Hash(TraceLog::GetCategoryGroupName( + trace_event.category_group_enabled())); + } else { + name_index = GetStringTableIndexForString(trace_event.name()); + category_name_index = + GetStringTableIndexForString(TraceLog::GetCategoryGroupName( + trace_event.category_group_enabled())); + } for (int i = 0; i < base::trace_event::kTraceMaxNumArgs && trace_event.arg_name(i); @@ -235,7 +254,6 @@ new_trace_event->set_process_id(process_id); new_trace_event->set_thread_id(thread_id); - char phase = trace_event.phase(); new_trace_event->set_phase(phase); for (int i = 0; @@ -288,11 +306,6 @@ int64_t duration = trace_event.duration().InMicroseconds(); if (duration != -1) { new_trace_event->set_duration(duration); - } else { - // TODO(oysteine): Workaround until TRACE_EVENT_PHASE_COMPLETE can be - // split into begin/end pairs. If the duration is -1 and the - // trace-viewer will spend forever generating a warning for each event. - new_trace_event->set_duration(0); } if (!trace_event.thread_timestamp().is_null()) { @@ -329,16 +342,16 @@ event_bundle_ = ChromeEventBundleHandle(); trace_packet_handle_ = perfetto::TraceWriter::TracePacketHandle(); trace_writer_->Flush(); - token_ = ""; } private: std::unique_ptr<perfetto::TraceWriter> trace_writer_; ChromeEventBundleHandle event_bundle_; perfetto::TraceWriter::TracePacketHandle trace_packet_handle_; - std::map<intptr_t, int> string_table_; - int next_string_table_index_ = 0; - std::string token_; + std::set<uint32_t> interned_strings_; +#if DCHECK_IS_ON() + std::map<uint32_t, std::string> hash_verifier_; +#endif }; namespace {
diff --git a/testing/buildbot/filters/chromeos.single_process_mash.browser_tests.filter b/testing/buildbot/filters/chromeos.single_process_mash.browser_tests.filter index 7f7b704..170f268 100644 --- a/testing/buildbot/filters/chromeos.single_process_mash.browser_tests.filter +++ b/testing/buildbot/filters/chromeos.single_process_mash.browser_tests.filter
@@ -72,10 +72,6 @@ # CalledOnValidSequence() from SchedulerWorkerDelegate::OnMainExit -LoginScreenDefaultPolicyLoginScreenBrowsertest.* -# ash::Shell access in test for display configuration. -# http://crbug.com/831826 --ShelfAppBrowserTest.LaunchAppFromDisplayWithoutFocus* - # Timeout because first non-empty paint isn't triggered. # https://crbug.com/885318 -NoBackgroundTasksTest.FirstNonEmptyPaintWithoutBackgroundTasks @@ -109,7 +105,7 @@ -PictureInPictureLazyBackgroundPageApiTest.PictureInPictureInBackgroundPage # These started failing with the switch to ws2. -# https:://crbug.com/855767 +# https://crbug.com/855767 -AppWindowApiTest.OnRestoredEvent -BrowserActionApiTest.BrowserActionPopupWithIframe -FirstRunUIBrowserTest.ModalWindowDoesNotBlock @@ -224,9 +220,6 @@ -WindowOpenApiTest.UpdateWindowToLockedFullscreen -WindowOpenApiTest.VerifyCommandsInLockedFullscreen -# Value of: immersive_controller->IsRevealed() --ZoomBubbleBrowserTest.ImmersiveFullscreen - # Flaky tests. crbug.com/833144 -GetAuthTokenFunctionPublicSessionTest.NonWhitelisted
diff --git a/testing/buildbot/filters/fuchsia.mojo_unittests.filter b/testing/buildbot/filters/fuchsia.mojo_unittests.filter index 7a1c767..8f529675 100644 --- a/testing/buildbot/filters/fuchsia.mojo_unittests.filter +++ b/testing/buildbot/filters/fuchsia.mojo_unittests.filter
@@ -4,10 +4,6 @@ -MessagePipeTest.ClosePipesStressTest -MessageTest.ExtendMessagePayloadLarge -# These tests require support for named channels. See crbug.com/754038. --MultiprocessMessagePipeTestWithPeerSupport*/2 --MultiprocessMessagePipeTestWithPeerSupport*/3 - # crbug.com/780317 - These timeout under QEMU s/w emulation of ARM64. -MultiprocessMessagePipeTestWithPeerSupport.PingPongPipe* -MessagePipeTest.SharedBufferHandlePingPong
diff --git a/testing/buildbot/filters/webui_polymer2_browser_tests.filter b/testing/buildbot/filters/webui_polymer2_browser_tests.filter index 20c2820..f44478c 100644 --- a/testing/buildbot/filters/webui_polymer2_browser_tests.filter +++ b/testing/buildbot/filters/webui_polymer2_browser_tests.filter
@@ -189,6 +189,7 @@ FileManagerPathUtilConvertUrlTest.* FileManagerUITest.* FileTasksBrowserTest.* +*/FilesAppBrowserTest.* GalleryBrowserTest.* GalleryBrowserTestInGuestMode.* GalleryJsTest.* @@ -279,7 +280,6 @@ SigninSyncConfirmationTest.* SiteEngagementBrowserTest.* SysInternalsBrowserTest.* -TabIndex/FilesAppBrowserTest.* TextDefaultsTest.* TtsAccessibilityTest.* UserManagerBrowserTest.*
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 94f77fcd..0b20114 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -694,13 +694,6 @@ "--enable-features=AutofillManualFallback", ], }, - "ios_chrome_payments_egtests": { - "label": "//ios/chrome/test/earl_grey:ios_chrome_payments_egtests", - "type": "raw", - "args": [ - "--enable-features=WebPayments", - ], - }, "ios_chrome_reading_list_egtests": { "label": "//ios/chrome/test/earl_grey:ios_chrome_reading_list_egtests", "type": "raw",
diff --git a/testing/buildbot/manage.py b/testing/buildbot/manage.py index 2767a32..09133545 100755 --- a/testing/buildbot/manage.py +++ b/testing/buildbot/manage.py
@@ -96,7 +96,6 @@ 'ios_chrome_bookmarks_egtests', 'ios_chrome_integration_egtests', 'ios_chrome_manual_fill_egtests', - 'ios_chrome_payments_egtests', 'ios_chrome_reading_list_egtests', 'ios_chrome_settings_egtests', 'ios_chrome_smoke_egtests',
diff --git a/testing/buildbot/tryserver.webrtc.json b/testing/buildbot/tryserver.webrtc.json index 375922ca..b57d1b6 100644 --- a/testing/buildbot/tryserver.webrtc.json +++ b/testing/buildbot/tryserver.webrtc.json
@@ -8,7 +8,8 @@ "content_browsertests", "content_unittests", "jingle_unittests", - "remoting_unittests" + "remoting_unittests", + "webkit_unit_tests" ] }, "linux_chromium_compile": { @@ -19,7 +20,8 @@ "content_unittests", "jingle_unittests", "remoting_unittests", - "remoting/webapp:webapp" + "remoting/webapp:webapp", + "webkit_unit_tests" ] }, "mac_chromium_compile": { @@ -30,7 +32,8 @@ "content_unittests", "jingle_unittests", "remoting_unittests", - "remoting/webapp:webapp" + "remoting/webapp:webapp", + "webkit_unit_tests" ] }, "win_chromium_compile": { @@ -41,7 +44,8 @@ "content_unittests", "jingle_unittests", "remoting_unittests", - "remoting/webapp:webapp" + "remoting/webapp:webapp", + "webkit_unit_tests" ] } }
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 6da83ce..f58a0c4 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -3919,6 +3919,7 @@ 'content_unittests', 'jingle_unittests', 'remoting_unittests', + 'webkit_unit_tests', ], }, 'linux_chromium_compile': { @@ -3930,6 +3931,7 @@ 'jingle_unittests', 'remoting_unittests', 'remoting/webapp:webapp', + 'webkit_unit_tests', ], }, 'mac_chromium_compile': { @@ -3941,6 +3943,7 @@ 'jingle_unittests', 'remoting_unittests', 'remoting/webapp:webapp', + 'webkit_unit_tests', ], }, 'win_chromium_compile': { @@ -3952,6 +3955,7 @@ 'jingle_unittests', 'remoting_unittests', 'remoting/webapp:webapp', + 'webkit_unit_tests', ], }, },
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index b44c4f5..f88bb92 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1511,6 +1511,7 @@ crbug.com/249112 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-007.xht [ Skip ] crbug.com/467127 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-008.xht [ Skip ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-009.html [ Skip ] +crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-010.html [ Skip ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-001.xht [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-002.xht [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-003.xht [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/animations/animationworklet/animate-multiple-effects-on-different-targets-via-main-thread-expected.txt b/third_party/WebKit/LayoutTests/animations/animationworklet/animate-multiple-effects-on-different-targets-via-main-thread-expected.txt new file mode 100644 index 0000000..07ff5d8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/animations/animationworklet/animate-multiple-effects-on-different-targets-via-main-thread-expected.txt
@@ -0,0 +1,3 @@ +CONSOLE MESSAGE: line 63: background-color for the first target is: rgb(0, 128, 128) +CONSOLE MESSAGE: line 65: box-shadow for the second target is: rgb(0, 128, 128) 4px 4px 25px 0px +
diff --git a/third_party/WebKit/LayoutTests/animations/animationworklet/animate-multiple-effects-via-main-thread.html b/third_party/WebKit/LayoutTests/animations/animationworklet/animate-multiple-effects-on-different-targets-via-main-thread.html similarity index 69% rename from third_party/WebKit/LayoutTests/animations/animationworklet/animate-multiple-effects-via-main-thread.html rename to third_party/WebKit/LayoutTests/animations/animationworklet/animate-multiple-effects-on-different-targets-via-main-thread.html index 7ac66cf..58418d0 100644 --- a/third_party/WebKit/LayoutTests/animations/animationworklet/animate-multiple-effects-via-main-thread.html +++ b/third_party/WebKit/LayoutTests/animations/animationworklet/animate-multiple-effects-on-different-targets-via-main-thread.html
@@ -19,7 +19,9 @@ <script id="simple_animate" type="text/worklet"> registerAnimator("test_animator", class { animate(currentTime, effect) { - effect.localTime = 1000; + let effects = effect.getChildren(); + effects[0].localTime = 1000; + effects[1].localTime = 1000; } }); </script> @@ -52,38 +54,16 @@ { duration: 2000 } ); - const effect3 = new KeyframeEffect( - document.getElementById("target"), - [ - { width: '100px' }, - { width: '200px' } - ], - { duration: 2000 } - ); - - const effect4 = new KeyframeEffect( - document.getElementById("target2"), - [ - { opacity: 1 }, - { opacity: 0 } - ], - { duration: 2000 } - ); - const animation = new WorkletAnimation('test_animator', - [ effect, effect2, effect3, effect4 ]); + [ effect, effect2 ]); animation.play(); if (window.testRunner) { waitTwoAnimationFrames( _ => { console.log('background-color for the first target is: ' + getComputedStyle(document.getElementById('target')).backgroundColor); - console.log('width for the first target is: ' + - getComputedStyle(document.getElementById('target')).width); console.log('box-shadow for the second target is: ' + getComputedStyle(document.getElementById('target2')).boxShadow); - console.log('opacity for the second target is: ' + - getComputedStyle(document.getElementById('target2')).opacity); testRunner.notifyDone(); }); }
diff --git a/third_party/WebKit/LayoutTests/animations/animationworklet/multiple-effects-on-same-target-driven-by-individual-local-time-expected.txt b/third_party/WebKit/LayoutTests/animations/animationworklet/multiple-effects-on-same-target-driven-by-individual-local-time-expected.txt new file mode 100644 index 0000000..1bc3597e --- /dev/null +++ b/third_party/WebKit/LayoutTests/animations/animationworklet/multiple-effects-on-same-target-driven-by-individual-local-time-expected.txt
@@ -0,0 +1,3 @@ +CONSOLE MESSAGE: line 62: background-color for the first target is: rgb(0, 255, 0) +CONSOLE MESSAGE: line 64: width for the first target is: 150px +
diff --git a/third_party/WebKit/LayoutTests/animations/animationworklet/animate-multiple-effects-via-main-thread.html b/third_party/WebKit/LayoutTests/animations/animationworklet/multiple-effects-on-same-target-driven-by-individual-local-time.html similarity index 65% copy from third_party/WebKit/LayoutTests/animations/animationworklet/animate-multiple-effects-via-main-thread.html copy to third_party/WebKit/LayoutTests/animations/animationworklet/multiple-effects-on-same-target-driven-by-individual-local-time.html index 7ac66cf..e927d98 100644 --- a/third_party/WebKit/LayoutTests/animations/animationworklet/animate-multiple-effects-via-main-thread.html +++ b/third_party/WebKit/LayoutTests/animations/animationworklet/multiple-effects-on-same-target-driven-by-individual-local-time.html
@@ -14,12 +14,13 @@ </style> <div id="target"></div> -<div id="target2"></div> <script id="simple_animate" type="text/worklet"> registerAnimator("test_animator", class { animate(currentTime, effect) { - effect.localTime = 1000; + let effects = effect.getChildren(); + effects[0].localTime = 0; + effects[1].localTime = 1000; } }); </script> @@ -44,15 +45,6 @@ ); const effect2 = new KeyframeEffect( - document.getElementById("target2"), - [ - { boxShadow: '4px 4px 25px #00f' }, - { boxShadow: '4px 4px 25px #0f0' } - ], - { duration: 2000 } - ); - - const effect3 = new KeyframeEffect( document.getElementById("target"), [ { width: '100px' }, @@ -61,17 +53,8 @@ { duration: 2000 } ); - const effect4 = new KeyframeEffect( - document.getElementById("target2"), - [ - { opacity: 1 }, - { opacity: 0 } - ], - { duration: 2000 } - ); - const animation = new WorkletAnimation('test_animator', - [ effect, effect2, effect3, effect4 ]); + [ effect, effect2 ]); animation.play(); if (window.testRunner) { @@ -80,10 +63,6 @@ getComputedStyle(document.getElementById('target')).backgroundColor); console.log('width for the first target is: ' + getComputedStyle(document.getElementById('target')).width); - console.log('box-shadow for the second target is: ' + - getComputedStyle(document.getElementById('target2')).boxShadow); - console.log('opacity for the second target is: ' + - getComputedStyle(document.getElementById('target2')).opacity); testRunner.notifyDone(); }); }
diff --git a/third_party/WebKit/LayoutTests/css3/blending/background-blend-mode-different-image-formats-expected.png b/third_party/WebKit/LayoutTests/css3/blending/background-blend-mode-different-image-formats-expected.png index 94e02a6b..46520bae 100644 --- a/third_party/WebKit/LayoutTests/css3/blending/background-blend-mode-different-image-formats-expected.png +++ b/third_party/WebKit/LayoutTests/css3/blending/background-blend-mode-different-image-formats-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/css3/blending/background-blend-mode-image-image-expected.png b/third_party/WebKit/LayoutTests/css3/blending/background-blend-mode-image-image-expected.png index 260b6a7a..2123608 100644 --- a/third_party/WebKit/LayoutTests/css3/blending/background-blend-mode-image-image-expected.png +++ b/third_party/WebKit/LayoutTests/css3/blending/background-blend-mode-image-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-010.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-010.html new file mode 100644 index 0000000..482c062d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-010.html
@@ -0,0 +1,64 @@ +<!DOCTYPE html> +<title>Tests correct handling of min-height: min-content with dynamic changes</title> +<link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths" title="4.5. Implied Minimum Size of Flex Items" /> +<link rel="author" title="Google Inc." href="http://www.google.com/"> +<link href="support/flexbox.css" rel="stylesheet"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<style> +.container { + height: 300px; + outline: 2px solid black; +} + +.inner +{ + width: 400px; + flex: 1; + background-color: green; +} +#container2 .flexbox > * { flex-basis: 0; } +#container2 .column > * { flex-basis: auto; } +.container .flexbox { min-height: min-content; } +.container > .flexbox { min-height: 0; } +</style> +<script> +function change() { + var container = document.getElementById('container'); + container.offsetHeight; + container.style.height = '80px'; + container = document.getElementById('container2'); + container.offsetHeight; + container.style.height = '80px'; + checkLayout('.container'); +} +</script> +<body onload="change()"> +<p>Green rectangle should be entirely within the black rectangle</p> +<div id="log"></div> +<div id="container" class="container"> + <div class="flexbox column" style="height: 100%;"> + <div class="flexbox flex-one"> + <div class="flexbox column"> + <div class="flexbox column flex-one"> + <div class="inner" data-expected-height="80"> + </div> + </div> + </div> + </div> + </div> +</div> + +<div id="container2" class="container"> + <div class="flexbox column" style="height: 100%;"> + <div class="flexbox flex-one"> + <div class="flexbox column"> + <div class="flexbox column flex-one"> + <div class="inner" data-expected-height="80"> + </div> + </div> + </div> + </div> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize18-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize18-expected.png index 307a323..b16289d8 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize18-expected.png +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize18-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize19-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize19-expected.png index 436dbf16..caf1f2b 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize19-expected.png +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize19-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize21-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize21-expected.png index 307a323..b16289d8 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize21-expected.png +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize21-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize22-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize22-expected.png index 2ccbf0cc..d6a8962 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize22-expected.png +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize22-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/size/contain-and-cover-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/size/contain-and-cover-expected.png index 6eee9d4..d8a7026d 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/size/contain-and-cover-expected.png +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/size/contain-and-cover-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/size/contain-and-cover-zoomed-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/size/contain-and-cover-zoomed-expected.png index 55f3261..a9c7b12 100644 --- a/third_party/WebKit/LayoutTests/fast/backgrounds/size/contain-and-cover-zoomed-expected.png +++ b/third_party/WebKit/LayoutTests/fast/backgrounds/size/contain-and-cover-zoomed-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/hidpi/static/pointerevents/pointerevent_touch-adjustment_click_target.html b/third_party/WebKit/LayoutTests/fast/hidpi/static/pointerevents/pointerevent_touch-adjustment_click_target.html new file mode 100644 index 0000000..a2b8bc1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/hidpi/static/pointerevents/pointerevent_touch-adjustment_click_target.html
@@ -0,0 +1,65 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Touch-generated events should have the same target</title> +<script src="../../../../resources/testharness.js"></script> +<script src="../../../../resources/testharnessreport.js"></script> +<body onload="inject_input()"> +<p>Touch letter 'O' below to run the test. If a "PASS" result appears the test passes, otherwise it fails</p> +<p><a href="#" id="link" style="margin:3px">Link</a> <span id="target">O</span></p> +<div id="log"></div> +</body> +<script> +const target = document.getElementById('target'); +const xPosition = target.offsetLeft + 2; +const yPosition = target.offsetTop + 2; + +async_test(t => { + const link = document.getElementById('link'); + const expectedEventLog = ['pointerdown-link', 'touchstart-link', 'pointerup-link', 'touchend-link', 'click-link']; + const eventLogRecorder = []; + + const eventNames = ['touchstart', 'touchmove', 'touchend', 'pointerdown', 'pointermove', 'pointerup', 'click']; + for (eventName of eventNames) { + document.addEventListener(eventName, t.step_func(event => { + // TouchEvent and PointerEvent should have the same un-adjusted coordinates. + // click event should have coordinates adjusted to link element. + const eventClientX = event.clientX || (event.touches.length > 0 ? event.touches[0].clientX : 0); + const eventClientY = event.clientY || (event.touches.length > 0 ? event.touches[0].clientY : 0); + + if (event.type === 'click') { + assert_equals(document.elementFromPoint(eventClientX, eventClientY), link, + 'click should have clientX/Y adjusted to link.'); + } else if (event.type != 'touchend') { + assert_equals(eventClientX, xPosition, + `${event.type} should have un-adjusted x coordinates.`); + assert_equals(eventClientY, yPosition, + `${event.type} should have un-adjusted y coordinates.`); + } + + // All events should have target adjusted to link. + const targetName = event.target.id || event.target.nodeName || '[null]'; + eventLogRecorder.push(`${event.type}-${targetName}`); + if (event.type === 'click') { + assert_array_equals(eventLogRecorder, expectedEventLog); + t.done(); + } + })); + } +}); +</script> +<script> + function inject_input() { + return new Promise(function(resolve, reject) { + if (window.chrome && chrome.gpuBenchmarking) { + chrome.gpuBenchmarking.pointerActionSequence( [ + {source: 'touch', + actions: [ + { name: 'pointerDown', x: xPosition, y: yPosition }, + { name: 'pointerUp' } + ]}], resolve); + } else { + reject(); + } + }); + } +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/network/failed-request-preview-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/network/failed-request-preview-expected.txt new file mode 100644 index 0000000..0838edb --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/network/failed-request-preview-expected.txt
@@ -0,0 +1,5 @@ +Verifies that network request previews don't have src set when the request fails +request.url(): http://localhost:8000/ +request.failed: true +previewImage.src: +
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/network/failed-request-preview.js b/third_party/WebKit/LayoutTests/http/tests/devtools/network/failed-request-preview.js new file mode 100644 index 0000000..0de3e484 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/network/failed-request-preview.js
@@ -0,0 +1,30 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`Verifies that network request previews don't have src set when the request fails`); + await TestRunner.loadModule('application_test_runner'); + await TestRunner.loadModule('network_test_runner'); + await TestRunner.showPanel('network'); + + SDK.multitargetNetworkManager.setBlockingEnabled(true); + TestRunner.networkManager.addEventListener( + SDK.NetworkManager.Events.RequestFinished, (event) => { + const request = event.data; + TestRunner.addResult('request.url(): ' + request.url()); + TestRunner.addResult('request.failed: ' + request.failed); + + const previewImage = createElementWithClass('img', 'image-network-icon-preview'); + request.populateImageSource(previewImage).then(() => { + TestRunner.addResult('previewImage.src: ' + previewImage.src); + TestRunner.completeTest(); + }); + }); + + SDK.multitargetNetworkManager.setBlockedPatterns([ + {url: '*', enabled: true} + ]); + + NetworkTestRunner.makeXHR('GET', 'http://localhost:8000'); +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/animationworklet-origin-trial-interfaces-worklet-scope-expected.txt b/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/animationworklet-origin-trial-interfaces-worklet-scope-expected.txt index c2476942..33995cd7 100644 --- a/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/animationworklet-origin-trial-interfaces-worklet-scope-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/origin_trials/webexposed/animationworklet-origin-trial-interfaces-worklet-scope-expected.txt
@@ -25,6 +25,9 @@ CONSOLE MESSAGE: line 153: method constructor CONSOLE MESSAGE: line 153: interface WorkletGlobalScope CONSOLE MESSAGE: line 153: method constructor +CONSOLE MESSAGE: line 153: interface WorkletGroupEffectProxy +CONSOLE MESSAGE: line 153: method constructor +CONSOLE MESSAGE: line 153: method getChildren CONSOLE MESSAGE: line 153: interface WritableStream CONSOLE MESSAGE: line 153: getter locked CONSOLE MESSAGE: line 153: method abort
diff --git a/third_party/WebKit/LayoutTests/images/jpeg-yuv-progressive-canvas-expected.png b/third_party/WebKit/LayoutTests/images/jpeg-yuv-progressive-canvas-expected.png index 3bbf755..23438b0 100644 --- a/third_party/WebKit/LayoutTests/images/jpeg-yuv-progressive-canvas-expected.png +++ b/third_party/WebKit/LayoutTests/images/jpeg-yuv-progressive-canvas-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/images/jpeg-yuv-progressive-image-expected.png index 136bf11..fc85a45 100644 --- a/third_party/WebKit/LayoutTests/images/jpeg-yuv-progressive-image-expected.png +++ b/third_party/WebKit/LayoutTests/images/jpeg-yuv-progressive-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/icc-v2-gbr-420-height-not-whole-mcu.jpg b/third_party/WebKit/LayoutTests/images/resources/icc-v2-gbr-420-height-not-whole-mcu.jpg new file mode 100644 index 0000000..c85a236 --- /dev/null +++ b/third_party/WebKit/LayoutTests/images/resources/icc-v2-gbr-420-height-not-whole-mcu.jpg Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/icc-v2-gbr-420-width-not-whole-mcu.jpg b/third_party/WebKit/LayoutTests/images/resources/icc-v2-gbr-420-width-not-whole-mcu.jpg new file mode 100644 index 0000000..fc5bc164 --- /dev/null +++ b/third_party/WebKit/LayoutTests/images/resources/icc-v2-gbr-420-width-not-whole-mcu.jpg Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/icc-v2-gbr-422-whole-mcus.jpg b/third_party/WebKit/LayoutTests/images/resources/icc-v2-gbr-422-whole-mcus.jpg new file mode 100644 index 0000000..5cdeb3c0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/images/resources/icc-v2-gbr-422-whole-mcus.jpg Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/android/http/tests/origin_trials/webexposed/animationworklet-origin-trial-interfaces-worklet-scope-expected.txt b/third_party/WebKit/LayoutTests/platform/android/http/tests/origin_trials/webexposed/animationworklet-origin-trial-interfaces-worklet-scope-expected.txt index d07266d..6cde39f 100644 --- a/third_party/WebKit/LayoutTests/platform/android/http/tests/origin_trials/webexposed/animationworklet-origin-trial-interfaces-worklet-scope-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/android/http/tests/origin_trials/webexposed/animationworklet-origin-trial-interfaces-worklet-scope-expected.txt
@@ -25,6 +25,9 @@ CONSOLE MESSAGE: line 151: method constructor CONSOLE MESSAGE: line 151: interface WorkletGlobalScope CONSOLE MESSAGE: line 151: method constructor +CONSOLE MESSAGE: line 153: interface WorkletGroupEffectProxy +CONSOLE MESSAGE: line 153: method constructor +CONSOLE MESSAGE: line 153: method getChildren CONSOLE MESSAGE: line 151: interface WritableStream CONSOLE MESSAGE: line 151: getter locked CONSOLE MESSAGE: line 151: method abort
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/size/contain-and-cover-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/size/contain-and-cover-expected.png index b75d1616..a8784384 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/size/contain-and-cover-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/size/contain-and-cover-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/animate-elem-39-t-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/animate-elem-39-t-expected.png index ea3d4171..a0a9ef4 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/animate-elem-39-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/animate-elem-39-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-viewattr-02-b-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-viewattr-02-b-expected.png index 6f76cd9..dc78de88 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-viewattr-02-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-viewattr-02-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/carto.net/selectionlist-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/carto.net/selectionlist-expected.png index 4599d87..c8c2c8e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/carto.net/selectionlist-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/carto.net/selectionlist-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/image-rescale-clip-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/image-rescale-clip-expected.png index b4e57b2d..71983dd 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/image-rescale-clip-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/image-rescale-clip-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/image-rescale-scroll-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/image-rescale-scroll-expected.png index 28b9bc8..ba7f258e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/image-rescale-scroll-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/image-rescale-scroll-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug101674-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug101674-expected.png index 5127861..aa25797 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug101674-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug101674-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug11026-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug11026-expected.png index 3be7a63..d17ff81a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug11026-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug11026-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4284-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4284-expected.png index 8e11e44b..bc83055 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4284-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4284-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4427-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4427-expected.png index 170ee2c..4a0b8ed 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4427-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug4427-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug625-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug625-expected.png index e2c14cdd..3912c50 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug625-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug625-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/core/bloomberg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/core/bloomberg-expected.png index 6edf690..8f10d11e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/core/bloomberg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/core/bloomberg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png deleted file mode 100644 index f550526..0000000 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png deleted file mode 100644 index f550526..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla/core/bloomberg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla/core/bloomberg-expected.png index 9626ece3..7c0a096142 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla/core/bloomberg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla/core/bloomberg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png deleted file mode 100644 index f550526..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png deleted file mode 100644 index f550526..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png deleted file mode 100644 index f550526..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-39-t-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-39-t-expected.png index c6704e4..ddae108 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-39-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-39-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-viewattr-02-b-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-viewattr-02-b-expected.png index 2dec00e..e174cf6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-viewattr-02-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-viewattr-02-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/carto.net/selectionlist-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/carto.net/selectionlist-expected.png index 14efad6..404e509 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/carto.net/selectionlist-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/carto.net/selectionlist-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/image-rescale-clip-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/image-rescale-clip-expected.png index de9687d..25f75b0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/image-rescale-clip-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/image-rescale-clip-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/image-rescale-scroll-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/image-rescale-scroll-expected.png index f8a10e88..2009544 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/image-rescale-scroll-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/image-rescale-scroll-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug101674-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug101674-expected.png index 1945054..a4c7cdd 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug101674-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug101674-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug11026-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug11026-expected.png index e98efd4..76b09fc 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug11026-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug11026-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4284-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4284-expected.png index 64a5b14..8a86a2b5 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4284-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4284-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4427-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4427-expected.png index 01d6cc8..97cdd585 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4427-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug4427-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug625-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug625-expected.png index cc918b77..1721820 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug625-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug625-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/core/bloomberg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/core/bloomberg-expected.png index 10a657e..b465b5187 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/core/bloomberg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/core/bloomberg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png deleted file mode 100644 index f550526..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/animate-elem-39-t-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/animate-elem-39-t-expected.png index 30547917..d78d28c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/animate-elem-39-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/animate-elem-39-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/coords-viewattr-02-b-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/coords-viewattr-02-b-expected.png index a2cf71ec..3d78dc78 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/coords-viewattr-02-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/coords-viewattr-02-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/carto.net/selectionlist-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/carto.net/selectionlist-expected.png index 7e6a3de..90b6f6b6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/carto.net/selectionlist-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/carto.net/selectionlist-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/image-rescale-clip-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/image-rescale-clip-expected.png index 39c667e..a69cb76 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/image-rescale-clip-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/image-rescale-clip-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/image-rescale-scroll-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/image-rescale-scroll-expected.png index 51633f1e..e7d91f46 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/image-rescale-scroll-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/image-rescale-scroll-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug101674-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug101674-expected.png index eb316b4..f4e1f57 100644 --- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug101674-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug101674-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug11026-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug11026-expected.png index 9a17ac31..0efcc81 100644 --- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug11026-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug11026-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4284-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4284-expected.png index e62d9ea..aef9ca7b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4284-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4284-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4427-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4427-expected.png index 1456ac4..bafd960f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4427-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug4427-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug625-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug625-expected.png index 49c6740..d087485 100644 --- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug625-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug625-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/core/bloomberg-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/core/bloomberg-expected.png index 46cd39a..da1b5fd0 100644 --- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/core/bloomberg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/core/bloomberg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png deleted file mode 100644 index f550526..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png deleted file mode 100644 index f550526..0000000 --- a/third_party/WebKit/LayoutTests/platform/win7/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/jpeg-yuv-progressive-canvas-expected.png b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/jpeg-yuv-progressive-canvas-expected.png index 3cb69e14..3be3edb 100644 --- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/jpeg-yuv-progressive-canvas-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/jpeg-yuv-progressive-canvas-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/jpeg-yuv-progressive-image-expected.png index 8b345df30..9d38684 100644 --- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/jpeg-yuv-progressive-image-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/jpeg-yuv-progressive-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/exif-orientation-height-image-document-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/exif-orientation-height-image-document-expected.png index 55ef4be0..4ebe79a 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/exif-orientation-height-image-document-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/exif-orientation-height-image-document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png index 42913af6..2143db1 100644 --- a/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png +++ b/third_party/WebKit/LayoutTests/virtual/gpu-rasterization/images/jpeg-yuv-progressive-image-expected.png Binary files differ
diff --git a/third_party/blink/public/platform/web_coalesced_input_event.h b/third_party/blink/public/platform/web_coalesced_input_event.h index 19653c8..6488167 100644 --- a/third_party/blink/public/platform/web_coalesced_input_event.h +++ b/third_party/blink/public/platform/web_coalesced_input_event.h
@@ -33,6 +33,11 @@ const WebInputEvent& CoalescedEvent(size_t index) const; std::vector<const WebInputEvent*> GetCoalescedEventsPointers() const; + void AddPredictedEvent(const blink::WebInputEvent&); + size_t PredictedEventSize() const; + const WebInputEvent& PredictedEvent(size_t index) const; + std::vector<const WebInputEvent*> GetPredictedEventsPointers() const; + private: // TODO(hans): Remove this once clang-cl knows to not inline dtors that // call operator(), https://crbug.com/691714 @@ -47,6 +52,7 @@ WebScopedInputEvent event_; std::vector<WebScopedInputEvent> coalesced_events_; + std::vector<WebScopedInputEvent> predicted_events_; }; using WebScopedCoalescedInputEvent = std::unique_ptr<WebCoalescedInputEvent>;
diff --git a/third_party/blink/public/web/web_widget.h b/third_party/blink/public/web/web_widget.h index ece3c3fc..5e96a0e 100644 --- a/third_party/blink/public/web/web_widget.h +++ b/third_party/blink/public/web/web_widget.h
@@ -63,6 +63,11 @@ class WebWidget { public: + // Called during set up of the WebWidget to declare the WebLayerTreeView for + // the widget to use. This does not pass ownership, but the caller must keep + // the pointer valid until Close() is called. + virtual void SetLayerTreeView(WebLayerTreeView*) = 0; + // This method closes and deletes the WebWidget. virtual void Close() {}
diff --git a/third_party/blink/public/web/web_widget_client.h b/third_party/blink/public/web/web_widget_client.h index 9e8c537..fb95d331 100644 --- a/third_party/blink/public/web/web_widget_client.h +++ b/third_party/blink/public/web/web_widget_client.h
@@ -64,12 +64,6 @@ // Called when a region of the WebWidget needs to be re-painted. virtual void DidInvalidateRect(const WebRect&) {} - // Initializes the layer compositor for the widget, returning a pointer - // to the newly constructed LayerTreeView that provides access to the - // compositor, which is owned by the WebWidgetClient. Will return null if - // AllowsBrokenNullLayerTreeView() is true. - virtual WebLayerTreeView* InitializeLayerTreeView() = 0; - // FIXME: Remove all overrides of this. virtual bool AllowsBrokenNullLayerTreeView() const { return false; }
diff --git a/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc b/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc index ef15fb17..64036ac 100644 --- a/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc
@@ -23,9 +23,9 @@ v8::Isolate* isolate) { Vector<scoped_refptr<DOMWrapperWorld>> worlds; worlds.push_back(DOMWrapperWorld::EnsureIsolatedWorld( - isolate, DOMWrapperWorld::WorldId::kMainWorldId + 1)); + isolate, DOMWrapperWorld::kMainWorldId + 1)); worlds.push_back(DOMWrapperWorld::EnsureIsolatedWorld( - isolate, DOMWrapperWorld::WorldId::kIsolatedWorldIdLimit - 1)); + isolate, DOMWrapperWorld::kDOMWrapperWorldEmbedderWorldIdLimit - 1)); EXPECT_TRUE(worlds[0]->IsIsolatedWorld()); EXPECT_TRUE(worlds[1]->IsIsolatedWorld()); return worlds;
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.cc b/third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.cc index ac84407..10efc8b6 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.cc
@@ -4,22 +4,19 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h" + namespace blink { -v8::Local<v8::Object> V8IteratorResultValue(v8::Isolate* isolate, +v8::Local<v8::Object> V8IteratorResultValue(ScriptState* script_state, bool done, v8::Local<v8::Value> value) { - v8::Local<v8::Object> result = v8::Object::New(isolate); if (value.IsEmpty()) - value = v8::Undefined(isolate); - if (!V8CallBoolean(result->CreateDataProperty( - isolate->GetCurrentContext(), V8AtomicString(isolate, "done"), - v8::Boolean::New(isolate, done))) || - !V8CallBoolean( - result->CreateDataProperty(isolate->GetCurrentContext(), - V8AtomicString(isolate, "value"), value))) - return v8::Local<v8::Object>(); - return result; + value = v8::Undefined(script_state->GetIsolate()); + return V8ObjectBuilder(script_state) + .Add("done", done) + .Add("value", value) + .V8Value(); } v8::MaybeLocal<v8::Value> V8UnpackIteratorResult(ScriptState* script_state,
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h b/third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h index 0c5c246..6d376489 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h +++ b/third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h
@@ -15,7 +15,7 @@ // "Iterator result" in this file is an object returned from iterator.next() // having two members "done" and "value". -CORE_EXPORT v8::Local<v8::Object> V8IteratorResultValue(v8::Isolate*, +CORE_EXPORT v8::Local<v8::Object> V8IteratorResultValue(ScriptState*, bool done, v8::Local<v8::Value>); @@ -28,7 +28,7 @@ inline ScriptValue V8IteratorResult(ScriptState* script_state, const T& value) { return ScriptValue( script_state, - V8IteratorResultValue(script_state->GetIsolate(), false, + V8IteratorResultValue(script_state, false, ToV8(value, script_state->GetContext()->Global(), script_state->GetIsolate()))); } @@ -36,7 +36,7 @@ inline ScriptValue V8IteratorResultDone(ScriptState* script_state) { return ScriptValue( script_state, - V8IteratorResultValue(script_state->GetIsolate(), true, + V8IteratorResultValue(script_state, true, v8::Undefined(script_state->GetIsolate()))); }
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc index a164dc1..8bd506f 100644 --- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc +++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -313,7 +313,8 @@ DCHECK_EQ(popup_client_->OwnerElement().GetDocument().ExistingAXObjectCache(), frame->GetDocument()->ExistingAXObjectCache()); - InitializeLayerTreeView(); + layer_tree_view_->SetVisible(true); + page_->LayerTreeViewInitialized(*layer_tree_view_, nullptr); scoped_refptr<SharedBuffer> data = SharedBuffer::Create(); popup_client_->WriteDocument(data.get()); @@ -324,6 +325,15 @@ SetFocus(true); } +void WebPagePopupImpl::SetLayerTreeView(WebLayerTreeView* layer_tree_view) { + // The WebWidgetClient is given |this| as its WebWidget but it is set up + // before Initialize() is called on |this|. So we store the |layer_tree_view| + // here, but finish setting it up in Initialize(). + layer_tree_view_ = layer_tree_view; + animation_host_ = std::make_unique<CompositorAnimationHost>( + layer_tree_view_->CompositorAnimationHost()); +} + void WebPagePopupImpl::PostMessageToPopup(const String& message) { if (!page_) return; @@ -369,15 +379,6 @@ } } -void WebPagePopupImpl::InitializeLayerTreeView() { - TRACE_EVENT0("blink", "WebPagePopupImpl::InitializeLayerTreeView"); - layer_tree_view_ = widget_client_->InitializeLayerTreeView(); - layer_tree_view_->SetVisible(true); - animation_host_ = std::make_unique<CompositorAnimationHost>( - layer_tree_view_->CompositorAnimationHost()); - page_->LayerTreeViewInitialized(*layer_tree_view_, nullptr); -} - void WebPagePopupImpl::SetSuppressFrameRequestsWorkaroundFor704763Only( bool suppress_frame_requests) { if (!page_)
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.h b/third_party/blink/renderer/core/exported/web_page_popup_impl.h index da5171d..d954c8654 100644 --- a/third_party/blink/renderer/core/exported/web_page_popup_impl.h +++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.h
@@ -82,6 +82,7 @@ private: // WebWidget functions + void SetLayerTreeView(WebLayerTreeView*) override; void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final; void BeginFrame(base::TimeTicks last_frame_time) override; void UpdateLifecycle(LifecycleUpdate requested_update) override; @@ -116,7 +117,6 @@ explicit WebPagePopupImpl(WebWidgetClient*); void DestroyPage(); - void InitializeLayerTreeView(); void SetRootLayer(cc::Layer*); WebRect WindowRectInScreen() const;
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index b428d92..ce20989d 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -349,15 +349,10 @@ // they avoid the compositor by using a null client, and sometimes by having // the client return a null compositor. We should make things more consistent // and clear. - if (WidgetClient()) { - if (WidgetClient()->AllowsBrokenNullLayerTreeView()) { - // For some reason this was not set when WidgetClient() is not provided, - // even though there will be no LayerTreeView in that case either. - page_->GetSettings().SetAcceleratedCompositingEnabled(false); - } else { - InitializeLayerTreeView(); - } - } + // For some reason this was not set when WidgetClient() is not provided, + // even though there will be no LayerTreeView in that case either. + if (WidgetClient() && WidgetClient()->AllowsBrokenNullLayerTreeView()) + page_->GetSettings().SetAcceleratedCompositingEnabled(false); dev_tools_emulator_ = DevToolsEmulator::Create(this); @@ -3269,8 +3264,8 @@ client_->WidgetClient()->ScheduleAnimation(); } -void WebViewImpl::InitializeLayerTreeView() { - layer_tree_view_ = WidgetClient()->InitializeLayerTreeView(); +void WebViewImpl::SetLayerTreeView(WebLayerTreeView* layer_tree_view) { + layer_tree_view_ = layer_tree_view; if (Platform::Current()->IsThreadedAnimationEnabled()) { animation_host_ = std::make_unique<CompositorAnimationHost>( layer_tree_view_->CompositorAnimationHost());
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index c4837e1..8b0bde13 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -108,6 +108,7 @@ static bool UseExternalPopupMenus(); // WebWidget methods: + void SetLayerTreeView(WebLayerTreeView*) override; void Close() override; WebSize Size() override; void Resize(const WebSize&) override; @@ -491,8 +492,6 @@ void ConfigureAutoResizeMode(); - void InitializeLayerTreeView(); - void SetIsAcceleratedCompositingActive(bool); void DoComposite(); void ReallocateRenderer();
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc index 31893ff..9a892c7 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -3717,13 +3717,9 @@ // correctly is the job of LayoutTests/fast/events/event-handler-count.html. TEST_F(WebViewTest, HasTouchEventHandlers) { TouchEventHandlerWebWidgetClient client; - // We need to create a LayerTreeView for the client before loading the page, - // otherwise ChromeClient will default to assuming there are touch handlers. - WebLayerTreeView* layer_tree_view = client.InitializeLayerTreeView(); std::string url = RegisterMockedHttpURLLoad("has_touch_event_handlers.html"); WebViewImpl* web_view_impl = web_view_helper_.InitializeAndLoad(url, nullptr, nullptr, &client); - ASSERT_TRUE(layer_tree_view); const EventHandlerRegistry::EventHandlerClass kTouchEvent = EventHandlerRegistry::kTouchStartOrMoveEventBlocking;
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.cc b/third_party/blink/renderer/core/frame/frame_test_helpers.cc index 92d1bd3d..db8201b2 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.cc +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.cc
@@ -91,14 +91,14 @@ } // Helper to create a default test client if the supplied client pointer is -// null. +// null. The |owned_client| is used to store the client if it must be created. +// In both cases the client to be used is returned. template <typename T> -std::unique_ptr<T> CreateDefaultClientIfNeeded(T*& client) { +T* CreateDefaultClientIfNeeded(T* client, std::unique_ptr<T>& owned_client) { if (client) - return nullptr; - auto owned_client = std::make_unique<T>(); - client = owned_client.get(); - return owned_client; + return client; + owned_client = std::make_unique<T>(); + return owned_client.get(); } std::unique_ptr<WebNavigationParams> BuildDummyNavigationParams() { @@ -179,8 +179,8 @@ WebLocalFrameImpl* CreateLocalChild(WebLocalFrame& parent, WebTreeScopeType scope, TestWebFrameClient* client) { - std::unique_ptr<TestWebFrameClient> owned_client = - CreateDefaultClientIfNeeded(client); + std::unique_ptr<TestWebFrameClient> owned_client; + client = CreateDefaultClientIfNeeded(client, owned_client); WebLocalFrameImpl* frame = ToWebLocalFrameImpl(parent.CreateLocalChild(scope, client, nullptr)); client->Bind(frame, std::move(owned_client)); @@ -201,8 +201,8 @@ WebLocalFrameImpl* CreateProvisional(WebRemoteFrame& old_frame, TestWebFrameClient* client) { - std::unique_ptr<TestWebFrameClient> owned_client = - CreateDefaultClientIfNeeded(client); + std::unique_ptr<TestWebFrameClient> owned_client; + client = CreateDefaultClientIfNeeded(client, owned_client); WebLocalFrameImpl* frame = ToWebLocalFrameImpl(WebLocalFrame::CreateProvisional( client, nullptr, &old_frame, WebSandboxFlags::kNone, @@ -220,14 +220,17 @@ WebFrameWidget* frame_widget = WebFrameWidget::CreateForChildLocalRoot(widget_client.get(), frame); frame_widget->Resize(WebSize()); + // The WebWidget requires a LayerTreeView to be set, either by the + // WebWidgetClient itself or by someone else. We do that here. + frame_widget->SetLayerTreeView(widget_client->layer_tree_view()); client->BindWidgetClient(std::move(widget_client)); } return frame; } WebRemoteFrameImpl* CreateRemote(TestWebRemoteFrameClient* client) { - std::unique_ptr<TestWebRemoteFrameClient> owned_client = - CreateDefaultClientIfNeeded(client); + std::unique_ptr<TestWebRemoteFrameClient> owned_client; + client = CreateDefaultClientIfNeeded(client, owned_client); auto* frame = WebRemoteFrameImpl::Create(WebTreeScopeType::kDocument, client); client->Bind(frame, std::move(owned_client)); return frame; @@ -239,19 +242,24 @@ WebFrame* previous_sibling, TestWebFrameClient* client, TestWebWidgetClient* widget_client) { - std::unique_ptr<TestWebFrameClient> owned_client = - CreateDefaultClientIfNeeded(client); + std::unique_ptr<TestWebFrameClient> owned_client; + client = CreateDefaultClientIfNeeded(client, owned_client); WebLocalFrameImpl* frame = ToWebLocalFrameImpl(parent.CreateLocalChild( WebTreeScopeType::kDocument, name, WebSandboxFlags::kNone, client, nullptr, previous_sibling, ParsedFeaturePolicy(), properties, nullptr)); client->Bind(frame, std::move(owned_client)); - std::unique_ptr<TestWebWidgetClient> owned_widget_client = - CreateDefaultClientIfNeeded(widget_client); - WebFrameWidget::CreateForChildLocalRoot(widget_client, frame); + std::unique_ptr<TestWebWidgetClient> owned_widget_client; + widget_client = + CreateDefaultClientIfNeeded(widget_client, owned_widget_client); + WebFrameWidget* frame_widget = + WebFrameWidget::CreateForChildLocalRoot(widget_client, frame); // Set an initial size for subframes. if (frame->Parent()) - frame->FrameWidget()->Resize(WebSize()); + frame_widget->Resize(WebSize()); + // The WebWidget requires a LayerTreeView to be set, either by the + // WebWidgetClient itself or by someone else. We do that here. + frame_widget->SetLayerTreeView(widget_client->layer_tree_view()); client->BindWidgetClient(std::move(owned_widget_client)); return frame; } @@ -261,8 +269,8 @@ const WebString& name, scoped_refptr<SecurityOrigin> security_origin, TestWebRemoteFrameClient* client) { - std::unique_ptr<TestWebRemoteFrameClient> owned_client = - CreateDefaultClientIfNeeded(client); + std::unique_ptr<TestWebRemoteFrameClient> owned_client; + client = CreateDefaultClientIfNeeded(client, owned_client); auto* frame = ToWebRemoteFrameImpl(parent.CreateRemoteChild( WebTreeScopeType::kDocument, name, WebSandboxFlags::kNone, ParsedFeaturePolicy(), client, nullptr)); @@ -292,8 +300,9 @@ if (update_settings_func) update_settings_func(web_view_->GetSettings()); - std::unique_ptr<TestWebFrameClient> owned_web_frame_client = - CreateDefaultClientIfNeeded(web_frame_client); + std::unique_ptr<TestWebFrameClient> owned_web_frame_client; + web_frame_client = + CreateDefaultClientIfNeeded(web_frame_client, owned_web_frame_client); WebLocalFrame* frame = WebLocalFrame::CreateMainFrame( web_view_, web_frame_client, nullptr, opener); web_frame_client->Bind(frame, std::move(owned_web_frame_client)); @@ -342,8 +351,9 @@ InitializeWebView(web_view_client, nullptr); - std::unique_ptr<TestWebRemoteFrameClient> owned_web_remote_frame_client = - CreateDefaultClientIfNeeded(web_remote_frame_client); + std::unique_ptr<TestWebRemoteFrameClient> owned_web_remote_frame_client; + web_remote_frame_client = CreateDefaultClientIfNeeded( + web_remote_frame_client, owned_web_remote_frame_client); WebRemoteFrameImpl* frame = WebRemoteFrameImpl::CreateMainFrame( web_view_, web_remote_frame_client, nullptr); web_remote_frame_client->Bind(frame, @@ -387,7 +397,8 @@ void WebViewHelper::InitializeWebView(TestWebViewClient* web_view_client, class WebView* opener) { - owned_test_web_view_client_ = CreateDefaultClientIfNeeded(web_view_client); + web_view_client = + CreateDefaultClientIfNeeded(web_view_client, owned_test_web_view_client_); web_view_ = static_cast<WebViewImpl*>( WebView::Create(web_view_client, web_view_client, mojom::PageVisibilityState::kVisible, opener)); @@ -399,6 +410,8 @@ // // Consequently, all external image resources must be mocked. web_view_->GetSettings()->SetLoadsImagesAutomatically(true); + + web_view_->SetLayerTreeView(web_view_client->layer_tree_view()); web_view_->SetDeviceScaleFactor( web_view_client->GetScreenInfo().device_scale_factor); web_view_->SetDefaultPageScaleLimits(1, 4); @@ -507,13 +520,12 @@ return layer_tree_view_.get(); } -WebLayerTreeView* TestWebWidgetClient::InitializeLayerTreeView() { - return layer_tree_view_factory_.Initialize(); +TestWebWidgetClient::TestWebWidgetClient() { + layer_tree_view_ = layer_tree_view_factory_.Initialize(); } -WebLayerTreeView* TestWebViewClient::InitializeLayerTreeView() { - layer_tree_view_ = layer_tree_view_factory_.Initialize(); - return layer_tree_view_; +TestWebViewClient::TestWebViewClient(content::LayerTreeViewDelegate* delegate) { + layer_tree_view_ = layer_tree_view_factory_.Initialize(delegate); } } // namespace FrameTestHelpers
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.h b/third_party/blink/renderer/core/frame/frame_test_helpers.h index d0ad38a..fe7b16c 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.h +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.h
@@ -180,23 +180,25 @@ class TestWebWidgetClient : public WebWidgetClient { public: + TestWebWidgetClient(); ~TestWebWidgetClient() override = default; - // WebWidgetClient: - WebLayerTreeView* InitializeLayerTreeView() override; + content::LayerTreeView* layer_tree_view() { return layer_tree_view_; } private: + content::LayerTreeView* layer_tree_view_ = nullptr; LayerTreeViewFactory layer_tree_view_factory_; }; class TestWebViewClient : public WebViewClient, public WebWidgetClient { public: + // If no delegate is given, a stub is used. + explicit TestWebViewClient(content::LayerTreeViewDelegate* = nullptr); ~TestWebViewClient() override = default; content::LayerTreeView* layer_tree_view() { return layer_tree_view_; } // WebWidgetClient: - WebLayerTreeView* InitializeLayerTreeView() override; void ScheduleAnimation() override { animation_scheduled_ = true; } // WebViewClient:
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index c37c6a6b..6606792 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -560,8 +560,6 @@ } void WebFrameWidgetImpl::Initialize() { - InitializeLayerTreeView(); - if (LocalRoot()->Parent()) SetBackgroundColorOverride(Color::kTransparent); } @@ -1043,11 +1041,10 @@ return document->FocusedElement(); } -void WebFrameWidgetImpl::InitializeLayerTreeView() { +void WebFrameWidgetImpl::SetLayerTreeView(WebLayerTreeView* layer_tree_view) { DCHECK(Client()); DCHECK(!mutator_dispatcher_); - layer_tree_view_ = Client()->InitializeLayerTreeView(); - DCHECK(layer_tree_view_); + layer_tree_view_ = layer_tree_view; if (Platform::Current()->IsThreadedAnimationEnabled()) { animation_host_ = std::make_unique<CompositorAnimationHost>( layer_tree_view_->CompositorAnimationHost());
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h index e1979d2..5d215256 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
@@ -134,6 +134,7 @@ // WebFrameWidgetBase overrides: void Initialize() override; + void SetLayerTreeView(WebLayerTreeView*) override; bool ForSubframe() const override { return true; } void ScheduleAnimation() override; void IntrinsicSizingInfoChanged(const IntrinsicSizingInfo&) override; @@ -170,8 +171,6 @@ HitTestResult HitTestResultForRootFramePos( const LayoutPoint& pos_in_root_frame); - void InitializeLayerTreeView(); - void SetIsAcceleratedCompositingActive(bool); void UpdateLayerTreeViewport(); void UpdateLayerTreeBackgroundColor();
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 68c60ee..2ab2d4ae 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -689,7 +689,7 @@ const WebScriptSource& source_in) { DCHECK(GetFrame()); CHECK_GT(world_id, 0); - CHECK_LT(world_id, DOMWrapperWorld::kEmbedderWorldIdLimit); + CHECK_LT(world_id, DOMWrapperWorld::kDOMWrapperWorldEmbedderWorldIdLimit); // Note: An error event in an isolated world will never be dispatched to // a foreign world. @@ -704,7 +704,7 @@ const WebScriptSource& source_in) { DCHECK(GetFrame()); CHECK_GT(world_id, 0); - CHECK_LT(world_id, DOMWrapperWorld::kEmbedderWorldIdLimit); + CHECK_LT(world_id, DOMWrapperWorld::kDOMWrapperWorldEmbedderWorldIdLimit); // Note: An error event in an isolated world will never be dispatched to // a foreign world. @@ -850,7 +850,7 @@ WebScriptExecutionCallback* callback) { DCHECK(GetFrame()); CHECK_GT(world_id, 0); - CHECK_LT(world_id, DOMWrapperWorld::kEmbedderWorldIdLimit); + CHECK_LT(world_id, DOMWrapperWorld::kDOMWrapperWorldEmbedderWorldIdLimit); scoped_refptr<DOMWrapperWorld> isolated_world = DOMWrapperWorld::EnsureIsolatedWorld(ToIsolate(GetFrame()), world_id);
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc index 17729d3c..41899703 100644 --- a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc +++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
@@ -185,6 +185,12 @@ web_view_->SetCompositorVisibility(true); } +void WebViewFrameWidget::SetLayerTreeView(WebLayerTreeView*) { + // The WebViewImpl already has its LayerTreeView, the WebWidgetClient + // thus does not initialize and set another one here. + NOTREACHED(); +} + void WebViewFrameWidget::ScheduleAnimation() { web_view_->ScheduleAnimationForWidget(); }
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.h b/third_party/blink/renderer/core/frame/web_view_frame_widget.h index 0bb0d8b7..af2734d 100644 --- a/third_party/blink/renderer/core/frame/web_view_frame_widget.h +++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.h
@@ -85,6 +85,7 @@ // WebFrameWidgetBase overrides: void Initialize() override; + void SetLayerTreeView(WebLayerTreeView*) override; bool ForSubframe() const override { return false; } void ScheduleAnimation() override; base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index 833ea0c..30424f3 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -258,9 +258,9 @@ SetSuggestedOption(nullptr); if (is_autofilled_by_preview_) SetAutofillState(WebAutofillState::kNotFilled); - SelectOptionFlags flags = kDeselectOtherOptions | kMakeOptionDirty; + SelectOptionFlags flags = kDeselectOtherOptionsFlag | kMakeOptionDirtyFlag; if (send_events) - flags |= kDispatchInputAndChangeEvent; + flags |= kDispatchInputAndChangeEventFlag; SelectOption(option, flags); if (send_events && previous_selected_option != option && !UsesMenuList()) @@ -826,7 +826,7 @@ SelectOption(first_enabled_option, reason == kResetReasonSelectedOptionRemoved ? 0 - : kDeselectOtherOptions); + : kDeselectOtherOptionsFlag); last_selected_option = first_enabled_option; did_change = true; } @@ -857,7 +857,7 @@ } void HTMLSelectElement::setSelectedIndex(int index) { - SelectOption(item(index), kDeselectOtherOptions | kMakeOptionDirty); + SelectOption(item(index), kDeselectOtherOptionsFlag | kMakeOptionDirtyFlag); } int HTMLSelectElement::SelectedListIndex() const { @@ -919,9 +919,9 @@ bool option_is_selected) { DCHECK_EQ(option->OwnerSelectElement(), this); if (option_is_selected) - SelectOption(option, IsMultiple() ? 0 : kDeselectOtherOptions); + SelectOption(option, IsMultiple() ? 0 : kDeselectOtherOptionsFlag); else if (!UsesMenuList() || IsMultiple()) - SelectOption(nullptr, IsMultiple() ? 0 : kDeselectOtherOptions); + SelectOption(nullptr, IsMultiple() ? 0 : kDeselectOtherOptionsFlag); else ResetToDefaultSelection(); } @@ -931,7 +931,7 @@ DCHECK_EQ(option.OwnerSelectElement(), this); SetRecalcListItems(); if (option_is_selected) { - SelectOption(&option, IsMultiple() ? 0 : kDeselectOtherOptions); + SelectOption(&option, IsMultiple() ? 0 : kDeselectOtherOptionsFlag); } else { // No need to reset if we already have a selected option. if (!last_on_change_option_) @@ -1009,12 +1009,12 @@ if (!element->Selected()) should_update_popup = true; element->SetSelectedState(true); - if (flags & kMakeOptionDirty) + if (flags & kMakeOptionDirtyFlag) element->SetDirty(true); } // DeselectItemsWithoutValidation() is O(N). - if (flags & kDeselectOtherOptions) + if (flags & kDeselectOtherOptionsFlag) should_update_popup |= DeselectItemsWithoutValidation(element); // We should update active selection after finishing OPTION state change @@ -1022,10 +1022,10 @@ if (element) { // setActiveSelectionAnchor is O(N). if (!active_selection_anchor_ || !IsMultiple() || - flags & kDeselectOtherOptions) + flags & kDeselectOtherOptionsFlag) SetActiveSelectionAnchor(element); if (!active_selection_end_ || !IsMultiple() || - flags & kDeselectOtherOptions) + flags & kDeselectOtherOptionsFlag) SetActiveSelectionEnd(element); } @@ -1033,7 +1033,7 @@ // LayoutMenuList::UpdateFromElement. bool should_dispatch_events = false; if (UsesMenuList()) { - should_dispatch_events = (flags & kDispatchInputAndChangeEvent) && + should_dispatch_events = (flags & kDispatchInputAndChangeEventFlag) && last_on_change_option_ != element; last_on_change_option_ = element; } @@ -1163,7 +1163,7 @@ if (items_size == 0) return; - SelectOption(nullptr, kDeselectOtherOptions); + SelectOption(nullptr, kDeselectOtherOptionsFlag); // The saved state should have at least one value and an index. DCHECK_GE(state.ValueSize(), 2u); @@ -1222,7 +1222,7 @@ // WebKit. However Edge seems to "ask for a reset" simply. As of 2016 // March, the HTML specification says nothing about this. if (old_selected_option) - SelectOption(old_selected_option, kDeselectOtherOptions); + SelectOption(old_selected_option, kDeselectOtherOptionsFlag); else ResetToDefaultSelection(); } @@ -1345,8 +1345,8 @@ handled = false; if (handled && option) { - SelectOption(option, kDeselectOtherOptions | kMakeOptionDirty | - kDispatchInputAndChangeEvent); + SelectOption(option, kDeselectOtherOptionsFlag | kMakeOptionDirtyFlag | + kDispatchInputAndChangeEventFlag); } if (handled) @@ -1770,9 +1770,9 @@ event, TypeAhead::kMatchPrefix | TypeAhead::kCycleFirstChar); if (index < 0) return; - SelectOption(OptionAtListIndex(index), kDeselectOtherOptions | - kMakeOptionDirty | - kDispatchInputAndChangeEvent); + SelectOption(OptionAtListIndex(index), kDeselectOtherOptionsFlag | + kMakeOptionDirtyFlag | + kDispatchInputAndChangeEventFlag); if (!UsesMenuList()) ListBoxOnChange(); } @@ -1787,8 +1787,8 @@ EventQueueScope scope; // If this index is already selected, unselect. otherwise update the // selected index. - SelectOptionFlags flags = - kDispatchInputAndChangeEvent | (IsMultiple() ? 0 : kDeselectOtherOptions); + SelectOptionFlags flags = kDispatchInputAndChangeEventFlag | + (IsMultiple() ? 0 : kDeselectOtherOptionsFlag); if (option->Selected()) { if (UsesMenuList()) SelectOption(nullptr, flags); @@ -1951,8 +1951,8 @@ // the selected option is not change. if (option == SelectedOption()) return; - SelectOption(option, kDeselectOtherOptions | kMakeOptionDirty | - kDispatchInputAndChangeEvent); + SelectOption(option, kDeselectOtherOptionsFlag | kMakeOptionDirtyFlag | + kDispatchInputAndChangeEventFlag); } void HTMLSelectElement::PopupDidCancel() {
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.h b/third_party/blink/renderer/core/html/forms/html_select_element.h index eab2da2..9199c12 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.h +++ b/third_party/blink/renderer/core/html/forms/html_select_element.h
@@ -233,9 +233,9 @@ bool HasPlaceholderLabelOption() const; enum SelectOptionFlag { - kDeselectOtherOptions = 1 << 0, - kDispatchInputAndChangeEvent = 1 << 1, - kMakeOptionDirty = 1 << 2, + kDeselectOtherOptionsFlag = 1 << 0, + kDispatchInputAndChangeEventFlag = 1 << 1, + kMakeOptionDirtyFlag = 1 << 2, }; typedef unsigned SelectOptionFlags; void SelectOption(HTMLOptionElement*, SelectOptionFlags);
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc index f939223..160d74b 100644 --- a/third_party/blink/renderer/core/input/event_handler.cc +++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -1752,7 +1752,8 @@ touch_adjustment_result_.adjusted_point); } else { hit_rect_size = GetHitTestRectForAdjustment( - LayoutSize(adjusted_event.TapAreaInRootFrame())); + LayoutSize(adjusted_event.TapAreaInRootFrame()), + frame_->PageZoomFactor()); if (!hit_rect_size.IsEmpty()) hit_type |= HitTestRequest::kListBased; }
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.cc b/third_party/blink/renderer/core/input/pointer_event_manager.cc index 2faa7369..6da95a6 100644 --- a/third_party/blink/renderer/core/input/pointer_event_manager.cc +++ b/third_party/blink/renderer/core/input/pointer_event_manager.cc
@@ -326,7 +326,8 @@ WebPointerProperties::PointerType::kTouch); LayoutSize hit_rect_size = GetHitTestRectForAdjustment( - LayoutSize(pointer_event.width, pointer_event.height)); + LayoutSize(pointer_event.width, pointer_event.height), + frame_->PageZoomFactor()); if (hit_rect_size.IsEmpty()) return;
diff --git a/third_party/blink/renderer/core/layout/layout_block.h b/third_party/blink/renderer/core/layout/layout_block.h index fb9ba1b..211c556 100644 --- a/third_party/blink/renderer/core/layout/layout_block.h +++ b/third_party/blink/renderer/core/layout/layout_block.h
@@ -449,11 +449,11 @@ private: void AddVisualOverflowFromBlockChildren(); - void AddVisualOverflowFromTheme(); void AddLayoutOverflowFromPositionedObjects(); void AddLayoutOverflowFromBlockChildren(); protected: + void AddVisualOverflowFromTheme(); virtual void ComputeVisualOverflow( const LayoutRect& previous_visual_overflow_rect, bool recompute_floats); @@ -461,7 +461,7 @@ bool recompute_floats); virtual void AddLayoutOverflowFromChildren(); - virtual void AddVisualOverflowFromChildren(); + void AddVisualOverflowFromChildren(); void AddOutlineRects(Vector<LayoutRect>&, const LayoutPoint& additional_offset,
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc index 163847a8d..bf9be92a 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow.cc +++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -2566,11 +2566,20 @@ void LayoutBlockFlow::ComputeVisualOverflow( const LayoutRect& previous_visual_overflow_rect, bool recompute_floats) { - LayoutBlock::ComputeVisualOverflow(previous_visual_overflow_rect, - recompute_floats); + AddVisualOverflowFromChildren(); + + AddVisualEffectOverflow(); + AddVisualOverflowFromTheme(); + if (recompute_floats || CreatesNewFormattingContext() || HasSelfPaintingLayer()) AddVisualOverflowFromFloats(); + + if (VisualOverflowRect() != previous_visual_overflow_rect) { + if (Layer()) + Layer()->SetNeedsCompositingInputsUpdate(); + GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired); + } } void LayoutBlockFlow::ComputeLayoutOverflow(LayoutUnit old_client_after_edge,
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index b1ea5be..6ac0179 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -3181,7 +3181,12 @@ DISABLE_CFI_PERF void LayoutBox::UpdateLogicalHeight() { - intrinsic_content_logical_height_ = ContentLogicalHeight(); + if (!HasOverrideLogicalHeight()) { + // If we have an override height, our children will have sized themselves + // relative to our override height, which would make our intrinsic size + // incorrect (too big). + intrinsic_content_logical_height_ = ContentLogicalHeight(); + } LogicalExtentComputedValues computed_values; ComputeLogicalHeight(computed_values);
diff --git a/third_party/blink/renderer/core/layout/layout_list_item.cc b/third_party/blink/renderer/core/layout/layout_list_item.cc index f2a7ed1..a729d66 100644 --- a/third_party/blink/renderer/core/layout/layout_list_item.cc +++ b/third_party/blink/renderer/core/layout/layout_list_item.cc
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/layout/layout_list_marker.h" #include "third_party/blink/renderer/core/paint/list_item_painter.h" +#include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/platform/wtf/saturated_arithmetic.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -289,6 +290,25 @@ return false; } +void LayoutListItem::ComputeVisualOverflow( + const LayoutRect& previous_visual_overflow_rect, + bool recompute_floats) { + AddVisualOverflowFromChildren(); + + AddVisualEffectOverflow(); + AddVisualOverflowFromTheme(); + + if (recompute_floats || CreatesNewFormattingContext() || + HasSelfPaintingLayer()) + AddVisualOverflowFromFloats(); + + if (VisualOverflowRect() != previous_visual_overflow_rect) { + if (Layer()) + Layer()->SetNeedsCompositingInputsUpdate(); + GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired); + } +} + void LayoutListItem::AddVisualOverflowFromChildren() { LayoutBlockFlow::AddVisualOverflowFromChildren(); UpdateOverflow(Visual);
diff --git a/third_party/blink/renderer/core/layout/layout_list_item.h b/third_party/blink/renderer/core/layout/layout_list_item.h index e180df75..e0d7736 100644 --- a/third_party/blink/renderer/core/layout/layout_list_item.h +++ b/third_party/blink/renderer/core/layout/layout_list_item.h
@@ -70,7 +70,9 @@ void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override; - void AddVisualOverflowFromChildren() override; + void ComputeVisualOverflow(const LayoutRect&, bool recompute_floats) final; + + void AddVisualOverflowFromChildren(); void AddLayoutOverflowFromChildren() override; void AlignMarkerInBlockDirection();
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_set.cc b/third_party/blink/renderer/core/layout/layout_multi_column_set.cc index a7ae137..0adaeba0 100644 --- a/third_party/blink/renderer/core/layout/layout_multi_column_set.cc +++ b/third_party/blink/renderer/core/layout/layout_multi_column_set.cc
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h" #include "third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h" #include "third_party/blink/renderer/core/paint/multi_column_set_painter.h" +#include "third_party/blink/renderer/core/paint/paint_layer.h" namespace blink { @@ -520,6 +521,25 @@ return result; } +void LayoutMultiColumnSet::ComputeVisualOverflow( + const LayoutRect& previous_visual_overflow_rect, + bool recompute_floats) { + AddVisualOverflowFromChildren(); + + AddVisualEffectOverflow(); + AddVisualOverflowFromTheme(); + + if (recompute_floats || CreatesNewFormattingContext() || + HasSelfPaintingLayer()) + AddVisualOverflowFromFloats(); + + if (VisualOverflowRect() != previous_visual_overflow_rect) { + if (Layer()) + Layer()->SetNeedsCompositingInputsUpdate(); + GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired); + } +} + void LayoutMultiColumnSet::AddVisualOverflowFromChildren() { // It's useless to calculate overflow if we haven't determined the page // logical height yet.
diff --git a/third_party/blink/renderer/core/layout/layout_multi_column_set.h b/third_party/blink/renderer/core/layout/layout_multi_column_set.h index 8dbe3d27..8e66f98 100644 --- a/third_party/blink/renderer/core/layout/layout_multi_column_set.h +++ b/third_party/blink/renderer/core/layout/layout_multi_column_set.h
@@ -255,7 +255,9 @@ void PaintObject(const PaintInfo&, const LayoutPoint& paint_offset) const override; - void AddVisualOverflowFromChildren() override; + void ComputeVisualOverflow(const LayoutRect&, bool recompute_floats) final; + + void AddVisualOverflowFromChildren(); void AddLayoutOverflowFromChildren() override; MultiColumnFragmentainerGroupList fragmentainer_groups_;
diff --git a/third_party/blink/renderer/core/layout/layout_table.cc b/third_party/blink/renderer/core/layout/layout_table.cc index d6e1978c..410930b5 100644 --- a/third_party/blink/renderer/core/layout/layout_table.cc +++ b/third_party/blink/renderer/core/layout/layout_table.cc
@@ -910,6 +910,21 @@ } } +void LayoutTable::ComputeVisualOverflow( + const LayoutRect& previous_visual_overflow_rect, + bool recompute_floats) { + AddVisualOverflowFromChildren(); + + AddVisualEffectOverflow(); + AddVisualOverflowFromTheme(); + + if (VisualOverflowRect() != previous_visual_overflow_rect) { + if (Layer()) + Layer()->SetNeedsCompositingInputsUpdate(); + GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired); + } +} + void LayoutTable::AddVisualOverflowFromChildren() { // Add overflow from borders. // Technically it's odd that we are incorporating the borders into layout
diff --git a/third_party/blink/renderer/core/layout/layout_table.h b/third_party/blink/renderer/core/layout/layout_table.h index 48af1bc..983880a8 100644 --- a/third_party/blink/renderer/core/layout/layout_table.h +++ b/third_party/blink/renderer/core/layout/layout_table.h
@@ -474,7 +474,9 @@ OverlayScrollbarClipBehavior = kIgnorePlatformOverlayScrollbarSize) const override; - void AddVisualOverflowFromChildren() override; + void ComputeVisualOverflow(const LayoutRect&, bool recompute_floats) final; + + void AddVisualOverflowFromChildren(); void AddLayoutOverflowFromChildren() override; void RecalcSections() const;
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc b/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc index 79a43d1..086ca24f23 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc +++ b/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc
@@ -34,6 +34,7 @@ #include "third_party/blink/renderer/core/layout/hit_test_result.h" #include "third_party/blink/renderer/core/layout/layout_analyzer.h" #include "third_party/blink/renderer/core/layout/layout_theme.h" +#include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/text_control_single_line_painter.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" @@ -317,4 +318,23 @@ return ToHTMLInputElement(GetNode()); } +void LayoutTextControlSingleLine::ComputeVisualOverflow( + const LayoutRect& previous_visual_overflow_rect, + bool recompute_floats) { + AddVisualOverflowFromChildren(); + + AddVisualEffectOverflow(); + AddVisualOverflowFromTheme(); + + if (recompute_floats || CreatesNewFormattingContext() || + HasSelfPaintingLayer()) + AddVisualOverflowFromFloats(); + + if (VisualOverflowRect() != previous_visual_overflow_rect) { + if (Layer()) + Layer()->SetNeedsCompositingInputsUpdate(); + GetFrameView()->SetIntersectionObservationState(LocalFrameView::kDesired); + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_single_line.h b/third_party/blink/renderer/core/layout/layout_text_control_single_line.h index 9132a9e..66c2a232 100644 --- a/third_party/blink/renderer/core/layout/layout_text_control_single_line.h +++ b/third_party/blink/renderer/core/layout/layout_text_control_single_line.h
@@ -78,10 +78,11 @@ LayoutUnit line_height, LayoutUnit non_content_height) const override; + void ComputeVisualOverflow(const LayoutRect&, bool recompute_floats) override; + // If the INPUT content height is smaller than the font height, the // inner-editor element overflows the INPUT box intentionally, however it // shouldn't affect outside of the INPUT box. So we ignore child overflow. - void AddVisualOverflowFromChildren() final {} void AddLayoutOverflowFromChildren() final {} bool AllowsOverflowClip() const override { return false; }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc index 94888b4..813b7b0 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -888,12 +888,12 @@ NGBfcOffset origin_bfc_offset = {ConstraintSpace().BfcOffset().line_offset, bfc_block_offset + content_size}; - const NGPositionedFloatVector positioned_floats = - PositionFloats(ConstraintSpace().AvailableSize(), - ConstraintSpace().PercentageResolutionSize(), - ConstraintSpace().ReplacedPercentageResolutionSize(), - origin_bfc_offset, bfc_block_offset, unpositioned_floats_, - ConstraintSpace(), exclusion_space); + NGPositionedFloatVector positioned_floats; + PositionFloats(ConstraintSpace().AvailableSize(), + ConstraintSpace().PercentageResolutionSize(), + ConstraintSpace().ReplacedPercentageResolutionSize(), + origin_bfc_offset, bfc_block_offset, unpositioned_floats_, + ConstraintSpace(), exclusion_space, &positioned_floats); positioned_floats_.AppendVector(positioned_floats); unpositioned_floats_.clear();
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc index d5f95c5..68530841 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
@@ -19,6 +19,7 @@ #include "third_party/blink/renderer/core/layout/ng/ng_relative_utils.h" #include "third_party/blink/renderer/core/paint/ng/ng_block_flow_painter.h" #include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h" +#include "third_party/blink/renderer/core/paint/paint_layer.h" namespace blink { @@ -66,6 +67,21 @@ } template <typename Base> +void LayoutNGMixin<Base>::ComputeVisualOverflow( + const LayoutRect& previous_visual_overflow_rect, + bool recompute_floats) { + Base::ComputeVisualOverflow(previous_visual_overflow_rect, recompute_floats); + AddVisualOverflowFromChildren(); + + if (Base::VisualOverflowRect() != previous_visual_overflow_rect) { + if (Base::Layer()) + Base::Layer()->SetNeedsCompositingInputsUpdate(); + Base::GetFrameView()->SetIntersectionObservationState( + LocalFrameView::kDesired); + } +} + +template <typename Base> void LayoutNGMixin<Base>::AddVisualOverflowFromChildren() { // |ComputeOverflow()| calls this, which is called from // |CopyFragmentDataToLayoutBox()| and |RecalcOverflowAfterStyleChange()|.
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h index 477d924..d1c60bd1 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h
@@ -83,7 +83,9 @@ protected: bool IsOfType(LayoutObject::LayoutObjectType) const override; - void AddVisualOverflowFromChildren() final; + void ComputeVisualOverflow(const LayoutRect&, bool recompute_floats) final; + + void AddVisualOverflowFromChildren(); void AddLayoutOverflowFromChildren() final; private:
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc index 708eabe1..feac6a1 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -2081,10 +2081,11 @@ ? container_builder_.BfcBlockOffset().value() : ConstraintSpace().FloatsBfcBlockOffset().value(); - const auto positioned_floats = PositionFloats( - child_available_size_, child_percentage_size_, - replaced_child_percentage_size_, origin_bfc_offset, bfc_block_offset, - unpositioned_floats_, ConstraintSpace(), &exclusion_space_); + NGPositionedFloatVector positioned_floats; + PositionFloats(child_available_size_, child_percentage_size_, + replaced_child_percentage_size_, origin_bfc_offset, + bfc_block_offset, unpositioned_floats_, ConstraintSpace(), + &exclusion_space_, &positioned_floats); AddPositionedFloats(positioned_floats);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc index 972033d..6437050 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -214,12 +214,6 @@ } return layout_result; } - // Cached fragment was stale. Its fragment children might point to - // deleted LayoutObjects. - // Removing cached result to ensure that stale children cannot be - // reached through LayoutNGMixin::CurrentFragment. - if (box_->NeedsLayout()) - ToLayoutBlockFlow(box_)->ClearCachedLayoutResult(); } // This follows the code from LayoutBox::UpdateLogicalWidth
diff --git a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h index 43fc62a..163f62d 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
@@ -87,8 +87,8 @@ return *this; } - virtual NGContainerFragmentBuilder& AddChild(const NGLayoutResult&, - const NGLogicalOffset&); + NGContainerFragmentBuilder& AddChild(const NGLayoutResult&, + const NGLogicalOffset&); // This version of AddChild will not propagate floats/out_of_flow. // Use the AddChild(NGLayoutResult) variant if NGLayoutResult is available.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc index 6e4315d..49df543 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_floats_utils.cc
@@ -306,26 +306,24 @@ return NGPositionedFloat(std::move(layout_result), float_bfc_offset); } -const NGPositionedFloatVector PositionFloats( - const NGLogicalSize& float_available_size, - const NGLogicalSize& float_percentage_size, - const NGLogicalSize& float_replaced_percentage_size, - const NGBfcOffset& origin_bfc_offset, - LayoutUnit parent_bfc_block_offset, - NGUnpositionedFloatVector& unpositioned_floats, - const NGConstraintSpace& space, - NGExclusionSpace* exclusion_space) { - NGPositionedFloatVector positioned_floats; - positioned_floats.ReserveCapacity(unpositioned_floats.size()); +void PositionFloats(const NGLogicalSize& float_available_size, + const NGLogicalSize& float_percentage_size, + const NGLogicalSize& float_replaced_percentage_size, + const NGBfcOffset& origin_bfc_offset, + LayoutUnit parent_bfc_block_offset, + NGUnpositionedFloatVector& unpositioned_floats, + const NGConstraintSpace& space, + NGExclusionSpace* exclusion_space, + NGPositionedFloatVector* positioned_floats) { + positioned_floats->ReserveCapacity(positioned_floats->size() + + unpositioned_floats.size()); for (NGUnpositionedFloat& unpositioned_float : unpositioned_floats) { - positioned_floats.push_back(PositionFloat( + positioned_floats->push_back(PositionFloat( float_available_size, float_percentage_size, float_replaced_percentage_size, origin_bfc_offset, parent_bfc_block_offset, &unpositioned_float, space, exclusion_space)); } - - return positioned_floats; } void AddUnpositionedFloat(NGUnpositionedFloatVector* unpositioned_floats,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h b/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h index dd1c017..ffcc9b5 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h +++ b/third_party/blink/renderer/core/layout/ng/ng_floats_utils.h
@@ -53,15 +53,16 @@ // Positions the list of {@code unpositioned_floats}. Adds them as exclusions to // {@code space}. -CORE_EXPORT const NGPositionedFloatVector -PositionFloats(const NGLogicalSize& float_available_size, - const NGLogicalSize& float_percentage_size, - const NGLogicalSize& float_replaced_percentage_size, - const NGBfcOffset& origin_bfc_offset, - LayoutUnit container_block_offset, - NGUnpositionedFloatVector& unpositioned_floats, - const NGConstraintSpace& space, - NGExclusionSpace* exclusion_space); +CORE_EXPORT void PositionFloats( + const NGLogicalSize& float_available_size, + const NGLogicalSize& float_percentage_size, + const NGLogicalSize& float_replaced_percentage_size, + const NGBfcOffset& origin_bfc_offset, + LayoutUnit container_block_offset, + NGUnpositionedFloatVector& unpositioned_floats, + const NGConstraintSpace& space, + NGExclusionSpace* exclusion_space, + NGPositionedFloatVector* positioned_floats); // Add a pending float to the list. It will be committed (positioned) once we // have resolved the BFC block offset.
diff --git a/third_party/blink/renderer/core/page/touch_adjustment.cc b/third_party/blink/renderer/core/page/touch_adjustment.cc index a218191..5e009e44 100644 --- a/third_party/blink/renderer/core/page/touch_adjustment.cc +++ b/third_party/blink/renderer/core/page/touch_adjustment.cc
@@ -44,7 +44,8 @@ namespace touch_adjustment { const float kZeroTolerance = 1e-6f; -constexpr float kMaxAdjustmentSizeDips = 32.f; +// The maximum adjustment range (diameters) in css pixel. +constexpr float kMaxAdjustmentSize = 32.f; // Class for remembering absolute quads of a target node and what node they // represent. @@ -513,10 +514,11 @@ subtargets, touch_adjustment::HybridDistanceFunction); } -LayoutSize GetHitTestRectForAdjustment(const LayoutSize& touch_area) { - const LayoutSize max_size(touch_adjustment::kMaxAdjustmentSizeDips, - touch_adjustment::kMaxAdjustmentSizeDips); - return touch_area.ShrunkTo(max_size); +LayoutSize GetHitTestRectForAdjustment(const LayoutSize& touch_area, + float zoom_factor) { + const LayoutSize max_size(touch_adjustment::kMaxAdjustmentSize, + touch_adjustment::kMaxAdjustmentSize); + return touch_area.ShrunkTo(max_size * zoom_factor); } } // namespace blink
diff --git a/third_party/blink/renderer/core/page/touch_adjustment.h b/third_party/blink/renderer/core/page/touch_adjustment.h index 3c4f06d..44f4a30 100644 --- a/third_party/blink/renderer/core/page/touch_adjustment.h +++ b/third_party/blink/renderer/core/page/touch_adjustment.h
@@ -43,7 +43,11 @@ const IntRect& touch_area, const HeapVector<Member<Node>>&); -LayoutSize GetHitTestRectForAdjustment(const LayoutSize& touch_area); +// Applies an upper bound to the touch area as the adjustment rect. The +// touch_area is in root frame coordinates, which is in physical pixel when +// zoom-for-dsf is enabled, otherwise in dip (when page scale is 1). +LayoutSize GetHitTestRectForAdjustment(const LayoutSize& touch_area, + float zoom_factor); struct TouchAdjustmentResult { uint32_t unique_event_id;
diff --git a/third_party/blink/renderer/core/testing/sim/sim_compositor.cc b/third_party/blink/renderer/core/testing/sim/sim_compositor.cc index 30850ca..71b4296 100644 --- a/third_party/blink/renderer/core/testing/sim/sim_compositor.cc +++ b/third_party/blink/renderer/core/testing/sim/sim_compositor.cc
@@ -23,19 +23,17 @@ SimCompositor::SimCompositor() { LocalFrameView::SetInitialTracksPaintInvalidationsForTesting(true); - - // SimCompositor overrides the LayerTreeViewDelegate to respond to - // BeginMainFrame(), which will update and paint the WebViewImpl given to - // SetWebView(). - layer_tree_view_ = layer_tree_view_factory_.Initialize(this); } SimCompositor::~SimCompositor() { LocalFrameView::SetInitialTracksPaintInvalidationsForTesting(false); } -void SimCompositor::SetWebView(WebViewImpl& web_view) { +void SimCompositor::SetWebView(WebViewImpl& web_view, + content::LayerTreeView& layer_tree_view) { web_view_ = &web_view; + layer_tree_view_ = &layer_tree_view; + DCHECK_EQ(&layer_tree_view, web_view_->LayerTreeView()); // SimCompositor starts with defer commits enabled, but uses synchronous // compositing which does not use defer commits anyhow, it only uses it for
diff --git a/third_party/blink/renderer/core/testing/sim/sim_compositor.h b/third_party/blink/renderer/core/testing/sim/sim_compositor.h index e1b033ee..b50f5478 100644 --- a/third_party/blink/renderer/core/testing/sim/sim_compositor.h +++ b/third_party/blink/renderer/core/testing/sim/sim_compositor.h
@@ -28,17 +28,18 @@ // Note: This also does not support compositor driven animations. class SimCompositor final : public content::StubLayerTreeViewDelegate { public: - explicit SimCompositor(); + SimCompositor(); ~SimCompositor() override; // This compositor should be given to the WebViewImpl passed to SetWebView. content::LayerTreeView& layer_tree_view() { return *layer_tree_view_; } // When the compositor asks for a main frame, this WebViewImpl will have its - // lifecycle updated and be painted. The compositor() should have also been - // given to the WebViewImpl so that its using the same compositor() for its - // layer tree. - void SetWebView(WebViewImpl&); + // lifecycle updated and be painted. The WebLayerTreeView that is being used + // to composite the WebViewImpl is passed separately as the underlying + // content::LayerTreeView type, in order to bypass the Web* API surface + // provided to blink. + void SetWebView(WebViewImpl&, content::LayerTreeView&); // Executes the BeginMainFrame processing steps, an approximation of what // cc::ThreadProxy::BeginMainFrame would do. @@ -93,7 +94,6 @@ SimCanvas::Commands* paint_commands_; content::LayerTreeView* layer_tree_view_ = nullptr; - FrameTestHelpers::LayerTreeViewFactory layer_tree_view_factory_; std::unique_ptr<cc::ScopedDeferCommits> scoped_defer_commits_; };
diff --git a/third_party/blink/renderer/core/testing/sim/sim_test.cc b/third_party/blink/renderer/core/testing/sim/sim_test.cc index c6a502e..8a3e27e6 100644 --- a/third_party/blink/renderer/core/testing/sim/sim_test.cc +++ b/third_party/blink/renderer/core/testing/sim/sim_test.cc
@@ -18,8 +18,11 @@ namespace blink { SimTest::SimTest() - : web_view_client_(compositor_.layer_tree_view()), - web_frame_client_(*this) { + : web_frame_client_(*this), + // SimCompositor overrides the LayerTreeViewDelegate to respond to + // BeginMainFrame(), which will update and paint the WebViewImpl given to + // SetWebView(). + web_view_client_(&compositor_) { Document::SetThreadedParsingEnabledForTesting(false); // Use the mock theme to get more predictable code paths, this also avoids // the OS callbacks in ScrollAnimatorMac which can schedule frames @@ -53,7 +56,7 @@ Test::SetUp(); web_view_helper_.Initialize(&web_frame_client_, &web_view_client_); - compositor_.SetWebView(WebView()); + compositor_.SetWebView(WebView(), *web_view_client_.layer_tree_view()); page_.SetPage(WebView().GetPage()); }
diff --git a/third_party/blink/renderer/core/testing/sim/sim_test.h b/third_party/blink/renderer/core/testing/sim/sim_test.h index ed38fac..6a4753c 100644 --- a/third_party/blink/renderer/core/testing/sim/sim_test.h +++ b/third_party/blink/renderer/core/testing/sim/sim_test.h
@@ -52,8 +52,8 @@ SimNetwork network_; SimCompositor compositor_; - SimWebViewClient web_view_client_; SimWebFrameClient web_frame_client_; + SimWebViewClient web_view_client_; SimPage page_; FrameTestHelpers::WebViewHelper web_view_helper_;
diff --git a/third_party/blink/renderer/core/testing/sim/sim_web_view_client.cc b/third_party/blink/renderer/core/testing/sim/sim_web_view_client.cc index befdd59..52ba409 100644 --- a/third_party/blink/renderer/core/testing/sim/sim_web_view_client.cc +++ b/third_party/blink/renderer/core/testing/sim/sim_web_view_client.cc
@@ -8,11 +8,8 @@ namespace blink { -SimWebViewClient::SimWebViewClient(content::LayerTreeView& layer_tree_view) - : visually_non_empty_layout_count_(0), - finished_parsing_layout_count_(0), - finished_loading_layout_count_(0), - layer_tree_view_(&layer_tree_view) {} +SimWebViewClient::SimWebViewClient(content::LayerTreeViewDelegate* delegate) + : FrameTestHelpers::TestWebViewClient(delegate) {} void SimWebViewClient::DidMeaningfulLayout( WebMeaningfulLayout meaningful_layout) { @@ -29,10 +26,6 @@ } } -WebLayerTreeView* SimWebViewClient::InitializeLayerTreeView() { - return layer_tree_view_; -} - WebView* SimWebViewClient::CreateView(WebLocalFrame* opener, const WebURLRequest&, const WebWindowFeatures&,
diff --git a/third_party/blink/renderer/core/testing/sim/sim_web_view_client.h b/third_party/blink/renderer/core/testing/sim/sim_web_view_client.h index 0fd8340c..f1a45d1b 100644 --- a/third_party/blink/renderer/core/testing/sim/sim_web_view_client.h +++ b/third_party/blink/renderer/core/testing/sim/sim_web_view_client.h
@@ -7,17 +7,11 @@ #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" -namespace content { -class LayerTreeView; -} - namespace blink { class SimWebViewClient final : public FrameTestHelpers::TestWebViewClient { public: - // The LayerTreeView to be returned from InitializeLayerTreeView() - // must be constructed before this class, and given to it. - explicit SimWebViewClient(content::LayerTreeView&); + explicit SimWebViewClient(content::LayerTreeViewDelegate* delegate); int VisuallyNonEmptyLayoutCount() const { return visually_non_empty_layout_count_; @@ -30,7 +24,6 @@ } // WebViewClient implementation. - WebLayerTreeView* InitializeLayerTreeView() override; WebView* CreateView(WebLocalFrame* opener, const WebURLRequest&, const WebWindowFeatures&, @@ -44,11 +37,10 @@ // WebWidgetClient overrides. void DidMeaningfulLayout(WebMeaningfulLayout) override; - int visually_non_empty_layout_count_; - int finished_parsing_layout_count_; - int finished_loading_layout_count_; + int visually_non_empty_layout_count_ = 0; + int finished_parsing_layout_count_ = 0; + int finished_loading_layout_count_ = 0; - content::LayerTreeView* layer_tree_view_; FrameTestHelpers::WebViewHelper web_view_helper_; };
diff --git a/third_party/blink/renderer/devtools/front_end/network/ResourceWebSocketFrameView.js b/third_party/blink/renderer/devtools/front_end/network/ResourceWebSocketFrameView.js index 526b4c5d..42e8b41 100644 --- a/third_party/blink/renderer/devtools/front_end/network/ResourceWebSocketFrameView.js +++ b/third_party/blink/renderer/devtools/front_end/network/ResourceWebSocketFrameView.js
@@ -81,6 +81,7 @@ const mainContainer = new UI.VBox(); mainContainer.element.appendChild(this._mainToolbar.element); this._dataGrid.asWidget().show(mainContainer.element); + mainContainer.setMinimumSize(0, 72); this._splitWidget.setMainWidget(mainContainer); this._frameEmptyWidget = new UI.EmptyWidget(Common.UIString('Select frame to browse its content.'));
diff --git a/third_party/blink/renderer/devtools/front_end/sdk/NetworkRequest.js b/third_party/blink/renderer/devtools/front_end/sdk/NetworkRequest.js index a00645cc6..e097ea2 100644 --- a/third_party/blink/renderer/devtools/front_end/sdk/NetworkRequest.js +++ b/third_party/blink/renderer/devtools/front_end/sdk/NetworkRequest.js
@@ -1151,12 +1151,13 @@ async populateImageSource(image) { const {content, encoded} = await this.contentData(); let imageSrc = Common.ContentProvider.contentAsDataURL(content, this._mimeType, encoded); - if (imageSrc === null) { + if (imageSrc === null && !this._failed) { const cacheControl = this.responseHeaderValue('cache-control') || ''; if (!cacheControl.includes('no-cache')) imageSrc = this._url; } - image.src = imageSrc; + if (imageSrc !== null) + image.src = imageSrc; } /**
diff --git a/third_party/blink/renderer/modules/animationworklet/BUILD.gn b/third_party/blink/renderer/modules/animationworklet/BUILD.gn index ddde73a..79387e8 100644 --- a/third_party/blink/renderer/modules/animationworklet/BUILD.gn +++ b/third_party/blink/renderer/modules/animationworklet/BUILD.gn
@@ -28,5 +28,7 @@ "worklet_animation.h", "worklet_animation_options.cc", "worklet_animation_options.h", + "worklet_group_effect_proxy.cc", + "worklet_group_effect_proxy.h", ] }
diff --git a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc index c7912c9..4fc5352 100644 --- a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc +++ b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
@@ -25,8 +25,7 @@ WorkletAnimationId id, double current_time, AnimationWorkletDispatcherOutput* result) { - AnimationWorkletDispatcherOutput::AnimationState animation_output( - id, base::nullopt); + AnimationWorkletDispatcherOutput::AnimationState animation_output(id); if (animator->Animate(script_state, current_time, &animation_output)) { result->animations.push_back(std::move(animation_output)); } @@ -66,9 +65,10 @@ Animator* AnimationWorkletGlobalScope::CreateAnimatorFor( int animation_id, const String& name, - WorkletAnimationOptions* options) { + WorkletAnimationOptions* options, + int num_effects) { DCHECK(!animators_.at(animation_id)); - Animator* animator = CreateInstance(name, options); + Animator* animator = CreateInstance(name, options, num_effects); if (!animator) return nullptr; animators_.Set(animation_id, animator); @@ -99,7 +99,8 @@ WorkletAnimationOptions* options = static_cast<WorkletAnimationOptions*>(animation.options.get()); - Animator* animator = CreateAnimatorFor(id, name, options); + Animator* animator = + CreateAnimatorFor(id, name, options, animation.num_effects); if (!animator) continue; @@ -121,10 +122,13 @@ for (const auto& worklet_animation_id : mutator_input.peeked_animations) { int id = worklet_animation_id.animation_id; Animator* animator = animators_.at(id); + if (!animator) + continue; - result->animations.emplace_back( - worklet_animation_id, - animator ? animator->GetLastLocalTime() : base::nullopt); + AnimationWorkletDispatcherOutput::AnimationState animation_output( + worklet_animation_id); + animation_output.local_times = animator->GetLocalTimes(); + result->animations.push_back(animation_output); } return result; @@ -185,7 +189,8 @@ Animator* AnimationWorkletGlobalScope::CreateInstance( const String& name, - WorkletAnimationOptions* options) { + WorkletAnimationOptions* options, + int num_effects) { DCHECK(IsContextThread()); AnimatorDefinition* definition = animator_definitions_.at(name); if (!definition) @@ -206,7 +211,7 @@ .ToLocal(&instance)) return nullptr; - return new Animator(isolate, definition, instance); + return new Animator(isolate, definition, instance, num_effects); } AnimatorDefinition* AnimationWorkletGlobalScope::FindDefinitionForTest(
diff --git a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h index c0ee79b..fbe305d 100644 --- a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h +++ b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h
@@ -56,10 +56,12 @@ void RegisterWithProxyClientIfNeeded(); Animator* CreateInstance(const String& name, - WorkletAnimationOptions* options); + WorkletAnimationOptions* options, + int num_effects); Animator* CreateAnimatorFor(int animation_id, const String& name, - WorkletAnimationOptions* options); + WorkletAnimationOptions* options, + int num_effects); typedef HeapHashMap<String, TraceWrapperMember<AnimatorDefinition>> DefinitionMap; DefinitionMap animator_definitions_;
diff --git a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc index 1b5aea32..6b54362 100644 --- a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc +++ b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope_test.cc
@@ -222,7 +222,7 @@ cc::WorkletAnimationId animation_id = {1, 1}; AnimationWorkletInput state; state.added_and_updated_animations.emplace_back(animation_id, "test", 5000, - nullptr); + nullptr, 1); std::unique_ptr<AnimationWorkletOutput> output = global_scope->Mutate(state); @@ -273,14 +273,14 @@ cc::WorkletAnimationId animation_id = {1, 1}; AnimationWorkletInput state; state.added_and_updated_animations.emplace_back(animation_id, "test", 5000, - nullptr); + nullptr, 1); std::unique_ptr<AnimationWorkletOutput> output = global_scope->Mutate(state); EXPECT_TRUE(output); EXPECT_EQ(output->animations.size(), 1ul); - EXPECT_EQ(output->animations[0].local_time, + EXPECT_EQ(output->animations[0].local_times[0], WTF::TimeDelta::FromMillisecondsD(123)); waitable_event->Signal(); @@ -329,7 +329,7 @@ EXPECT_EQ(global_scope->GetAnimatorsSizeForTest(), 0u); state.added_and_updated_animations.push_back( - {animation_id, "test", 5000, nullptr}); + {animation_id, "test", 5000, nullptr, 1}); EXPECT_EQ(state.added_and_updated_animations.size(), 1u); global_scope->Mutate(state); EXPECT_EQ(global_scope->GetAnimatorsSizeForTest(), 1u); @@ -366,7 +366,7 @@ cc::WorkletAnimationId animation_id = {1, 1}; AnimationWorkletInput state; state.added_and_updated_animations.push_back( - {animation_id, "test", 5000, nullptr}); + {animation_id, "test", 5000, nullptr, 1}); EXPECT_EQ(state.added_and_updated_animations.size(), 1u); global_scope->Mutate(state); EXPECT_EQ(global_scope->GetAnimatorsSizeForTest(), 1u);
diff --git a/third_party/blink/renderer/modules/animationworklet/animator.cc b/third_party/blink/renderer/modules/animationworklet/animator.cc index 5faecda3..a8c3fe61 100644 --- a/third_party/blink/renderer/modules/animationworklet/animator.cc +++ b/third_party/blink/renderer/modules/animationworklet/animator.cc
@@ -15,16 +15,19 @@ Animator::Animator(v8::Isolate* isolate, AnimatorDefinition* definition, - v8::Local<v8::Value> instance) + v8::Local<v8::Value> instance, + int num_effects) : definition_(definition), instance_(isolate, instance), - effect_(new EffectProxy()) {} + group_effect_(new WorkletGroupEffectProxy(num_effects)) { + DCHECK_GE(num_effects, 1); +} Animator::~Animator() = default; void Animator::Trace(blink::Visitor* visitor) { visitor->Trace(definition_); - visitor->Trace(effect_); + visitor->Trace(group_effect_); visitor->Trace(instance_); } @@ -46,8 +49,14 @@ // Prepare arguments (i.e., current time and effect) and pass them to animate // callback. - v8::Local<v8::Value> v8_effect = - ToV8(effect_, script_state->GetContext()->Global(), isolate); + v8::Local<v8::Value> v8_effect; + if (group_effect_->getChildren().size() == 1) { + v8_effect = ToV8(group_effect_->getChildren()[0], + script_state->GetContext()->Global(), isolate); + } else { + v8_effect = + ToV8(group_effect_, script_state->GetContext()->Global(), isolate); + } v8::Local<v8::Value> v8_current_time = ToV8(current_time, script_state->GetContext()->Global(), isolate); @@ -62,8 +71,17 @@ if (block.HasCaught()) return false; - output->local_time = effect_->local_time(); + output->local_times = GetLocalTimes(); return true; } +std::vector<base::Optional<TimeDelta>> Animator::GetLocalTimes() const { + std::vector<base::Optional<TimeDelta>> local_times; + local_times.reserve(group_effect_->getChildren().size()); + for (const auto& effect : group_effect_->getChildren()) { + local_times.push_back(effect->local_time()); + } + return local_times; +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/animationworklet/animator.h b/third_party/blink/renderer/modules/animationworklet/animator.h index c37bf14d..73e8e8c 100644 --- a/third_party/blink/renderer/modules/animationworklet/animator.h +++ b/third_party/blink/renderer/modules/animationworklet/animator.h
@@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_ANIMATOR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_ANIMATOR_H_ -#include "third_party/blink/renderer/modules/animationworklet/effect_proxy.h" +#include "third_party/blink/renderer/modules/animationworklet/worklet_group_effect_proxy.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h" @@ -25,7 +25,10 @@ class Animator final : public GarbageCollectedFinalized<Animator>, public NameClient { public: - Animator(v8::Isolate*, AnimatorDefinition*, v8::Local<v8::Value> instance); + Animator(v8::Isolate*, + AnimatorDefinition*, + v8::Local<v8::Value> instance, + int num_effects); ~Animator(); void Trace(blink::Visitor*); const char* NameInHeapSnapshot() const override { return "Animator"; } @@ -36,9 +39,7 @@ bool Animate(ScriptState*, double current_time, AnimationWorkletDispatcherOutput::AnimationState*); - base::Optional<TimeDelta> GetLastLocalTime() const { - return effect_->local_time(); - } + std::vector<base::Optional<TimeDelta>> GetLocalTimes() const; private: // This object keeps the definition object, and animator instance alive. @@ -46,7 +47,7 @@ TraceWrapperMember<AnimatorDefinition> definition_; TraceWrapperV8Reference<v8::Value> instance_; - Member<EffectProxy> effect_; + Member<WorkletGroupEffectProxy> group_effect_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc index 471ed16..e2a88e5 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc +++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
@@ -291,6 +291,7 @@ for (auto& effect : effects_) { AnimationEffect* target_effect = effect; target_effect->Attach(this); + local_times_.push_back(base::nullopt); } if (timeline_->IsScrollTimeline()) @@ -338,7 +339,7 @@ DestroyCompositorAnimation(); } - local_time_ = base::nullopt; + local_times_.Fill(base::nullopt); start_time_ = base::nullopt; running_on_main_thread_ = false; // TODO(yigu): Because this animation has been detached and will not receive @@ -382,16 +383,18 @@ if (!start_time_) return; - // TODO(crbug.com/756539): For now we use 0 as inherited time for compositor - // worklet animations. Will need to get the inherited time from worklet - // context. - double inherited_time_seconds = 0; + DCHECK_EQ(effects_.size(), local_times_.size()); + for (size_t i = 0; i < effects_.size(); ++i) { + // TODO(crbug.com/756539): For now we use 0 as inherited time for compositor + // worklet animations. Will need to get the inherited time from worklet + // context. + double inherited_time_seconds = 0; - if (local_time_) - inherited_time_seconds = local_time_->InSecondsF(); + if (local_times_[i]) + inherited_time_seconds = local_times_[i]->InSecondsF(); - for (auto& effect : effects_) - effect->UpdateInheritedTime(inherited_time_seconds, reason); + effects_[i]->UpdateInheritedTime(inherited_time_seconds, reason); + } } bool WorkletAnimation::CheckCanStart(String* failure_message) { @@ -573,7 +576,7 @@ input_state->Add( {id_, std::string(animator_name_.Ascii().data(), animator_name_.length()), - current_time, CloneOptions()}); + current_time, CloneOptions(), effects_.size()}); } else if (was_active && is_active) { // Skip if the input time is not changed. if (did_time_change) @@ -587,7 +590,13 @@ void WorkletAnimation::SetOutputState( const AnimationWorkletOutput::AnimationState& state) { DCHECK(state.worklet_animation_id == id_); - local_time_ = state.local_time; + // The local times for composited effects, i.e. not running on main, are + // peeked and set via the main thread. If an animator is not ready upon + // peeking state.local_times will be empty. + DCHECK(local_times_.size() == state.local_times.size() || + !running_on_main_thread_); + for (size_t i = 0; i < state.local_times.size(); ++i) + local_times_[i] = state.local_times[i]; } void WorkletAnimation::Dispose() {
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation.h b/third_party/blink/renderer/modules/animationworklet/worklet_animation.h index 208f368..10536a4eb 100644 --- a/third_party/blink/renderer/modules/animationworklet/worklet_animation.h +++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation.h
@@ -155,7 +155,7 @@ Animation::AnimationPlayState last_play_state_; // Start time in ms. base::Optional<base::TimeDelta> start_time_; - base::Optional<base::TimeDelta> local_time_; + Vector<base::Optional<base::TimeDelta>> local_times_; // We use this to skip updating if current time has not changed since last // update. base::Optional<base::TimeDelta> last_current_time_;
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_group_effect_proxy.cc b/third_party/blink/renderer/modules/animationworklet/worklet_group_effect_proxy.cc new file mode 100644 index 0000000..eeb27d8 --- /dev/null +++ b/third_party/blink/renderer/modules/animationworklet/worklet_group_effect_proxy.cc
@@ -0,0 +1,20 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/animationworklet/worklet_group_effect_proxy.h" + +namespace blink { + +WorkletGroupEffectProxy::WorkletGroupEffectProxy(int num_effects) + : effects_(num_effects) { + for (int i = 0; i < num_effects; ++i) + effects_[i] = new EffectProxy(); +} + +void WorkletGroupEffectProxy::Trace(blink::Visitor* visitor) { + visitor->Trace(effects_); + ScriptWrappable::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_group_effect_proxy.h b/third_party/blink/renderer/modules/animationworklet/worklet_group_effect_proxy.h new file mode 100644 index 0000000..388534c --- /dev/null +++ b/third_party/blink/renderer/modules/animationworklet/worklet_group_effect_proxy.h
@@ -0,0 +1,29 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_WORKLET_GROUP_EFFECT_PROXY_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_WORKLET_GROUP_EFFECT_PROXY_H_ + +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/modules/animationworklet/effect_proxy.h" +#include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class MODULES_EXPORT WorkletGroupEffectProxy : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + explicit WorkletGroupEffectProxy(int num_effects); + HeapVector<Member<EffectProxy>>& getChildren() { return effects_; } + void Trace(blink::Visitor*) override; + + private: + HeapVector<Member<EffectProxy>> effects_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ANIMATIONWORKLET_WORKLET_GROUP_EFFECT_PROXY_H_
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_group_effect_proxy.idl b/third_party/blink/renderer/modules/animationworklet/worklet_group_effect_proxy.idl new file mode 100644 index 0000000..b2fd1ed --- /dev/null +++ b/third_party/blink/renderer/modules/animationworklet/worklet_group_effect_proxy.idl
@@ -0,0 +1,9 @@ +// Copyright 2018 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. +[ + Exposed=AnimationWorklet, + OriginTrialEnabled=AnimationWorklet +] interface WorkletGroupEffectProxy { + sequence<EffectProxy> getChildren(); +};
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index c97681e..2385d4f 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -63,6 +63,7 @@ "animationworklet/animation_worklet_global_scope.idl", "animationworklet/effect_proxy.idl", "animationworklet/worklet_animation.idl", + "animationworklet/worklet_group_effect_proxy.idl", "app_banner/before_install_prompt_event.idl", "background_fetch/background_fetch_event.idl", "background_fetch/background_fetch_fetch.idl",
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc b/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc index e1895c44..890965a 100644 --- a/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc +++ b/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc
@@ -232,11 +232,6 @@ return stream; } -P2PQuicStreamImpl* P2PQuicTransportImpl::CreateOutgoingUnidirectionalStream() { - DCHECK(false); - return nullptr; -} - P2PQuicStreamImpl* P2PQuicTransportImpl::CreateIncomingStream( quic::QuicStreamId id) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h b/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h index 60c85ef..2764b717 100644 --- a/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h +++ b/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h
@@ -110,8 +110,7 @@ // Creates a new outgoing stream. The caller does not own the // stream, so the stream is activated and ownership is moved to the // quic::QuicSession. - P2PQuicStreamImpl* CreateOutgoingBidirectionalStream() override; - P2PQuicStreamImpl* CreateOutgoingUnidirectionalStream() override; + P2PQuicStreamImpl* CreateOutgoingBidirectionalStream(); void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc index 14d1064..0b8e7b8 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc
@@ -4,153 +4,87 @@ #include "third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h" + namespace blink { namespace { -template <typename T> -bool AddPropertyValue(v8::Local<v8::Object>& v8_object, - v8::Isolate* isolate, - T name, - v8::Local<v8::Value> value) { - return V8CallBoolean(v8_object->CreateDataProperty( - isolate->GetCurrentContext(), V8String(isolate, name), value)); -} - -bool AddPropertySequenceOfBooleans(v8::Local<v8::Object>& v8_object, - v8::Isolate* isolate, - WebString name, - const WebVector<int>& web_vector) { - v8::Local<v8::Array> v8_array = v8::Array::New(isolate, web_vector.size()); - for (size_t i = 0; i < web_vector.size(); ++i) { - if (!V8CallBoolean(v8_array->CreateDataProperty( - isolate->GetCurrentContext(), static_cast<uint32_t>(i), - v8::Boolean::New(isolate, static_cast<bool>(web_vector[i]))))) - return false; - } - return AddPropertyValue(v8_object, isolate, name, v8_array); -} - -template <typename T> -bool AddPropertySequenceOfNumbers(v8::Local<v8::Object>& v8_object, - v8::Isolate* isolate, - WebString name, - const WebVector<T>& web_vector) { - v8::Local<v8::Array> v8_array = v8::Array::New(isolate, web_vector.size()); - for (size_t i = 0; i < web_vector.size(); ++i) { - if (!V8CallBoolean(v8_array->CreateDataProperty( - isolate->GetCurrentContext(), static_cast<uint32_t>(i), - v8::Number::New(isolate, static_cast<double>(web_vector[i]))))) - return false; - } - return AddPropertyValue(v8_object, isolate, name, v8_array); -} - -bool AddPropertySequenceOfStrings(v8::Local<v8::Object>& v8_object, - v8::Isolate* isolate, - WebString name, - const WebVector<WebString>& web_vector) { - v8::Local<v8::Array> v8_array = v8::Array::New(isolate, web_vector.size()); - for (size_t i = 0; i < web_vector.size(); ++i) { - if (!V8CallBoolean(v8_array->CreateDataProperty( - isolate->GetCurrentContext(), static_cast<uint32_t>(i), - V8String(isolate, web_vector[i])))) - return false; - } - return AddPropertyValue(v8_object, isolate, name, v8_array); -} - v8::Local<v8::Value> WebRTCStatsToValue(ScriptState* script_state, const WebRTCStats* stats) { - v8::Isolate* isolate = script_state->GetIsolate(); - v8::Local<v8::Object> v8_object = v8::Object::New(isolate); + V8ObjectBuilder builder(script_state); - bool success = true; - success &= AddPropertyValue(v8_object, isolate, "id", - V8String(isolate, stats->Id())); - success &= AddPropertyValue(v8_object, isolate, "timestamp", - v8::Number::New(isolate, stats->Timestamp())); - success &= AddPropertyValue(v8_object, isolate, "type", - V8String(isolate, stats->GetType())); - for (size_t i = 0; i < stats->MembersCount() && success; ++i) { + builder.AddString("id", stats->Id()); + builder.AddNumber("timestamp", stats->Timestamp()); + builder.AddString("type", stats->GetType()); + + auto add_vector = [&builder](const WebString& name, auto web_vector) { + Vector<typename decltype(web_vector)::value_type> vector(web_vector.size()); + std::move(web_vector.begin(), web_vector.end(), vector.begin()); + builder.Add(name, vector); + }; + + for (size_t i = 0; i < stats->MembersCount(); ++i) { std::unique_ptr<WebRTCStatsMember> member = stats->GetMember(i); if (!member->IsDefined()) continue; WebString name = member->GetName(); switch (member->GetType()) { case kWebRTCStatsMemberTypeBool: - success &= - AddPropertyValue(v8_object, isolate, name, - v8::Boolean::New(isolate, member->ValueBool())); + builder.AddBoolean(name, member->ValueBool()); break; case kWebRTCStatsMemberTypeInt32: - success &= AddPropertyValue( - v8_object, isolate, name, - v8::Number::New(isolate, - static_cast<double>(member->ValueInt32()))); + builder.AddNumber(name, static_cast<double>(member->ValueInt32())); break; case kWebRTCStatsMemberTypeUint32: - success &= AddPropertyValue( - v8_object, isolate, name, - v8::Number::New(isolate, - static_cast<double>(member->ValueUint32()))); + builder.AddNumber(name, static_cast<double>(member->ValueUint32())); break; case kWebRTCStatsMemberTypeInt64: - success &= AddPropertyValue( - v8_object, isolate, name, - v8::Number::New(isolate, - static_cast<double>(member->ValueInt64()))); + builder.AddNumber(name, static_cast<double>(member->ValueInt64())); break; case kWebRTCStatsMemberTypeUint64: - success &= AddPropertyValue( - v8_object, isolate, name, - v8::Number::New(isolate, - static_cast<double>(member->ValueUint64()))); + builder.AddNumber(name, static_cast<double>(member->ValueUint64())); break; case kWebRTCStatsMemberTypeDouble: - success &= - AddPropertyValue(v8_object, isolate, name, - v8::Number::New(isolate, member->ValueDouble())); + builder.AddNumber(name, member->ValueDouble()); break; case kWebRTCStatsMemberTypeString: - success &= AddPropertyValue(v8_object, isolate, name, - V8String(isolate, member->ValueString())); + builder.AddString(name, member->ValueString()); break; - case kWebRTCStatsMemberTypeSequenceBool: - success &= AddPropertySequenceOfBooleans(v8_object, isolate, name, - member->ValueSequenceBool()); + case kWebRTCStatsMemberTypeSequenceBool: { + WebVector<int> sequence = member->ValueSequenceBool(); + Vector<bool> vector(sequence.size()); + std::copy(sequence.begin(), sequence.end(), vector.begin()); + builder.Add(name, vector); break; + } case kWebRTCStatsMemberTypeSequenceInt32: - success &= AddPropertySequenceOfNumbers(v8_object, isolate, name, - member->ValueSequenceInt32()); + add_vector(name, member->ValueSequenceInt32()); break; case kWebRTCStatsMemberTypeSequenceUint32: - success &= AddPropertySequenceOfNumbers(v8_object, isolate, name, - member->ValueSequenceUint32()); + add_vector(name, member->ValueSequenceUint32()); break; case kWebRTCStatsMemberTypeSequenceInt64: - success &= AddPropertySequenceOfNumbers(v8_object, isolate, name, - member->ValueSequenceInt64()); + add_vector(name, member->ValueSequenceInt64()); break; case kWebRTCStatsMemberTypeSequenceUint64: - success &= AddPropertySequenceOfNumbers(v8_object, isolate, name, - member->ValueSequenceUint64()); + add_vector(name, member->ValueSequenceUint64()); break; case kWebRTCStatsMemberTypeSequenceDouble: - success &= AddPropertySequenceOfNumbers(v8_object, isolate, name, - member->ValueSequenceDouble()); + add_vector(name, member->ValueSequenceDouble()); break; case kWebRTCStatsMemberTypeSequenceString: - success &= AddPropertySequenceOfStrings(v8_object, isolate, name, - member->ValueSequenceString()); + add_vector(name, member->ValueSequenceString()); break; default: NOTREACHED(); } } - if (!success) { + + v8::Local<v8::Object> v8_object = builder.V8Value(); + if (v8_object.IsEmpty()) { NOTREACHED(); - return v8::Undefined(isolate); + return v8::Undefined(script_state->GetIsolate()); } return v8_object; }
diff --git a/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc b/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc index afc9e46de..09177ea 100644 --- a/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc +++ b/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc
@@ -56,7 +56,7 @@ #if DCHECK_IS_ON() static bool IsIsolatedWorldId(int world_id) { return DOMWrapperWorld::kMainWorldId < world_id && - world_id < DOMWrapperWorld::kIsolatedWorldIdLimit; + world_id < DOMWrapperWorld::kDOMWrapperWorldIsolatedWorldIdLimit; } static bool IsMainWorldId(int world_id) {
diff --git a/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h b/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h index 04ca480..76f79ae 100644 --- a/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h +++ b/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h
@@ -59,8 +59,10 @@ kInvalidWorldId = -1, kMainWorldId = 0, - kEmbedderWorldIdLimit = IsolatedWorldId::kEmbedderWorldIdLimit, - kIsolatedWorldIdLimit = IsolatedWorldId::kIsolatedWorldIdLimit, + kDOMWrapperWorldEmbedderWorldIdLimit = + IsolatedWorldId::kEmbedderWorldIdLimit, + kDOMWrapperWorldIsolatedWorldIdLimit = + IsolatedWorldId::kIsolatedWorldIdLimit, // Other worlds can use IDs after this. Don't manually pick up an ID from // this range. generateWorldIdForType() picks it up on behalf of you.
diff --git a/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc b/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc index 87ed9f7..e82a0e1d 100644 --- a/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc +++ b/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc
@@ -82,6 +82,28 @@ return events; } +void WebCoalescedInputEvent::AddPredictedEvent( + const blink::WebInputEvent& event) { + predicted_events_.push_back(MakeWebScopedInputEvent(event)); +} + +size_t WebCoalescedInputEvent::PredictedEventSize() const { + return predicted_events_.size(); +} + +const WebInputEvent& WebCoalescedInputEvent::PredictedEvent( + size_t index) const { + return *predicted_events_[index].get(); +} + +std::vector<const WebInputEvent*> +WebCoalescedInputEvent::GetPredictedEventsPointers() const { + std::vector<const WebInputEvent*> events; + for (const auto& event : predicted_events_) + events.push_back(event.get()); + return events; +} + WebCoalescedInputEvent::WebCoalescedInputEvent(const WebInputEvent& event) { event_ = MakeWebScopedInputEvent(event); coalesced_events_.push_back(MakeWebScopedInputEvent(event));
diff --git a/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc b/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc index 70218ad..383fe84 100644 --- a/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc +++ b/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc
@@ -94,10 +94,10 @@ std::unique_ptr<AnimationWorkletDispatcherInput> CreateTestMutatorInput() { AnimationWorkletInput::AddAndUpdateState state1{ - {11, 1}, "test1", 5000, nullptr}; + {11, 1}, "test1", 5000, nullptr, 1}; AnimationWorkletInput::AddAndUpdateState state2{ - {22, 2}, "test2", 5000, nullptr}; + {22, 2}, "test2", 5000, nullptr, 1}; auto input = std::make_unique<AnimationWorkletDispatcherInput>(); input->Add(std::move(state1)); @@ -146,7 +146,7 @@ EXPECT_CALL(*client_, SetMutationUpdateRef(_)).Times(0); AnimationWorkletInput::AddAndUpdateState state2{ - {22, 2}, "test2", 5000, nullptr}; + {22, 2}, "test2", 5000, nullptr, 1}; auto input = std::make_unique<AnimationWorkletDispatcherInput>(); input->Add(std::move(state2));
diff --git a/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc b/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc index 16f6a142..42e7b288 100644 --- a/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc +++ b/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc
@@ -562,22 +562,6 @@ EXPECT_EQ(paint_image.FrameCount(), 3u); } -TEST_F(BitmapImageTest, DecoderAndCacheMipLevels) { - // Tests that the supported sizes from the decoder match the mip level sizes - // in cc. - LoadImage("/images/resources/cat.jpg"); - auto paint_image = image_->PaintImageForCurrentFrame(); - // Jpeg decoder supports upto 1/8 downscales, or mip level 3. - for (int mip_level = 0; mip_level < 4; ++mip_level) { - SCOPED_TRACE(mip_level); - SkISize scaled_size = gfx::SizeToSkISize(cc::MipMapUtil::GetSizeForLevel( - gfx::Size(paint_image.width(), paint_image.height()), mip_level)); - SkISize supported_size = paint_image.GetSupportedDecodeSize(scaled_size); - EXPECT_EQ(gfx::SkISizeToSize(supported_size), - gfx::SkISizeToSize(scaled_size)); - } -} - class BitmapImageTestWithMockDecoder : public BitmapImageTest, public MockImageDecoderClient { public:
diff --git a/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc index 8858238..f08fbb3 100644 --- a/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc +++ b/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder.cc
@@ -78,7 +78,7 @@ const int exifMarker = JPEG_APP0 + 1; // JPEG only supports a denominator of 8. -const unsigned g_scale_denomiator = 8; +const unsigned g_scale_denominator = 8; // Extracts the JPEG color space of an image for UMA purposes given |info| which // is assumed to have gone through a jpeg_read_header(). When the color space is @@ -451,6 +451,21 @@ ClearBuffer(); } + bool ShouldDecodeToOriginalSize() const { + // We should decode only to original size if either dimension cannot fit a + // whole number of MCUs. + const int max_h_samp_factor = info_.max_h_samp_factor; + const int max_v_samp_factor = info_.max_v_samp_factor; + DCHECK_GE(max_h_samp_factor, 1); + DCHECK_GE(max_v_samp_factor, 1); + DCHECK_LE(max_h_samp_factor, 4); + DCHECK_LE(max_v_samp_factor, 4); + const int mcu_width = info_.max_h_samp_factor * DCTSIZE; + const int mcu_height = info_.max_v_samp_factor * DCTSIZE; + return info_.image_width % mcu_width != 0 || + info_.image_height % mcu_height != 0; + } + // Decode the JPEG data. If |only_size| is specified, then only the size // information will be decoded. bool Decode(bool only_size) { @@ -496,16 +511,37 @@ // Calculate and set decoded size. int max_numerator = decoder_->DesiredScaleNumerator(); - info_.scale_denom = g_scale_denomiator; + info_.scale_denom = g_scale_denominator; if (decoder_->ShouldGenerateAllSizes()) { + // Some images should not be scaled down by libjpeg_turbo because + // doing so may cause artifacts. Specifically, if the image contains a + // non-whole number of MCUs in either dimension, it's possible that + // the encoder used bogus data to create the last row or column of + // MCUs. This data may manifest when downscaling using libjpeg_turbo. + // See https://crbug.com/890745 and + // https://github.com/libjpeg-turbo/libjpeg-turbo/issues/297. Hence, + // we'll only allow downscaling an image if both dimensions fit a + // whole number of MCUs or if decoding to the original size would + // cause us to exceed memory limits. The latter case is detected by + // checking the |max_numerator| returned by DesiredScaleNumerator(): + // this method will return either |g_scale_denominator| if decoding to + // the original size won't exceed the memory limit (see + // |max_decoded_bytes_| in ImageDecoder) or something less than + // |g_scale_denominator| otherwise to ensure the image is downscaled. std::vector<SkISize> sizes; - sizes.reserve(max_numerator); - for (int numerator = 1; numerator <= max_numerator; ++numerator) { - info_.scale_num = numerator; - jpeg_calc_output_dimensions(&info_); + if (max_numerator == g_scale_denominator && + ShouldDecodeToOriginalSize()) { sizes.push_back( - SkISize::Make(info_.output_width, info_.output_height)); + SkISize::Make(info_.image_width, info_.image_height)); + } else { + sizes.reserve(max_numerator); + for (int numerator = 1; numerator <= max_numerator; ++numerator) { + info_.scale_num = numerator; + jpeg_calc_output_dimensions(&info_); + sizes.push_back( + SkISize::Make(info_.output_width, info_.output_height)); + } } decoder_->SetSupportedDecodeSizes(std::move(sizes)); } @@ -868,13 +904,13 @@ size_t original_bytes = Size().Width() * Size().Height() * 4; if (original_bytes <= max_decoded_bytes_) - return g_scale_denomiator; + return g_scale_denominator; // Downsample according to the maximum decoded size. unsigned scale_numerator = static_cast<unsigned>(floor(sqrt( // MSVC needs explicit parameter type for sqrt(). - static_cast<float>(max_decoded_bytes_ * g_scale_denomiator * - g_scale_denomiator / original_bytes)))); + static_cast<float>(max_decoded_bytes_ * g_scale_denominator * + g_scale_denominator / original_bytes)))); return scale_numerator; }
diff --git a/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc b/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc index 899618c..734ee90 100644 --- a/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc +++ b/third_party/blink/renderer/platform/image-decoders/jpeg/jpeg_image_decoder_test.cc
@@ -338,7 +338,10 @@ } TEST(JPEGImageDecoderTest, SupportedSizesRectangle) { - const char* jpeg_file = "/images/resources/icc-v2-gbr.jpg"; // 275x207 + // This 272x200 image uses 4:2:2 sampling format. The MCU is therefore 16x8. + // The width is a multiple of 16 and the height is a multiple of 8, so it's + // okay for the decoder to downscale it. + const char* jpeg_file = "/images/resources/icc-v2-gbr-422-whole-mcus.jpg"; scoped_refptr<SharedBuffer> data = ReadFile(jpeg_file); ASSERT_TRUE(data); @@ -349,9 +352,9 @@ // This will decode the size and needs to be called to avoid DCHECKs ASSERT_TRUE(decoder->IsSizeAvailable()); std::vector<SkISize> expected_sizes = { - SkISize::Make(35, 26), SkISize::Make(69, 52), SkISize::Make(104, 78), - SkISize::Make(138, 104), SkISize::Make(172, 130), SkISize::Make(207, 156), - SkISize::Make(241, 182), SkISize::Make(275, 207)}; + SkISize::Make(34, 25), SkISize::Make(68, 50), SkISize::Make(102, 75), + SkISize::Make(136, 100), SkISize::Make(170, 125), SkISize::Make(204, 150), + SkISize::Make(238, 175), SkISize::Make(272, 200)}; auto sizes = decoder->GetSupportedDecodeSizes(); ASSERT_EQ(expected_sizes.size(), sizes.size()); @@ -363,6 +366,70 @@ } } +TEST(JPEGImageDecoderTest, + SupportedSizesRectangleNotMultipleOfMCUIfMemoryBound) { + // This 275x207 image uses 4:2:0 sampling format. The MCU is therefore 16x16. + // Neither the width nor the height is a multiple of the MCU, so downscaling + // should not be supported. However, we limit the memory so that the decoder + // is forced to support downscaling. + const char* jpeg_file = "/images/resources/icc-v2-gbr.jpg"; + + scoped_refptr<SharedBuffer> data = ReadFile(jpeg_file); + ASSERT_TRUE(data); + + // Make the memory limit one fewer byte than what is needed in order to force + // downscaling. + std::unique_ptr<ImageDecoder> decoder = CreateJPEGDecoder(275 * 207 * 4 - 1); + decoder->SetData(data.get(), true); + // This will decode the size and needs to be called to avoid DCHECKs + ASSERT_TRUE(decoder->IsSizeAvailable()); + std::vector<SkISize> expected_sizes = { + SkISize::Make(35, 26), SkISize::Make(69, 52), SkISize::Make(104, 78), + SkISize::Make(138, 104), SkISize::Make(172, 130), SkISize::Make(207, 156), + SkISize::Make(241, 182)}; + + auto sizes = decoder->GetSupportedDecodeSizes(); + ASSERT_EQ(expected_sizes.size(), sizes.size()); + for (size_t i = 0; i < sizes.size(); ++i) { + EXPECT_TRUE(expected_sizes[i] == sizes[i]) + << "Expected " << expected_sizes[i].width() << "x" + << expected_sizes[i].height() << ". Got " << sizes[i].width() << "x" + << sizes[i].height(); + } +} + +TEST(JPEGImageDecoderTest, SupportedSizesRectangleNotMultipleOfMCU) { + struct { + const char* jpeg_file; + SkISize expected_size; + } recs[] = { + {// This 264x192 image uses 4:2:0 sampling format. The MCU is therefore + // 16x16. The height is a multiple of 16, but the width is not a + // multiple of 16, so it's not okay for the decoder to downscale it. + "/images/resources/icc-v2-gbr-420-width-not-whole-mcu.jpg", + SkISize::Make(264, 192)}, + {// This 272x200 image uses 4:2:0 sampling format. The MCU is therefore + // 16x16. The width is a multiple of 16, but the width is not a multiple + // of 16, so it's not okay for the decoder to downscale it. + "/images/resources/icc-v2-gbr-420-height-not-whole-mcu.jpg", + SkISize::Make(272, 200)}}; + for (const auto& rec : recs) { + scoped_refptr<SharedBuffer> data = ReadFile(rec.jpeg_file); + ASSERT_TRUE(data); + std::unique_ptr<ImageDecoder> decoder = + CreateJPEGDecoder(std::numeric_limits<int>::max()); + decoder->SetData(data.get(), true); + // This will decode the size and needs to be called to avoid DCHECKs + ASSERT_TRUE(decoder->IsSizeAvailable()); + auto sizes = decoder->GetSupportedDecodeSizes(); + ASSERT_EQ(1u, sizes.size()); + EXPECT_EQ(rec.expected_size, sizes[0]) + << "Expected " << rec.expected_size.width() << "x" + << rec.expected_size.height() << ". Got " << sizes[0].width() << "x" + << sizes[0].height(); + } +} + TEST(JPEGImageDecoderTest, SupportedSizesTruncatedIfMemoryBound) { const char* jpeg_file = "/images/resources/lenna.jpg"; // 256x256 scoped_refptr<SharedBuffer> data = ReadFile(jpeg_file);
diff --git a/third_party/blink/renderer/platform/text/DEPS b/third_party/blink/renderer/platform/text/DEPS index a7e3ce7..9ab8273 100644 --- a/third_party/blink/renderer/platform/text/DEPS +++ b/third_party/blink/renderer/platform/text/DEPS
@@ -9,6 +9,7 @@ "+third_party/blink/renderer/platform/date_components.h", "+third_party/blink/renderer/platform/heap", "+third_party/blink/renderer/platform/language.h", + "+third_party/blink/renderer/platform/mac/version_util_mac.h", "+third_party/blink/renderer/platform/layout_test_support.h", "+third_party/blink/renderer/platform/platform_export.h", "+third_party/blink/renderer/platform/runtime_enabled_features.h",
diff --git a/third_party/blink/renderer/platform/text/locale_mac_test.cc b/third_party/blink/renderer/platform/text/locale_mac_test.cc index aad937b..661489c 100644 --- a/third_party/blink/renderer/platform/text/locale_mac_test.cc +++ b/third_party/blink/renderer/platform/text/locale_mac_test.cc
@@ -29,6 +29,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/date_components.h" +#include "third_party/blink/renderer/platform/mac/version_util_mac.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" #include "third_party/blink/renderer/platform/wtf/date_math.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" @@ -224,16 +225,26 @@ // Do not test ja_JP locale. OS X 10.8 and 10.7 have different formats. } -// http://crbug.com/811685 This test is flaky. -TEST_F(LocaleMacTest, DISABLED_formatTime) { +TEST_F(LocaleMacTest, formatTime) { + // On MacOS 10.13+, Arabic times (which contain spaces) use \xC2\xA0 + // (which is a non-breaking space) instead of \x20 for those spaces. The + // 10.13+ behavior is probably more correct, but there does not appear to be a + // way to configure NSDateFormatter to behave that way on < 10.13. + bool expect_ar_nbsp = !IsOS10_10() && !IsOS10_11() && !IsOS10_12(); + EXPECT_STREQ("1:23 PM", FormatTime("en_US", 13, 23, 00, 000, true).Utf8().data()); EXPECT_STREQ("13:23", FormatTime("fr_FR", 13, 23, 00, 000, true).Utf8().data()); EXPECT_STREQ("13:23", FormatTime("ja_JP", 13, 23, 00, 000, true).Utf8().data()); - EXPECT_STREQ("\xD9\xA1:\xD9\xA2\xD9\xA3 \xD9\x85", - FormatTime("ar", 13, 23, 00, 000, true).Utf8().data()); + if (expect_ar_nbsp) { + EXPECT_STREQ("\xD9\xA1:\xD9\xA2\xD9\xA3\xC2\xA0\xD9\x85", + FormatTime("ar", 13, 23, 00, 000, true).Utf8().data()); + } else { + EXPECT_STREQ("\xD9\xA1:\xD9\xA2\xD9\xA3 \xD9\x85", + FormatTime("ar", 13, 23, 00, 000, true).Utf8().data()); + } EXPECT_STREQ("\xDB\xB1\xDB\xB3:\xDB\xB2\xDB\xB3", FormatTime("fa", 13, 23, 00, 000, true).Utf8().data()); @@ -243,8 +254,13 @@ FormatTime("fr_FR", 00, 00, 00, 000, true).Utf8().data()); EXPECT_STREQ("0:00", FormatTime("ja_JP", 00, 00, 00, 000, true).Utf8().data()); - EXPECT_STREQ("\xD9\xA1\xD9\xA2:\xD9\xA0\xD9\xA0 \xD8\xB5", - FormatTime("ar", 00, 00, 00, 000, true).Utf8().data()); + if (expect_ar_nbsp) { + EXPECT_STREQ("\xD9\xA1\xD9\xA2:\xD9\xA0\xD9\xA0\xC2\xA0\xD8\xB5", + FormatTime("ar", 00, 00, 00, 000, true).Utf8().data()); + } else { + EXPECT_STREQ("\xD9\xA1\xD9\xA2:\xD9\xA0\xD9\xA0 \xD8\xB5", + FormatTime("ar", 00, 00, 00, 000, true).Utf8().data()); + } EXPECT_STREQ("\xDB\xB0:\xDB\xB0\xDB\xB0", FormatTime("fa", 00, 00, 00, 000, true).Utf8().data()); @@ -254,10 +270,17 @@ FormatTime("fr_FR", 07, 07, 07, 007, false).Utf8().data()); EXPECT_STREQ("7:07:07.007", FormatTime("ja_JP", 07, 07, 07, 007, false).Utf8().data()); - EXPECT_STREQ( - "\xD9\xA7:\xD9\xA0\xD9\xA7:" - "\xD9\xA0\xD9\xA7\xD9\xAB\xD9\xA0\xD9\xA0\xD9\xA7 \xD8\xB5", - FormatTime("ar", 07, 07, 07, 007, false).Utf8().data()); + if (expect_ar_nbsp) { + EXPECT_STREQ( + "\xD9\xA7:\xD9\xA0\xD9\xA7:" + "\xD9\xA0\xD9\xA7\xD9\xAB\xD9\xA0\xD9\xA0\xD9\xA7\xC2\xA0\xD8\xB5", + FormatTime("ar", 07, 07, 07, 007, false).Utf8().data()); + } else { + EXPECT_STREQ( + "\xD9\xA7:\xD9\xA0\xD9\xA7:" + "\xD9\xA0\xD9\xA7\xD9\xAB\xD9\xA0\xD9\xA0\xD9\xA7 \xD8\xB5", + FormatTime("ar", 07, 07, 07, 007, false).Utf8().data()); + } EXPECT_STREQ( "\xDB\xB7:\xDB\xB0\xDB\xB7:" "\xDB\xB0\xDB\xB7\xD9\xAB\xDB\xB0\xDB\xB0\xDB\xB7",
diff --git a/third_party/blink/renderer/platform/text/text_run.h b/third_party/blink/renderer/platform/text/text_run.h index df07c6f..0513011 100644 --- a/third_party/blink/renderer/platform/text/text_run.h +++ b/third_party/blink/renderer/platform/text/text_run.h
@@ -50,8 +50,6 @@ kAllowLeadingExpansion = 1 << 1, }; - enum TextCodePath { kAuto = 0, kForceSimple = 1, kForceComplex = 2 }; - typedef unsigned ExpansionBehavior; TextRun(const LChar* c,
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/base.py b/third_party/blink/tools/blinkpy/web_tests/port/base.py index 84eeae0..36b7eb9 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/base.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/base.py
@@ -256,6 +256,16 @@ '--ignore-certificate-errors-spki-list=' + WPT_FINGERPRINT + ',' + SXG_FINGERPRINT + ',' + SXG_WPT_FINGERPRINT, '--user-data-dir'] + + # If we're already repeating the tests more than once, then we're not + # particularly concerned with speed. Resetting the shell between tests + # increases test run time by 2-5X, but provides more consistent results + # [less state leaks between tests]. + if (self.get_option('reset_shell_between_tests') or + self.get_option('repeat_each') > 1 or + self.get_option('iterations') > 1): + flags += ['--reset-shell-between-tests'] + if TESTS_IN_BLINK: flags += ['--tests-in-blink'] return flags
diff --git a/third_party/blink/tools/blinkpy/web_tests/run_webkit_tests.py b/third_party/blink/tools/blinkpy/web_tests/run_webkit_tests.py index 2e81b05..ddcdeb9 100644 --- a/third_party/blink/tools/blinkpy/web_tests/run_webkit_tests.py +++ b/third_party/blink/tools/blinkpy/web_tests/run_webkit_tests.py
@@ -356,6 +356,14 @@ action='store', help='Output per-test profile information, using the specified profiler.'), optparse.make_option( + '--reset-shell-between-tests', + action='store_true', + default=False, + help='Resetting the shell between tests causes the tests to ' + 'take twice as long to run on average, but provides more ' + 'consistent results. This is automatically enabled if ' + '--repeat-each or --gtest_repeat is specified'), + optparse.make_option( '--repeat-each', type='int', default=1,
diff --git a/third_party/boringssl/BUILD.gn b/third_party/boringssl/BUILD.gn index f57824f..256aca0 100644 --- a/third_party/boringssl/BUILD.gn +++ b/third_party/boringssl/BUILD.gn
@@ -49,7 +49,8 @@ # Windows' assembly is built with Yasm. The other platforms use the platform # assembler. -if (is_win && !is_msan) { +# Exclude Yasm for Windows ARM64 because Yasm targets to x86 and x64 only. +if (is_win && !is_msan && current_cpu != "arm64") { import("//third_party/yasm/yasm_assemble.gni") yasm_assemble("boringssl_asm") { if (current_cpu == "x64") {
diff --git a/third_party/feed/README.chromium b/third_party/feed/README.chromium index 0f23db2..4ce5373f 100644 --- a/third_party/feed/README.chromium +++ b/third_party/feed/README.chromium
@@ -2,7 +2,7 @@ Short name: feed URL: https://chromium.googlesource.com/feed Version: 0 -Revision: d97e635aa74d7d067a32cca5a8b65a39f4855e85 +Revision: 89e2c00bd3b9b2f0ce981f5c1d07a40c1e20eac1 License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider.tlb b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider.tlb index dbcd1c1..ae0734c 100644 --- a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider.tlb +++ b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider.tlb Binary files differ
diff --git a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider_i.c b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider_i.c index bb729ba..fdcf5eeb 100644 --- a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider_i.c +++ b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider_i.c
@@ -8,7 +8,7 @@ /* File created by MIDL compiler version 8.xx.xxxx */ /* at a redacted point in time */ -/* Compiler settings for ../../chrome/credential_provider/gaiacp/gaia_credential_provider.idl: +/* Compiler settings for gen/chrome/credential_provider/gaiacp/gaia_credential_provider.idl: Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.xx.xxxx protocol : dce , ms_ext, c_ext, robust error checks: allocation ref bounds_check enum stub_data @@ -82,13 +82,7 @@ MIDL_DEFINE_GUID(IID, LIBID_GaiaCredentialProviderLib,0x4ADC3A52,0x8673,0x4CE3,0x81,0xF6,0x83,0x3D,0x18,0xBE,0xEB,0xA2); -MIDL_DEFINE_GUID(CLSID, CLSID_GaiaCredentialProvider,0x0B5BFDF0,0x4594,0x47AC,0x94,0x0A,0xCF,0xC6,0x9A,0xBC,0x56,0x1C); - - -MIDL_DEFINE_GUID(CLSID, CLSID_GaiaCredential,0x44AF95AC,0x6B23,0x4C54,0x94,0xBE,0xED,0xB1,0xCB,0x52,0xDA,0xFD); - - -MIDL_DEFINE_GUID(CLSID, CLSID_ReauthCredential,0xE6CC5D8B,0x54C2,0x4586,0xAD,0xC3,0x74,0x8E,0xD1,0x62,0x84,0xB7); +MIDL_DEFINE_GUID(CLSID, CLSID_GaiaCredentialProvider,0x89adae71,0xaee5,0x4ee2,0xbf,0xfb,0xe8,0x42,0x4e,0x06,0xf5,0x19); #undef MIDL_DEFINE_GUID
diff --git a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider_i.h b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider_i.h index 11b1bc2..bb09b0db 100644 --- a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider_i.h +++ b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider_i.h
@@ -6,7 +6,7 @@ /* File created by MIDL compiler version 8.xx.xxxx */ /* at a redacted point in time */ -/* Compiler settings for ../../chrome/credential_provider/gaiacp/gaia_credential_provider.idl: +/* Compiler settings for gen/chrome/credential_provider/gaiacp/gaia_credential_provider.idl: Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.xx.xxxx protocol : dce , ms_ext, c_ext, robust error checks: allocation ref bounds_check enum stub_data @@ -85,30 +85,6 @@ #endif /* __GaiaCredentialProvider_FWD_DEFINED__ */ -#ifndef __GaiaCredential_FWD_DEFINED__ -#define __GaiaCredential_FWD_DEFINED__ - -#ifdef __cplusplus -typedef class GaiaCredential GaiaCredential; -#else -typedef struct GaiaCredential GaiaCredential; -#endif /* __cplusplus */ - -#endif /* __GaiaCredential_FWD_DEFINED__ */ - - -#ifndef __ReauthCredential_FWD_DEFINED__ -#define __ReauthCredential_FWD_DEFINED__ - -#ifdef __cplusplus -typedef class ReauthCredential ReauthCredential; -#else -typedef struct ReauthCredential ReauthCredential; -#endif /* __cplusplus */ - -#endif /* __ReauthCredential_FWD_DEFINED__ */ - - /* header files for imported files */ #include "oaidl.h" #include "ocidl.h" @@ -514,25 +490,9 @@ #ifdef __cplusplus -class DECLSPEC_UUID("0B5BFDF0-4594-47AC-940A-CFC69ABC561C") +class DECLSPEC_UUID("89adae71-aee5-4ee2-bffb-e8424e06f519") GaiaCredentialProvider; #endif - -EXTERN_C const CLSID CLSID_GaiaCredential; - -#ifdef __cplusplus - -class DECLSPEC_UUID("44AF95AC-6B23-4C54-94BE-EDB1CB52DAFD") -GaiaCredential; -#endif - -EXTERN_C const CLSID CLSID_ReauthCredential; - -#ifdef __cplusplus - -class DECLSPEC_UUID("E6CC5D8B-54C2-4586-ADC3-748ED16284B7") -ReauthCredential; -#endif #endif /* __GaiaCredentialProviderLib_LIBRARY_DEFINED__ */ /* Additional Prototypes for ALL interfaces */
diff --git a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider_p.c b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider_p.c index 8198483..ed7fc05 100644 --- a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider_p.c +++ b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x64/gaia_credential_provider_p.c
@@ -6,7 +6,7 @@ /* File created by MIDL compiler version 8.xx.xxxx */ /* at a redacted point in time */ -/* Compiler settings for ../../chrome/credential_provider/gaiacp/gaia_credential_provider.idl: +/* Compiler settings for gen/chrome/credential_provider/gaiacp/gaia_credential_provider.idl: Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.xx.xxxx protocol : dce , ms_ext, c_ext, robust error checks: allocation ref bounds_check enum stub_data
diff --git a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider.tlb b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider.tlb index cd1e751..aa92482 100644 --- a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider.tlb +++ b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider.tlb Binary files differ
diff --git a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider_i.c b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider_i.c index 48dc5c3..3584b52 100644 --- a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider_i.c +++ b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider_i.c
@@ -8,7 +8,7 @@ /* File created by MIDL compiler version 8.xx.xxxx */ /* at a redacted point in time */ -/* Compiler settings for ../../chrome/credential_provider/gaiacp/gaia_credential_provider.idl: +/* Compiler settings for gen/chrome/credential_provider/gaiacp/gaia_credential_provider.idl: Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.xx.xxxx protocol : dce , ms_ext, c_ext, robust error checks: allocation ref bounds_check enum stub_data @@ -82,13 +82,7 @@ MIDL_DEFINE_GUID(IID, LIBID_GaiaCredentialProviderLib,0x4ADC3A52,0x8673,0x4CE3,0x81,0xF6,0x83,0x3D,0x18,0xBE,0xEB,0xA2); -MIDL_DEFINE_GUID(CLSID, CLSID_GaiaCredentialProvider,0x0B5BFDF0,0x4594,0x47AC,0x94,0x0A,0xCF,0xC6,0x9A,0xBC,0x56,0x1C); - - -MIDL_DEFINE_GUID(CLSID, CLSID_GaiaCredential,0x44AF95AC,0x6B23,0x4C54,0x94,0xBE,0xED,0xB1,0xCB,0x52,0xDA,0xFD); - - -MIDL_DEFINE_GUID(CLSID, CLSID_ReauthCredential,0xE6CC5D8B,0x54C2,0x4586,0xAD,0xC3,0x74,0x8E,0xD1,0x62,0x84,0xB7); +MIDL_DEFINE_GUID(CLSID, CLSID_GaiaCredentialProvider,0x89adae71,0xaee5,0x4ee2,0xbf,0xfb,0xe8,0x42,0x4e,0x06,0xf5,0x19); #undef MIDL_DEFINE_GUID
diff --git a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider_i.h b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider_i.h index 0ac426f0..e428dfd 100644 --- a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider_i.h +++ b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider_i.h
@@ -6,7 +6,7 @@ /* File created by MIDL compiler version 8.xx.xxxx */ /* at a redacted point in time */ -/* Compiler settings for ../../chrome/credential_provider/gaiacp/gaia_credential_provider.idl: +/* Compiler settings for gen/chrome/credential_provider/gaiacp/gaia_credential_provider.idl: Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.xx.xxxx protocol : dce , ms_ext, c_ext, robust error checks: allocation ref bounds_check enum stub_data @@ -85,30 +85,6 @@ #endif /* __GaiaCredentialProvider_FWD_DEFINED__ */ -#ifndef __GaiaCredential_FWD_DEFINED__ -#define __GaiaCredential_FWD_DEFINED__ - -#ifdef __cplusplus -typedef class GaiaCredential GaiaCredential; -#else -typedef struct GaiaCredential GaiaCredential; -#endif /* __cplusplus */ - -#endif /* __GaiaCredential_FWD_DEFINED__ */ - - -#ifndef __ReauthCredential_FWD_DEFINED__ -#define __ReauthCredential_FWD_DEFINED__ - -#ifdef __cplusplus -typedef class ReauthCredential ReauthCredential; -#else -typedef struct ReauthCredential ReauthCredential; -#endif /* __cplusplus */ - -#endif /* __ReauthCredential_FWD_DEFINED__ */ - - /* header files for imported files */ #include "oaidl.h" #include "ocidl.h" @@ -514,25 +490,9 @@ #ifdef __cplusplus -class DECLSPEC_UUID("0B5BFDF0-4594-47AC-940A-CFC69ABC561C") +class DECLSPEC_UUID("89adae71-aee5-4ee2-bffb-e8424e06f519") GaiaCredentialProvider; #endif - -EXTERN_C const CLSID CLSID_GaiaCredential; - -#ifdef __cplusplus - -class DECLSPEC_UUID("44AF95AC-6B23-4C54-94BE-EDB1CB52DAFD") -GaiaCredential; -#endif - -EXTERN_C const CLSID CLSID_ReauthCredential; - -#ifdef __cplusplus - -class DECLSPEC_UUID("E6CC5D8B-54C2-4586-ADC3-748ED16284B7") -ReauthCredential; -#endif #endif /* __GaiaCredentialProviderLib_LIBRARY_DEFINED__ */ /* Additional Prototypes for ALL interfaces */
diff --git a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider_p.c b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider_p.c index db38570..1489728 100644 --- a/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider_p.c +++ b/third_party/win_build_output/midl/chrome/credential_provider/gaiacp/x86/gaia_credential_provider_p.c
@@ -6,7 +6,7 @@ /* File created by MIDL compiler version 8.xx.xxxx */ /* at a redacted point in time */ -/* Compiler settings for ../../chrome/credential_provider/gaiacp/gaia_credential_provider.idl: +/* Compiler settings for gen/chrome/credential_provider/gaiacp/gaia_credential_provider.idl: Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.xx.xxxx protocol : dce , ms_ext, c_ext, robust error checks: allocation ref bounds_check enum stub_data
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 8ce0439..271203f 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -1114,6 +1114,8 @@ <int value="15" label="Visible renderer in foreground app allocation failure"/> <int value="16" label="All renderer allocation failure"/> + <int value="17" label="Utility process foreground OOM"/> + <int value="18" label="All utility process crashes"/> </enum> <enum name="AndroidResourceExtractionStatus"> @@ -1898,6 +1900,17 @@ <int value="11" label="READY_SCREEN_CONTINUED"/> </enum> +<enum name="AssistantSource"> + <int value="0" label="kUnspecified"/> + <int value="1" label="kDeepLink"/> + <int value="2" label="kHotkey"/> + <int value="3" label="kHotword"/> + <int value="4" label="kLauncherSearchBox"/> + <int value="5" label="kLongPressLauncher"/> + <int value="6" label="kSetup"/> + <int value="7" label="kStylus"/> +</enum> + <enum name="AsyncDNSConfigParsePosix"> <int value="0" label="OK"/> <int value="1" label="RES_INIT_FAILED"/> @@ -5287,6 +5300,15 @@ <int value="31" label="Chooser Permissions Bubble"/> </enum> +<enum name="CachedImageFetcherEvent"> + <int value="0" label="Request for an image"/> + <int value="1" label="Cache hit"/> + <int value="2" label="Cache miss"/> + <int value="3" label="Cache decoding error"/> + <int value="4" label="Network transcoding error"/> + <int value="5" label="Failure to fetch the image from the network"/> +</enum> + <enum name="CacheResult"> <int value="0" label="MEMORY_CACHE_HIT"/> <int value="1" label="DISK_CACHE_HIT"/> @@ -29246,6 +29268,7 @@ <int value="-1174267639" label="ClientLoFi:disabled"/> <int value="-1172572865" label="NTPShowGoogleGInOmnibox:enabled"/> <int value="-1172204005" label="enable-offline-auto-reload-visible-only"/> + <int value="-1166715563" label="ChromeOSAssistant:disabled"/> <int value="-1162944097" label="enable-color-correct-rendering"/> <int value="-1161409696" label="MediaRemotingEncrypted:enabled"/> <int value="-1161384421" label="ContextualSuggestionsAboveArticles:enabled"/> @@ -30603,6 +30626,7 @@ <int value="1481562816" label="disable-password-link"/> <int value="1486171015" label="disable-fill-on-account-select"/> <int value="1487341558" label="MacViewsAutofillPopup:enabled"/> + <int value="1488193175" label="ChromeOSAssistant:enabled"/> <int value="1488700164" label="password-import:disabled"/> <int value="1489915799" label="disable-permissions-blacklist"/> <int value="1490043732" label="enable-fill-on-account-select"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index e1b8c905..168040c 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -5324,6 +5324,13 @@ <summary>Record the status of the Assistant opt-in flow.</summary> </histogram> +<histogram name="Assistant.QueryCountPerEntryPoint" enum="AssistantSource" + expires_after="2019-10-15"> + <owner>xiaohuic@chromium.org</owner> + <owner>meilinw@chromium.org</owner> + <summary>Number of queries fired for each entry point.</summary> +</histogram> + <histogram name="Assistant.ServiceStartTime" units="ms"> <owner>updowndota@chromium.org</owner> <summary>Amount of time spent in starting Assistant service.</summary> @@ -11552,6 +11559,43 @@ <summary>A bubble was given to the bubble manager but not shown.</summary> </histogram> +<histogram name="CachedImageFetcher.Events" enum="CachedImageFetcherEvent"> + <owner>fgorski@chromium.org</owner> + <owner>wylieb@chromium.org</owner> + <summary> + Events that track the lifecycle and performance of the cached_image_fetcher. + The events reported include: success/failure conditions, various recoverable + errors and a couple of dead-end errors. + </summary> +</histogram> + +<histogram name="CachedImageFetcher.ImageLoadFromCacheTime" units="ms"> + <owner>fgorski@chromium.org</owner> + <owner>wylieb@chromium.org</owner> + <summary> + The time it takes for cached_image_fetcher to load an image from the cache. + </summary> +</histogram> + +<histogram name="CachedImageFetcher.ImageLoadFromNetworkAfterCacheHit" + units="ms"> + <owner>fgorski@chromium.org</owner> + <owner>wylieb@chromium.org</owner> + <summary> + The time it takes for cached_image_fetcher to load an image from the network + after a cache hit. + </summary> +</histogram> + +<histogram name="CachedImageFetcher.ImageLoadFromNetworkTime" units="ms"> + <owner>fgorski@chromium.org</owner> + <owner>wylieb@chromium.org</owner> + <summary> + The time it takes for cached_image_fetcher to load an image from the + network. + </summary> +</histogram> + <histogram name="Canvas.ContextType" enum="CanvasContextType"> <owner>junov@chromium.org</owner> <owner>kbr@chromium.org</owner> @@ -84750,6 +84794,16 @@ </summary> </histogram> +<histogram name="Renderer4.Browser.RasterTaskTotalDuration" + units="microseconds"> + <owner>khushalsagar@chromium.org</owner> + <summary> + Time spent completing all work for a compositor rasterization task. This + includes the time in the renderer process for sending GL or paint commands + to the GPU process and the time for flushing these commands to the driver. + </summary> +</histogram> + <histogram name="Renderer4.CommitToFinish" units="ms"> <owner>wiltzius@chromium.org</owner> <summary> @@ -85228,6 +85282,16 @@ </summary> </histogram> +<histogram name="Renderer4.Renderer.RasterTaskTotalDuration" + units="microseconds"> + <owner>khushalsagar@chromium.org</owner> + <summary> + Time spent completing all work for a compositor rasterization task. This + includes the time in the renderer process for sending GL or paint commands + to the GPU process and the time for flushing these commands to the driver. + </summary> +</histogram> + <histogram name="Renderer4.renderPassCount"> <owner>wiltzius@chromium.org</owner> <summary> @@ -107259,6 +107323,15 @@ <summary>Time it took sync to load models for USS datatypes.</summary> </histogram> +<histogram base="true" name="Sync.USSMigrationEntityCount" units="entries" + expires_after="2020-02-01"> + <owner>mastiz@chromium.org</owner> + <summary> + Counts the number of sync entities per model type successfully migrated from + directory to USS. + </summary> +</histogram> + <histogram name="Sync.USSMigrationFailure" enum="SyncModelTypes"> <owner>maxbogue@chromium.org</owner> <summary>Counts directory to USS migration failures per model type.</summary> @@ -131664,6 +131737,13 @@ <affected-histogram name="Renderer4.ImageDecodeTaskDurationUs.OutOfRaster"/> </histogram_suffixes> +<histogram_suffixes name="RasterTaskTypeGpu" separator="."> + <suffix name="Gpu" label="This metric is for only gpu raster."/> + <suffix name="Oop" label="This metric is for only oop raster."/> + <affected-histogram name="Renderer4.Browser.RasterTaskTotalDuration"/> + <affected-histogram name="Renderer4.Renderer.RasterTaskTotalDuration"/> +</histogram_suffixes> + <histogram_suffixes name="ReadErrorSourceNetwork" separator="."> <suffix name="AnyNetwork"/> <suffix name="CurrentNetwork" @@ -133851,6 +133931,7 @@ <affected-histogram name="Sync.ModelTypeCount4"/> <affected-histogram name="Sync.ModelTypeEntityChange"/> <affected-histogram name="Sync.ModelTypeMemoryKB"/> + <affected-histogram name="Sync.USSMigrationEntityCount"/> </histogram_suffixes> <histogram_suffixes name="SyncModelTypeByMacro" separator="" ordering="prefix">
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index 23c0c69..7ead40f 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -17,7 +17,6 @@ blink_perf.svg,"kouhei@chromium.org, fs@opera.com",Blink>SVG,https://bit.ly/blink-perf-benchmarks, components_perftests,csharrison@chromium.org,,, dromaeo,"jbroman@chromium.org, yukishiino@chromium.org, haraken@chromium.org",Blink>Bindings,, -dummy_benchmark.histogram_benchmark_1,"eakuefner@chromium.org, simonhatch@chromium.org",,, dummy_benchmark.noisy_benchmark_1,nednguyen@google.com,Speed>Telemetry,, dummy_benchmark.stable_benchmark_1,nednguyen@google.com,Speed>Telemetry,, gpu_perftests,"reveman@chromium.org, chrome-gpu-perf-owners@chromium.org",Internals>GPU,,
diff --git a/tools/perf/benchmarks/dummy_benchmark.py b/tools/perf/benchmarks/dummy_benchmark.py index da440613..b284ae50 100644 --- a/tools/perf/benchmarks/dummy_benchmark.py +++ b/tools/perf/benchmarks/dummy_benchmark.py
@@ -15,7 +15,6 @@ from telemetry import benchmark from telemetry.value import scalar from telemetry.page import legacy_page_test -from telemetry.web_perf import timeline_based_measurement from page_sets import dummy_story_set @@ -63,18 +62,3 @@ def Name(cls): return 'dummy_benchmark.noisy_benchmark_1' - -@benchmark.Info(emails=['eakuefner@chromium.org', 'simonhatch@chromium.org']) -class DummyBenchmarkThree(perf_benchmark.PerfBenchmark): - """A test benchmark for outputting histograms.""" - page_set = dummy_story_set.DummyStorySet - - def CreateCoreTimelineBasedMeasurementOptions(self): - options = timeline_based_measurement.Options( - timeline_based_measurement.DEBUG_OVERHEAD_LEVEL) - options.SetTimelineBasedMetrics(['sampleMetric']) - return options - - @classmethod - def Name(cls): - return 'dummy_benchmark.histogram_benchmark_1'
diff --git a/tools/perf/core/shard_maps/android-go-perf_map.json b/tools/perf/core/shard_maps/android-go-perf_map.json index 885370c..091808ab 100644 --- a/tools/perf/core/shard_maps/android-go-perf_map.json +++ b/tools/perf/core/shard_maps/android-go-perf_map.json
@@ -49,22 +49,22 @@ "benchmarks": { "system_health.common_mobile": { "begin": 17, - "end": 33 + "end": 34 } } }, "6": { "benchmarks": { "system_health.common_mobile": { - "begin": 33, - "end": 59 + "begin": 34, + "end": 61 } } }, "7": { "benchmarks": { "system_health.common_mobile": { - "begin": 59 + "begin": 61 }, "system_health.memory_mobile": { "end": 6 @@ -99,38 +99,38 @@ "benchmarks": { "system_health.memory_mobile": { "begin": 24, - "end": 32 + "end": 33 } } }, "12": { "benchmarks": { "system_health.memory_mobile": { - "begin": 32, - "end": 44 + "begin": 33, + "end": 45 } } }, "13": { "benchmarks": { "system_health.memory_mobile": { - "begin": 44, - "end": 54 + "begin": 45, + "end": 56 } } }, "14": { "benchmarks": { "system_health.memory_mobile": { - "begin": 54, - "end": 60 + "begin": 56, + "end": 62 } } }, "15": { "benchmarks": { "system_health.memory_mobile": { - "begin": 60 + "begin": 62 }, "system_health.webview_startup": {}, "v8.browsing_mobile": { @@ -162,7 +162,7 @@ } }, "extra_infos": { - "num_stories": 194, + "num_stories": 198, "predicted_min_shard_time": 2148.0, "predicted_min_shard_index": 10, "predicted_max_shard_time": 3000.0, @@ -172,15 +172,15 @@ "shard #2": 2538.0, "shard #3": 2356.0, "shard #4": 2546.0, - "shard #5": 2320.0, - "shard #6": 2318.0, + "shard #5": 2322.0, + "shard #6": 2320.0, "shard #7": 2452.0, "shard #8": 3000.0, "shard #9": 2220.0, "shard #10": 2148.0, - "shard #11": 2394.0, + "shard #11": 2400.0, "shard #12": 2538.0, - "shard #13": 2334.0, + "shard #13": 2340.0, "shard #14": 2538.0, "shard #15": 2214.0, "shard #16": 2574.0,
diff --git a/tools/perf/core/shard_maps/android-nexus5x-perf_map.json b/tools/perf/core/shard_maps/android-nexus5x-perf_map.json index 509ccd0..0f758274 100644 --- a/tools/perf/core/shard_maps/android-nexus5x-perf_map.json +++ b/tools/perf/core/shard_maps/android-nexus5x-perf_map.json
@@ -8,18 +8,22 @@ "blink_perf.dom": {}, "blink_perf.events": {}, "blink_perf.image_decoder": {}, - "blink_perf.layout": {} + "blink_perf.layout": { + "end": 59 + } } }, "1": { "benchmarks": { + "blink_perf.layout": { + "begin": 59 + }, "blink_perf.owp_storage": {}, "blink_perf.paint": {}, "blink_perf.parser": {}, "blink_perf.shadow_dom": {}, "blink_perf.svg": {}, "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, "dummy_benchmark.noisy_benchmark_1": {}, "dummy_benchmark.stable_benchmark_1": {}, "jetstream": {}, @@ -34,22 +38,22 @@ "benchmarks": { "loading.mobile": { "begin": 16, - "end": 47 + "end": 44 } } }, "3": { "benchmarks": { "loading.mobile": { - "begin": 47, - "end": 92 + "begin": 44, + "end": 90 } } }, "4": { "benchmarks": { "loading.mobile": { - "begin": 92 + "begin": 90 }, "media.desktop": {}, "media.mobile": {}, @@ -57,14 +61,14 @@ "memory.long_running_idle_gmail_background_tbmv2": {}, "memory.long_running_idle_gmail_tbmv2": {}, "memory.top_10_mobile": { - "end": 12 + "end": 9 } } }, "5": { "benchmarks": { "memory.top_10_mobile": { - "begin": 12 + "begin": 9 }, "octane": {}, "oortonline_tbmv2": {}, @@ -72,52 +76,48 @@ "power.typical_10_mobile": {}, "rasterize_and_record_micro.partial_invalidation": {}, "rasterize_and_record_micro.top_25": {}, - "rendering.desktop": {}, - "rendering.mobile": { - "end": 12 - } + "rendering.desktop": {} } }, "6": { "benchmarks": { "rendering.mobile": { - "begin": 12, - "end": 116 + "end": 101 } } }, "7": { "benchmarks": { "rendering.mobile": { - "begin": 116, - "end": 220 + "begin": 101, + "end": 228 } } }, "8": { "benchmarks": { "rendering.mobile": { - "begin": 220, - "end": 356 + "begin": 228, + "end": 359 } } }, "9": { "benchmarks": { "rendering.mobile": { - "begin": 356 + "begin": 359 }, - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": { - "end": 12 + "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, + "smoothness.tough_pinch_zoom_cases": { + "end": 13 } } }, "10": { "benchmarks": { - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": { - "begin": 12 + "smoothness.tough_pinch_zoom_cases": { + "begin": 13 }, - "smoothness.tough_pinch_zoom_cases": {}, "speedometer": {}, "speedometer-future": {}, "speedometer2": {}, @@ -125,33 +125,33 @@ "startup.mobile": {}, "system_health.common_desktop": {}, "system_health.common_mobile": { - "end": 24 + "end": 39 } } }, "11": { "benchmarks": { "system_health.common_mobile": { - "begin": 24 + "begin": 39 }, "system_health.memory_desktop": {}, "system_health.memory_mobile": { - "end": 14 + "end": 15 } } }, "12": { "benchmarks": { "system_health.memory_mobile": { - "begin": 14, - "end": 39 + "begin": 15, + "end": 43 } } }, "13": { "benchmarks": { "system_health.memory_mobile": { - "begin": 39 + "begin": 43 }, "system_health.webview_startup": {}, "tab_switching.typical_25": {}, @@ -159,14 +159,14 @@ "v8.browsing_desktop": {}, "v8.browsing_desktop-future": {}, "v8.browsing_mobile": { - "end": 7 + "end": 8 } } }, "14": { "benchmarks": { "v8.browsing_mobile": { - "begin": 7 + "begin": 8 }, "v8.browsing_mobile-future": { "end": 7 @@ -184,26 +184,26 @@ } }, "extra_infos": { - "num_stories": 1904, - "predicted_min_shard_time": 6850.0, - "predicted_min_shard_index": 13, - "predicted_max_shard_time": 7154.0, - "predicted_max_shard_index": 14, - "shard #0": 7030.0, - "shard #1": 7070.0, - "shard #2": 7016.0, - "shard #3": 7152.0, - "shard #4": 6970.0, - "shard #5": 6978.0, - "shard #6": 7020.0, - "shard #7": 7026.0, - "shard #8": 7008.0, - "shard #9": 7068.0, - "shard #10": 6956.0, - "shard #11": 7076.0, - "shard #12": 6984.0, - "shard #13": 6850.0, - "shard #14": 7154.0, + "num_stories": 1953, + "predicted_min_shard_time": 6540.0, + "predicted_min_shard_index": 2, + "predicted_max_shard_time": 7232.0, + "predicted_max_shard_index": 1, + "shard #0": 6832.0, + "shard #1": 7232.0, + "shard #2": 6540.0, + "shard #3": 7188.0, + "shard #4": 6610.0, + "shard #5": 6800.0, + "shard #6": 6944.0, + "shard #7": 6860.0, + "shard #8": 6916.0, + "shard #9": 6844.0, + "shard #10": 6850.0, + "shard #11": 6700.0, + "shard #12": 7068.0, + "shard #13": 6834.0, + "shard #14": 6630.0, "shard #15": 7136.0 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/android_nexus5_perf_map.json b/tools/perf/core/shard_maps/android_nexus5_perf_map.json index 51e35602..73d55558 100644 --- a/tools/perf/core/shard_maps/android_nexus5_perf_map.json +++ b/tools/perf/core/shard_maps/android_nexus5_perf_map.json
@@ -24,102 +24,96 @@ "blink_perf.shadow_dom": {}, "blink_perf.svg": {}, "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, "dummy_benchmark.noisy_benchmark_1": {}, - "dummy_benchmark.stable_benchmark_1": {}, - "jetstream": {} + "dummy_benchmark.stable_benchmark_1": {} } }, "2": { "benchmarks": { + "jetstream": {}, "kraken": {}, "loading.desktop": {}, "loading.mobile": { - "end": 24 + "end": 23 } } }, "3": { "benchmarks": { "loading.mobile": { - "begin": 24, - "end": 63 + "begin": 23, + "end": 59 } } }, "4": { "benchmarks": { "loading.mobile": { - "begin": 63 + "begin": 59 }, "media.desktop": {}, "media.mobile": {}, "memory.desktop": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, - "memory.top_10_mobile": { - "end": 2 - } + "memory.long_running_idle_gmail_background_tbmv2": {} } }, "5": { "benchmarks": { - "memory.top_10_mobile": { - "begin": 2 - }, + "memory.long_running_idle_gmail_tbmv2": {}, + "memory.top_10_mobile": {}, "octane": {}, "oortonline_tbmv2": {}, "power.desktop": {}, "power.typical_10_mobile": {}, "rasterize_and_record_micro.partial_invalidation": {}, "rasterize_and_record_micro.top_25": { - "end": 20 + "end": 7 } } }, "6": { "benchmarks": { "rasterize_and_record_micro.top_25": { - "begin": 20 + "begin": 7 }, "rendering.desktop": {}, "rendering.mobile": { - "end": 96 + "end": 81 } } }, "7": { "benchmarks": { "rendering.mobile": { - "begin": 96, - "end": 210 + "begin": 81, + "end": 218 } } }, "8": { "benchmarks": { "rendering.mobile": { - "begin": 210, - "end": 358 + "begin": 218, + "end": 360 } } }, "9": { "benchmarks": { "rendering.mobile": { - "begin": 358 + "begin": 360 }, - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": { - "end": 16 + "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, + "smoothness.tough_pinch_zoom_cases": { + "end": 14 } } }, "10": { "benchmarks": { - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": { - "begin": 16 + "smoothness.tough_pinch_zoom_cases": { + "begin": 14 }, - "smoothness.tough_pinch_zoom_cases": {}, "speedometer": {}, "speedometer-future": {}, "speedometer2": {}, @@ -127,33 +121,33 @@ "startup.mobile": {}, "system_health.common_desktop": {}, "system_health.common_mobile": { - "end": 23 + "end": 36 } } }, "11": { "benchmarks": { "system_health.common_mobile": { - "begin": 23 + "begin": 36 }, "system_health.memory_desktop": {}, "system_health.memory_mobile": { - "end": 13 + "end": 14 } } }, "12": { "benchmarks": { "system_health.memory_mobile": { - "begin": 13, - "end": 36 + "begin": 14, + "end": 40 } } }, "13": { "benchmarks": { "system_health.memory_mobile": { - "begin": 36 + "begin": 40 }, "system_health.webview_startup": {}, "tab_switching.typical_25": {}, @@ -161,24 +155,24 @@ "v8.browsing_desktop": {}, "v8.browsing_desktop-future": {}, "v8.browsing_mobile": { - "end": 1 + "end": 2 } } }, "14": { "benchmarks": { "v8.browsing_mobile": { - "begin": 1 + "begin": 2 }, "v8.browsing_mobile-future": { - "end": 3 + "end": 6 } } }, "15": { "benchmarks": { "v8.browsing_mobile-future": { - "begin": 3 + "begin": 6 }, "v8.runtime_stats.top_25": {}, "wasm": {}, @@ -186,26 +180,26 @@ } }, "extra_infos": { - "num_stories": 1904, - "predicted_min_shard_time": 7492.0, - "predicted_min_shard_index": 11, - "predicted_max_shard_time": 8258.0, - "predicted_max_shard_index": 1, - "shard #0": 7888.0, - "shard #1": 8258.0, - "shard #2": 7542.0, - "shard #3": 7740.0, - "shard #4": 7796.0, - "shard #5": 7906.0, - "shard #6": 7830.0, - "shard #7": 7882.0, - "shard #8": 7874.0, - "shard #9": 7874.0, - "shard #10": 7856.0, - "shard #11": 7492.0, - "shard #12": 8160.0, - "shard #13": 8008.0, - "shard #14": 7732.0, - "shard #15": 7848.0 + "num_stories": 1953, + "predicted_min_shard_time": 7352.0, + "predicted_min_shard_index": 1, + "predicted_max_shard_time": 8142.0, + "predicted_max_shard_index": 2, + "shard #0": 7462.0, + "shard #1": 7352.0, + "shard #2": 8142.0, + "shard #3": 7580.0, + "shard #4": 7590.0, + "shard #5": 7974.0, + "shard #6": 7624.0, + "shard #7": 7710.0, + "shard #8": 7644.0, + "shard #9": 7724.0, + "shard #10": 7710.0, + "shard #11": 7566.0, + "shard #12": 7764.0, + "shard #13": 7754.0, + "shard #14": 7564.0, + "shard #15": 7712.0 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/android_nexus5x_webview_perf_map.json b/tools/perf/core/shard_maps/android_nexus5x_webview_perf_map.json index dcf2abcf..0f8ce77 100644 --- a/tools/perf/core/shard_maps/android_nexus5x_webview_perf_map.json +++ b/tools/perf/core/shard_maps/android_nexus5x_webview_perf_map.json
@@ -9,14 +9,14 @@ "blink_perf.events": {}, "blink_perf.image_decoder": {}, "blink_perf.layout": { - "end": 12 + "end": 13 } } }, "1": { "benchmarks": { "blink_perf.layout": { - "begin": 12 + "begin": 13 }, "blink_perf.owp_storage": {}, "blink_perf.paint": {}, @@ -33,37 +33,36 @@ "dromaeo": { "begin": 2 }, - "dummy_benchmark.histogram_benchmark_1": {}, "dummy_benchmark.noisy_benchmark_1": {}, "dummy_benchmark.stable_benchmark_1": {}, "jetstream": {}, "kraken": {}, "loading.desktop": {}, "loading.mobile": { - "end": 33 + "end": 31 } } }, "3": { "benchmarks": { "loading.mobile": { - "begin": 33, - "end": 55 + "begin": 31, + "end": 54 } } }, "4": { "benchmarks": { "loading.mobile": { - "begin": 55, - "end": 92 + "begin": 54, + "end": 91 } } }, "5": { "benchmarks": { "loading.mobile": { - "begin": 92 + "begin": 91 }, "media.desktop": {}, "media.mobile": {}, @@ -71,14 +70,14 @@ "memory.long_running_idle_gmail_background_tbmv2": {}, "memory.long_running_idle_gmail_tbmv2": {}, "memory.top_10_mobile": { - "end": 18 + "end": 17 } } }, "6": { "benchmarks": { "memory.top_10_mobile": { - "begin": 18 + "begin": 17 }, "octane": {}, "oortonline_tbmv2": {}, @@ -88,22 +87,22 @@ "rasterize_and_record_micro.top_25": {}, "rendering.desktop": {}, "rendering.mobile": { - "end": 22 + "end": 17 } } }, "7": { "benchmarks": { "rendering.mobile": { - "begin": 22, - "end": 187 + "begin": 17, + "end": 174 } } }, "8": { "benchmarks": { "rendering.mobile": { - "begin": 187, + "begin": 174, "end": 403 } } @@ -122,37 +121,42 @@ "startup.mobile": {}, "system_health.common_desktop": {}, "system_health.common_mobile": { - "end": 1 + "end": 8 } } }, "10": { "benchmarks": { "system_health.common_mobile": { - "begin": 1 + "begin": 8 + }, + "system_health.memory_desktop": { + "end": 78 } } }, "11": { "benchmarks": { - "system_health.memory_desktop": {}, + "system_health.memory_desktop": { + "begin": 78 + }, "system_health.memory_mobile": { - "end": 19 + "end": 20 } } }, "12": { "benchmarks": { "system_health.memory_mobile": { - "begin": 19, - "end": 47 + "begin": 20, + "end": 50 } } }, "13": { "benchmarks": { "system_health.memory_mobile": { - "begin": 47 + "begin": 50 }, "system_health.webview_startup": {}, "tab_switching.typical_25": {}, @@ -160,14 +164,14 @@ "v8.browsing_desktop": {}, "v8.browsing_desktop-future": {}, "v8.browsing_mobile": { - "end": 6 + "end": 7 } } }, "14": { "benchmarks": { "v8.browsing_mobile": { - "begin": 6 + "begin": 7 }, "v8.browsing_mobile-future": { "end": 7 @@ -185,26 +189,26 @@ } }, "extra_infos": { - "num_stories": 1904, - "predicted_min_shard_time": 5702.0, - "predicted_min_shard_index": 13, - "predicted_max_shard_time": 6112.0, - "predicted_max_shard_index": 4, - "shard #0": 5910.0, - "shard #1": 5896.0, - "shard #2": 5950.0, - "shard #3": 5852.0, - "shard #4": 6112.0, - "shard #5": 5754.0, - "shard #6": 6004.0, - "shard #7": 5862.0, - "shard #8": 5950.0, - "shard #9": 5896.0, - "shard #10": 6030.0, - "shard #11": 5730.0, - "shard #12": 6054.0, - "shard #13": 5702.0, - "shard #14": 6104.0, + "num_stories": 1953, + "predicted_min_shard_time": 5582.0, + "predicted_min_shard_index": 14, + "predicted_max_shard_time": 6080.0, + "predicted_max_shard_index": 13, + "shard #0": 5832.0, + "shard #1": 5874.0, + "shard #2": 5836.0, + "shard #3": 5840.0, + "shard #4": 5816.0, + "shard #5": 5914.0, + "shard #6": 5700.0, + "shard #7": 5902.0, + "shard #8": 5872.0, + "shard #9": 5776.0, + "shard #10": 5874.0, + "shard #11": 5922.0, + "shard #12": 5700.0, + "shard #13": 6080.0, + "shard #14": 5582.0, "shard #15": 5914.0 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/android_nexus6_webview_perf_map.json b/tools/perf/core/shard_maps/android_nexus6_webview_perf_map.json index 2d415c3..7b0ec2a0 100644 --- a/tools/perf/core/shard_maps/android_nexus6_webview_perf_map.json +++ b/tools/perf/core/shard_maps/android_nexus6_webview_perf_map.json
@@ -15,7 +15,6 @@ "blink_perf.shadow_dom": {}, "blink_perf.svg": {}, "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, "dummy_benchmark.noisy_benchmark_1": {}, "dummy_benchmark.stable_benchmark_1": {} } @@ -26,14 +25,14 @@ "kraken": {}, "loading.desktop": {}, "loading.mobile": { - "end": 77 + "end": 70 } } }, "2": { "benchmarks": { "loading.mobile": { - "begin": 77 + "begin": 70 }, "media.desktop": {}, "media.mobile": {}, @@ -49,51 +48,46 @@ "rasterize_and_record_micro.top_25": {}, "rendering.desktop": {}, "rendering.mobile": { - "end": 13 + "end": 1 } } }, "3": { "benchmarks": { "rendering.mobile": { - "begin": 13, - "end": 263 + "begin": 1, + "end": 245 } } }, "4": { "benchmarks": { "rendering.mobile": { - "begin": 263 + "begin": 245 }, "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, - "smoothness.tough_pinch_zoom_cases": { - "end": 9 - } + "smoothness.tough_pinch_zoom_cases": {}, + "speedometer": {}, + "speedometer-future": {}, + "speedometer2": {} } }, "5": { "benchmarks": { - "smoothness.tough_pinch_zoom_cases": { - "begin": 9 - }, - "speedometer": {}, - "speedometer-future": {}, - "speedometer2": {}, "speedometer2-future": {}, "startup.mobile": {}, "system_health.common_desktop": {}, "system_health.common_mobile": {}, "system_health.memory_desktop": {}, "system_health.memory_mobile": { - "end": 16 + "end": 18 } } }, "6": { "benchmarks": { "system_health.memory_mobile": { - "begin": 16 + "begin": 18 }, "system_health.webview_startup": {}, "tab_switching.typical_25": {}, @@ -101,14 +95,14 @@ "v8.browsing_desktop": {}, "v8.browsing_desktop-future": {}, "v8.browsing_mobile": { - "end": 1 + "end": 2 } } }, "7": { "benchmarks": { "v8.browsing_mobile": { - "begin": 1 + "begin": 2 }, "v8.browsing_mobile-future": {}, "v8.runtime_stats.top_25": {}, @@ -117,18 +111,18 @@ } }, "extra_infos": { - "num_stories": 1944, - "predicted_min_shard_time": 13184.0, - "predicted_min_shard_index": 0, - "predicted_max_shard_time": 13580.0, + "num_stories": 1953, + "predicted_min_shard_time": 12832.0, + "predicted_min_shard_index": 6, + "predicted_max_shard_time": 13204.0, "predicted_max_shard_index": 1, - "shard #0": 13184.0, - "shard #1": 13580.0, - "shard #2": 13458.0, - "shard #3": 13400.0, - "shard #4": 13364.0, - "shard #5": 13324.0, - "shard #6": 13426.0, - "shard #7": 13452.0 + "shard #0": 13022.0, + "shard #1": 13204.0, + "shard #2": 13022.0, + "shard #3": 13138.0, + "shard #4": 13204.0, + "shard #5": 13138.0, + "shard #6": 12832.0, + "shard #7": 13192.0 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/linux-perf_map.json b/tools/perf/core/shard_maps/linux-perf_map.json index f1cd4cd..df0380f 100644 --- a/tools/perf/core/shard_maps/linux-perf_map.json +++ b/tools/perf/core/shard_maps/linux-perf_map.json
@@ -9,44 +9,43 @@ "blink_perf.events": {}, "blink_perf.image_decoder": {}, "blink_perf.layout": { - "end": 8 + "end": 9 } } }, "1": { "benchmarks": { "blink_perf.layout": { - "begin": 8 + "begin": 9 }, "blink_perf.owp_storage": {}, "blink_perf.paint": {}, "blink_perf.parser": {}, "blink_perf.shadow_dom": { - "end": 35 + "end": 37 } } }, "2": { "benchmarks": { "blink_perf.shadow_dom": { - "begin": 35 + "begin": 37 }, "blink_perf.svg": {}, "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, "dummy_benchmark.noisy_benchmark_1": {}, "dummy_benchmark.stable_benchmark_1": {}, "jetstream": {}, "kraken": {}, "loading.desktop": { - "end": 25 + "end": 26 } } }, "3": { "benchmarks": { "loading.desktop": { - "begin": 25, + "begin": 26, "end": 61 } } @@ -83,62 +82,62 @@ "octane": {}, "oortonline_tbmv2": {}, "power.desktop": { - "end": 4 + "end": 5 } } }, "7": { "benchmarks": { "power.desktop": { - "begin": 4 + "begin": 5 }, "power.typical_10_mobile": {}, "rasterize_and_record_micro.partial_invalidation": {}, "rasterize_and_record_micro.top_25": { - "end": 23 + "end": 24 } } }, "8": { "benchmarks": { "rasterize_and_record_micro.top_25": { - "begin": 23 + "begin": 24 }, "rendering.desktop": { - "end": 52 + "end": 53 } } }, "9": { "benchmarks": { "rendering.desktop": { - "begin": 52, - "end": 109 + "begin": 53, + "end": 111 } } }, "10": { "benchmarks": { "rendering.desktop": { - "begin": 109, - "end": 173 + "begin": 111, + "end": 178 } } }, "11": { "benchmarks": { "rendering.desktop": { - "begin": 173 + "begin": 178 }, "rendering.mobile": { - "end": 67 + "end": 138 } } }, "12": { "benchmarks": { "rendering.mobile": { - "begin": 67 + "begin": 138 }, "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, "smoothness.tough_pinch_zoom_cases": {}, @@ -148,65 +147,65 @@ "speedometer2-future": {}, "startup.mobile": {}, "system_health.common_desktop": { - "end": 16 + "end": 19 } } }, "13": { "benchmarks": { "system_health.common_desktop": { - "begin": 16, - "end": 59 + "begin": 19, + "end": 74 } } }, "14": { "benchmarks": { "system_health.common_desktop": { - "begin": 59 + "begin": 74 }, "system_health.common_mobile": {}, "system_health.memory_desktop": { - "end": 7 + "end": 9 } } }, "15": { "benchmarks": { "system_health.memory_desktop": { - "begin": 7, - "end": 17 + "begin": 9, + "end": 19 } } }, "16": { "benchmarks": { "system_health.memory_desktop": { - "begin": 17, - "end": 35 + "begin": 19, + "end": 43 } } }, "17": { "benchmarks": { "system_health.memory_desktop": { - "begin": 35, - "end": 57 + "begin": 43, + "end": 72 } } }, "18": { "benchmarks": { "system_health.memory_desktop": { - "begin": 57, - "end": 68 + "begin": 72, + "end": 88 } } }, "19": { "benchmarks": { "system_health.memory_desktop": { - "begin": 68 + "begin": 88 }, "system_health.memory_mobile": {}, "system_health.webview_startup": {}, @@ -255,50 +254,50 @@ "benchmarks": { "v8.runtime_stats.top_25": { "begin": 74, - "end": 114 + "end": 113 } } }, "25": { "benchmarks": { "v8.runtime_stats.top_25": { - "begin": 114 + "begin": 113 }, "wasm": {}, "webrtc": {} } }, "extra_infos": { - "num_stories": 1904, - "predicted_min_shard_time": 2782.0, - "predicted_min_shard_index": 14, - "predicted_max_shard_time": 3088.0, + "num_stories": 1953, + "predicted_min_shard_time": 2784.0, + "predicted_min_shard_index": 15, + "predicted_max_shard_time": 3100.0, "predicted_max_shard_index": 21, - "shard #0": 2920.0, - "shard #1": 2912.0, - "shard #2": 2894.0, - "shard #3": 2972.0, + "shard #0": 2928.0, + "shard #1": 2916.0, + "shard #2": 2920.0, + "shard #3": 2888.0, "shard #4": 2940.0, "shard #5": 2878.0, - "shard #6": 2916.0, - "shard #7": 2862.0, - "shard #8": 2952.0, - "shard #9": 2904.0, - "shard #10": 2926.0, - "shard #11": 2930.0, - "shard #12": 2928.0, - "shard #13": 2944.0, - "shard #14": 2782.0, - "shard #15": 3054.0, - "shard #16": 2892.0, - "shard #17": 2892.0, - "shard #18": 3012.0, - "shard #19": 2832.0, - "shard #20": 2804.0, - "shard #21": 3088.0, + "shard #6": 3008.0, + "shard #7": 2926.0, + "shard #8": 2856.0, + "shard #9": 2910.0, + "shard #10": 2962.0, + "shard #11": 2908.0, + "shard #12": 2870.0, + "shard #13": 2862.0, + "shard #14": 3080.0, + "shard #15": 2784.0, + "shard #16": 3048.0, + "shard #17": 2814.0, + "shard #18": 3042.0, + "shard #19": 2850.0, + "shard #20": 2816.0, + "shard #21": 3100.0, "shard #22": 2828.0, "shard #23": 2946.0, - "shard #24": 2958.0, - "shard #25": 2882.0 + "shard #24": 2882.0, + "shard #25": 2958.0 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/mac-10_12_laptop_low_end-perf_map.json b/tools/perf/core/shard_maps/mac-10_12_laptop_low_end-perf_map.json index 2320a5ec..2985eee 100644 --- a/tools/perf/core/shard_maps/mac-10_12_laptop_low_end-perf_map.json +++ b/tools/perf/core/shard_maps/mac-10_12_laptop_low_end-perf_map.json
@@ -9,14 +9,14 @@ "blink_perf.events": {}, "blink_perf.image_decoder": {}, "blink_perf.layout": { - "end": 59 + "end": 60 } } }, "1": { "benchmarks": { "blink_perf.layout": { - "begin": 59 + "begin": 60 }, "blink_perf.owp_storage": {}, "blink_perf.paint": {}, @@ -24,20 +24,19 @@ "blink_perf.shadow_dom": {}, "blink_perf.svg": {}, "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, "dummy_benchmark.noisy_benchmark_1": {}, "dummy_benchmark.stable_benchmark_1": {}, "jetstream": {}, "kraken": {}, "loading.desktop": { - "end": 9 + "end": 10 } } }, "2": { "benchmarks": { "loading.desktop": { - "begin": 9, + "begin": 10, "end": 42 } } @@ -95,116 +94,111 @@ "rasterize_and_record_micro.partial_invalidation": {}, "rasterize_and_record_micro.top_25": {}, "rendering.desktop": { - "end": 21 + "end": 23 } } }, "8": { "benchmarks": { "rendering.desktop": { - "begin": 21, - "end": 71 + "begin": 23, + "end": 72 } } }, "9": { "benchmarks": { "rendering.desktop": { - "begin": 71, - "end": 121 + "begin": 72, + "end": 123 } } }, "10": { "benchmarks": { "rendering.desktop": { - "begin": 121, - "end": 200 + "begin": 123, + "end": 203 } } }, "11": { "benchmarks": { "rendering.desktop": { - "begin": 200 + "begin": 203 }, - "rendering.mobile": { - "end": 421 - } + "rendering.mobile": {}, + "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, + "smoothness.tough_pinch_zoom_cases": {} } }, "12": { "benchmarks": { - "rendering.mobile": { - "begin": 421 - }, - "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, - "smoothness.tough_pinch_zoom_cases": {}, "speedometer": {}, "speedometer-future": {}, "speedometer2": {}, "speedometer2-future": {}, "startup.mobile": {}, "system_health.common_desktop": { - "end": 22 + "end": 26 } } }, "13": { "benchmarks": { "system_health.common_desktop": { - "begin": 22, - "end": 62 + "begin": 26, + "end": 80 } } }, "14": { "benchmarks": { "system_health.common_desktop": { - "begin": 62 + "begin": 80 }, "system_health.common_mobile": {}, "system_health.memory_desktop": { - "end": 10 + "end": 11 } } }, "15": { "benchmarks": { "system_health.memory_desktop": { - "begin": 10, - "end": 19 + "begin": 11, + "end": 25 } } }, "16": { "benchmarks": { "system_health.memory_desktop": { - "begin": 19, - "end": 40 + "begin": 25, + "end": 49 } } }, "17": { "benchmarks": { "system_health.memory_desktop": { - "begin": 40, - "end": 58 + "begin": 49, + "end": 73 } } }, "18": { "benchmarks": { "system_health.memory_desktop": { - "begin": 58, - "end": 65 + "begin": 73, + "end": 83 } } }, "19": { "benchmarks": { "system_health.memory_desktop": { - "begin": 65 + "begin": 83 }, "system_health.memory_mobile": {}, "system_health.webview_startup": {}, @@ -225,14 +219,14 @@ "21": { "benchmarks": { "v8.browsing_desktop-future": { - "end": 20 + "end": 25 } } }, "22": { "benchmarks": { "v8.browsing_desktop-future": { - "begin": 20 + "begin": 25 }, "v8.browsing_mobile": {}, "v8.browsing_mobile-future": {}, @@ -267,34 +261,34 @@ } }, "extra_infos": { - "num_stories": 1904, - "predicted_min_shard_time": 2928.0, + "num_stories": 1953, + "predicted_min_shard_time": 2778.0, "predicted_min_shard_index": 17, - "predicted_max_shard_time": 3780.0, + "predicted_max_shard_time": 3798.0, "predicted_max_shard_index": 18, - "shard #0": 3246.0, - "shard #1": 3264.0, - "shard #2": 3300.0, + "shard #0": 3228.0, + "shard #1": 3322.0, + "shard #2": 3216.0, "shard #3": 3216.0, "shard #4": 3280.0, "shard #5": 3174.0, "shard #6": 3328.0, - "shard #7": 3174.0, - "shard #8": 3252.0, - "shard #9": 3280.0, - "shard #10": 3266.0, - "shard #11": 3244.0, - "shard #12": 3230.0, - "shard #13": 3264.0, - "shard #14": 3408.0, - "shard #15": 3174.0, - "shard #16": 3126.0, - "shard #17": 2928.0, - "shard #18": 3780.0, - "shard #19": 3178.0, - "shard #20": 3234.0, - "shard #21": 3226.0, - "shard #22": 3288.0, + "shard #7": 3286.0, + "shard #8": 3230.0, + "shard #9": 3256.0, + "shard #10": 3274.0, + "shard #11": 3192.0, + "shard #12": 3340.0, + "shard #13": 3230.0, + "shard #14": 3268.0, + "shard #15": 3204.0, + "shard #16": 3330.0, + "shard #17": 2778.0, + "shard #18": 3798.0, + "shard #19": 3208.0, + "shard #20": 3246.0, + "shard #21": 3236.0, + "shard #22": 3290.0, "shard #23": 3198.0, "shard #24": 3270.0, "shard #25": 3226.0
diff --git a/tools/perf/core/shard_maps/mac-10_13_laptop_high_end-perf_map.json b/tools/perf/core/shard_maps/mac-10_13_laptop_high_end-perf_map.json index f741a28a..b3040eb 100644 --- a/tools/perf/core/shard_maps/mac-10_13_laptop_high_end-perf_map.json +++ b/tools/perf/core/shard_maps/mac-10_13_laptop_high_end-perf_map.json
@@ -9,14 +9,14 @@ "blink_perf.events": {}, "blink_perf.image_decoder": {}, "blink_perf.layout": { - "end": 60 + "end": 62 } } }, "1": { "benchmarks": { "blink_perf.layout": { - "begin": 60 + "begin": 62 }, "blink_perf.owp_storage": {}, "blink_perf.paint": {}, @@ -24,28 +24,27 @@ "blink_perf.shadow_dom": {}, "blink_perf.svg": {}, "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, "dummy_benchmark.noisy_benchmark_1": {}, "dummy_benchmark.stable_benchmark_1": {}, "jetstream": {}, "kraken": {}, "loading.desktop": { - "end": 10 + "end": 11 } } }, "2": { "benchmarks": { "loading.desktop": { - "begin": 10, - "end": 44 + "begin": 11, + "end": 45 } } }, "3": { "benchmarks": { "loading.desktop": { - "begin": 44, + "begin": 45, "end": 76 } } @@ -55,16 +54,11 @@ "loading.desktop": { "begin": 76 }, - "loading.mobile": { - "end": 84 - } + "loading.mobile": {} } }, "5": { "benchmarks": { - "loading.mobile": { - "begin": 84 - }, "media.desktop": {}, "media.mobile": {}, "memory.desktop": {} @@ -81,48 +75,48 @@ "power.typical_10_mobile": {}, "rasterize_and_record_micro.partial_invalidation": {}, "rasterize_and_record_micro.top_25": { - "end": 9 + "end": 12 } } }, "7": { "benchmarks": { "rasterize_and_record_micro.top_25": { - "begin": 9 + "begin": 12 }, "rendering.desktop": { - "end": 40 + "end": 41 } } }, "8": { "benchmarks": { "rendering.desktop": { - "begin": 40, - "end": 96 + "begin": 41, + "end": 97 } } }, "9": { "benchmarks": { "rendering.desktop": { - "begin": 96, - "end": 157 + "begin": 97, + "end": 162 } } }, "10": { "benchmarks": { "rendering.desktop": { - "begin": 157, - "end": 237 + "begin": 162, + "end": 238 } } }, "11": { "benchmarks": { "rendering.desktop": { - "begin": 237 + "begin": 238 }, "rendering.mobile": {}, "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, @@ -133,87 +127,87 @@ "speedometer2-future": {}, "startup.mobile": {}, "system_health.common_desktop": { - "end": 12 + "end": 14 } } }, "12": { "benchmarks": { "system_health.common_desktop": { - "begin": 12, - "end": 52 + "begin": 14, + "end": 69 } } }, "13": { "benchmarks": { "system_health.common_desktop": { - "begin": 52 + "begin": 69 }, "system_health.common_mobile": {}, "system_health.memory_desktop": { - "end": 3 + "end": 5 } } }, "14": { "benchmarks": { "system_health.memory_desktop": { - "begin": 3, - "end": 14 + "begin": 5, + "end": 15 } } }, "15": { "benchmarks": { "system_health.memory_desktop": { - "begin": 14, - "end": 29 + "begin": 15, + "end": 36 } } }, "16": { "benchmarks": { "system_health.memory_desktop": { - "begin": 29, - "end": 50 + "begin": 36, + "end": 62 } } }, "17": { "benchmarks": { "system_health.memory_desktop": { - "begin": 50, - "end": 60 + "begin": 62, + "end": 75 } } }, "18": { "benchmarks": { "system_health.memory_desktop": { - "begin": 60, - "end": 67 + "begin": 75, + "end": 87 } } }, "19": { "benchmarks": { "system_health.memory_desktop": { - "begin": 67 + "begin": 87 }, "system_health.memory_mobile": {}, "system_health.webview_startup": {}, "tab_switching.typical_25": {}, "tracing.tracing_with_background_memory_infra": {}, "v8.browsing_desktop": { - "end": 11 + "end": 12 } } }, "20": { "benchmarks": { "v8.browsing_desktop": { - "begin": 11 + "begin": 12 }, "v8.browsing_desktop-future": { "end": 4 @@ -224,14 +218,14 @@ "benchmarks": { "v8.browsing_desktop-future": { "begin": 4, - "end": 22 + "end": 26 } } }, "22": { "benchmarks": { "v8.browsing_desktop-future": { - "begin": 22 + "begin": 26 }, "v8.browsing_mobile": {}, "v8.browsing_mobile-future": {}, @@ -266,34 +260,34 @@ } }, "extra_infos": { - "num_stories": 1904, - "predicted_min_shard_time": 2436.0, + "num_stories": 1953, + "predicted_min_shard_time": 2466.0, "predicted_min_shard_index": 18, - "predicted_max_shard_time": 3204.0, + "predicted_max_shard_time": 3222.0, "predicted_max_shard_index": 17, - "shard #0": 2874.0, - "shard #1": 2826.0, - "shard #2": 2880.0, - "shard #3": 2892.0, - "shard #4": 2848.0, - "shard #5": 2988.0, - "shard #6": 2728.0, - "shard #7": 2910.0, - "shard #8": 2840.0, - "shard #9": 2846.0, - "shard #10": 2906.0, - "shard #11": 2850.0, - "shard #12": 2844.0, - "shard #13": 2858.0, - "shard #14": 2868.0, - "shard #15": 2844.0, - "shard #16": 2976.0, - "shard #17": 3204.0, - "shard #18": 2436.0, - "shard #19": 2944.0, - "shard #20": 2752.0, - "shard #21": 2990.0, - "shard #22": 2802.0, + "shard #0": 2866.0, + "shard #1": 2866.0, + "shard #2": 2896.0, + "shard #3": 2812.0, + "shard #4": 2888.0, + "shard #5": 2948.0, + "shard #6": 2790.0, + "shard #7": 2898.0, + "shard #8": 2828.0, + "shard #9": 2882.0, + "shard #10": 2922.0, + "shard #11": 2838.0, + "shard #12": 2820.0, + "shard #13": 2918.0, + "shard #14": 2718.0, + "shard #15": 3036.0, + "shard #16": 2850.0, + "shard #17": 3222.0, + "shard #18": 2466.0, + "shard #19": 2964.0, + "shard #20": 2762.0, + "shard #21": 2808.0, + "shard #22": 2996.0, "shard #23": 2826.0, "shard #24": 2878.0, "shard #25": 2860.0
diff --git a/tools/perf/core/shard_maps/win-10-perf_map.json b/tools/perf/core/shard_maps/win-10-perf_map.json index e8f67e8..dce7647e 100644 --- a/tools/perf/core/shard_maps/win-10-perf_map.json +++ b/tools/perf/core/shard_maps/win-10-perf_map.json
@@ -9,14 +9,14 @@ "blink_perf.events": {}, "blink_perf.image_decoder": {}, "blink_perf.layout": { - "end": 39 + "end": 40 } } }, "1": { "benchmarks": { "blink_perf.layout": { - "begin": 39 + "begin": 40 }, "blink_perf.owp_storage": {}, "blink_perf.paint": {}, @@ -24,24 +24,27 @@ "blink_perf.shadow_dom": {}, "blink_perf.svg": {}, "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, "dummy_benchmark.noisy_benchmark_1": {}, "dummy_benchmark.stable_benchmark_1": {}, "jetstream": {}, - "kraken": {} + "kraken": {}, + "loading.desktop": { + "end": 1 + } } }, "2": { "benchmarks": { "loading.desktop": { - "end": 36 + "begin": 1, + "end": 37 } } }, "3": { "benchmarks": { "loading.desktop": { - "begin": 36, + "begin": 37, "end": 65 } } @@ -73,12 +76,17 @@ "begin": 2 }, "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {} + "memory.long_running_idle_gmail_tbmv2": {}, + "memory.top_10_mobile": { + "end": 2 + } } }, "7": { "benchmarks": { - "memory.top_10_mobile": {}, + "memory.top_10_mobile": { + "begin": 2 + }, "octane": {}, "oortonline_tbmv2": {}, "power.desktop": {}, @@ -86,48 +94,48 @@ "rasterize_and_record_micro.partial_invalidation": {}, "rasterize_and_record_micro.top_25": {}, "rendering.desktop": { - "end": 1 + "end": 2 } } }, "8": { "benchmarks": { "rendering.desktop": { - "begin": 1, - "end": 56 + "begin": 2, + "end": 57 } } }, "9": { "benchmarks": { "rendering.desktop": { - "begin": 56, - "end": 114 + "begin": 57, + "end": 116 } } }, "10": { "benchmarks": { "rendering.desktop": { - "begin": 114, - "end": 181 + "begin": 116, + "end": 185 } } }, "11": { "benchmarks": { "rendering.desktop": { - "begin": 181 + "begin": 185 }, "rendering.mobile": { - "end": 210 + "end": 269 } } }, "12": { "benchmarks": { "rendering.mobile": { - "begin": 210 + "begin": 269 }, "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, "smoothness.tough_pinch_zoom_cases": {}, @@ -137,65 +145,65 @@ "speedometer2-future": {}, "startup.mobile": {}, "system_health.common_desktop": { - "end": 17 + "end": 20 } } }, "13": { "benchmarks": { "system_health.common_desktop": { - "begin": 17, - "end": 59 + "begin": 20, + "end": 74 } } }, "14": { "benchmarks": { "system_health.common_desktop": { - "begin": 59 + "begin": 74 }, "system_health.common_mobile": {}, "system_health.memory_desktop": { - "end": 7 + "end": 8 } } }, "15": { "benchmarks": { "system_health.memory_desktop": { - "begin": 7, - "end": 16 + "begin": 8, + "end": 19 } } }, "16": { "benchmarks": { "system_health.memory_desktop": { - "begin": 16, - "end": 33 + "begin": 19, + "end": 40 } } }, "17": { "benchmarks": { "system_health.memory_desktop": { - "begin": 33, - "end": 54 + "begin": 40, + "end": 69 } } }, "18": { "benchmarks": { "system_health.memory_desktop": { - "begin": 54, - "end": 63 + "begin": 69, + "end": 80 } } }, "19": { "benchmarks": { "system_health.memory_desktop": { - "begin": 63 + "begin": 80 }, "system_health.memory_mobile": {}, "system_health.webview_startup": {}, @@ -216,14 +224,14 @@ "21": { "benchmarks": { "v8.browsing_desktop-future": { - "end": 19 + "end": 24 } } }, "22": { "benchmarks": { "v8.browsing_desktop-future": { - "begin": 19 + "begin": 24 }, "v8.browsing_mobile": {}, "v8.browsing_mobile-future": {}, @@ -244,50 +252,50 @@ "benchmarks": { "v8.runtime_stats.top_25": { "begin": 66, - "end": 106 + "end": 105 } } }, "25": { "benchmarks": { "v8.runtime_stats.top_25": { - "begin": 106 + "begin": 105 }, "wasm": {}, "webrtc": {} } }, "extra_infos": { - "num_stories": 1904, - "predicted_min_shard_time": 2570.0, + "num_stories": 1953, + "predicted_min_shard_time": 2606.0, "predicted_min_shard_index": 19, - "predicted_max_shard_time": 3012.0, - "predicted_max_shard_index": 18, - "shard #0": 2868.0, - "shard #1": 2770.0, - "shard #2": 2852.0, - "shard #3": 2872.0, + "predicted_max_shard_time": 3132.0, + "predicted_max_shard_index": 15, + "shard #0": 2856.0, + "shard #1": 2874.0, + "shard #2": 2820.0, + "shard #3": 2800.0, "shard #4": 2808.0, "shard #5": 2952.0, - "shard #6": 2770.0, - "shard #7": 2836.0, - "shard #8": 2802.0, - "shard #9": 2866.0, - "shard #10": 2842.0, - "shard #11": 2830.0, - "shard #12": 2870.0, - "shard #13": 2912.0, - "shard #14": 2666.0, - "shard #15": 2838.0, - "shard #16": 2970.0, - "shard #17": 2760.0, - "shard #18": 3012.0, - "shard #19": 2570.0, - "shard #20": 2836.0, - "shard #21": 2838.0, - "shard #22": 2978.0, + "shard #6": 2790.0, + "shard #7": 2828.0, + "shard #8": 2850.0, + "shard #9": 2858.0, + "shard #10": 2852.0, + "shard #11": 2832.0, + "shard #12": 2882.0, + "shard #13": 2784.0, + "shard #14": 2688.0, + "shard #15": 3132.0, + "shard #16": 2712.0, + "shard #17": 2808.0, + "shard #18": 3024.0, + "shard #19": 2606.0, + "shard #20": 2848.0, + "shard #21": 2848.0, + "shard #22": 2980.0, "shard #23": 2830.0, - "shard #24": 2856.0, - "shard #25": 2810.0 + "shard #24": 2794.0, + "shard #25": 2872.0 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/win_7_nvidia_gpu_perf_map.json b/tools/perf/core/shard_maps/win_7_nvidia_gpu_perf_map.json index 92d6488..7cf15934 100644 --- a/tools/perf/core/shard_maps/win_7_nvidia_gpu_perf_map.json +++ b/tools/perf/core/shard_maps/win_7_nvidia_gpu_perf_map.json
@@ -15,21 +15,20 @@ "blink_perf.shadow_dom": {}, "blink_perf.svg": {}, "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, "dummy_benchmark.noisy_benchmark_1": {}, "dummy_benchmark.stable_benchmark_1": {}, "jetstream": {}, "kraken": {}, "loading.desktop": {}, "loading.mobile": { - "end": 82 + "end": 91 } } }, "1": { "benchmarks": { "loading.mobile": { - "begin": 82 + "begin": 91 }, "media.desktop": {}, "media.mobile": {}, @@ -44,14 +43,14 @@ "rasterize_and_record_micro.partial_invalidation": {}, "rasterize_and_record_micro.top_25": {}, "rendering.desktop": { - "end": 158 + "end": 161 } } }, "2": { "benchmarks": { "rendering.desktop": { - "begin": 158 + "begin": 161 }, "rendering.mobile": {}, "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, @@ -64,28 +63,28 @@ "system_health.common_desktop": {}, "system_health.common_mobile": {}, "system_health.memory_desktop": { - "end": 16 + "end": 19 } } }, "3": { "benchmarks": { "system_health.memory_desktop": { - "begin": 16 + "begin": 19 }, "system_health.memory_mobile": {}, "system_health.webview_startup": {}, "tab_switching.typical_25": {}, "tracing.tracing_with_background_memory_infra": {}, "v8.browsing_desktop": { - "end": 20 + "end": 25 } } }, "4": { "benchmarks": { "v8.browsing_desktop": { - "begin": 20 + "begin": 25 }, "v8.browsing_desktop-future": {}, "v8.browsing_mobile": {}, @@ -96,15 +95,15 @@ } }, "extra_infos": { - "num_stories": 1904, - "predicted_min_shard_time": 15154.0, - "predicted_min_shard_index": 2, - "predicted_max_shard_time": 15372.0, - "predicted_max_shard_index": 3, - "shard #0": 15232.0, - "shard #1": 15240.0, - "shard #2": 15154.0, - "shard #3": 15372.0, - "shard #4": 15166.0 + "num_stories": 1953, + "predicted_min_shard_time": 15180.0, + "predicted_min_shard_index": 4, + "predicted_max_shard_time": 15370.0, + "predicted_max_shard_index": 2, + "shard #0": 15254.0, + "shard #1": 15242.0, + "shard #2": 15370.0, + "shard #3": 15220.0, + "shard #4": 15180.0 } } \ No newline at end of file
diff --git a/tools/perf/core/shard_maps/win_7_perf_map.json b/tools/perf/core/shard_maps/win_7_perf_map.json index 7297c940..c63d3d484 100644 --- a/tools/perf/core/shard_maps/win_7_perf_map.json +++ b/tools/perf/core/shard_maps/win_7_perf_map.json
@@ -15,20 +15,19 @@ "blink_perf.shadow_dom": {}, "blink_perf.svg": {}, "dromaeo": {}, - "dummy_benchmark.histogram_benchmark_1": {}, "dummy_benchmark.noisy_benchmark_1": {}, "dummy_benchmark.stable_benchmark_1": {}, "jetstream": {}, "kraken": {}, "loading.desktop": { - "end": 94 + "end": 95 } } }, "1": { "benchmarks": { "loading.desktop": { - "begin": 94 + "begin": 95 }, "loading.mobile": {}, "media.desktop": {}, @@ -44,14 +43,14 @@ "rasterize_and_record_micro.partial_invalidation": {}, "rasterize_and_record_micro.top_25": {}, "rendering.desktop": { - "end": 136 + "end": 138 } } }, "2": { "benchmarks": { "rendering.desktop": { - "begin": 136 + "begin": 138 }, "rendering.mobile": {}, "smoothness.gpu_rasterization.tough_pinch_zoom_cases": {}, @@ -64,28 +63,28 @@ "system_health.common_desktop": {}, "system_health.common_mobile": {}, "system_health.memory_desktop": { - "end": 12 + "end": 14 } } }, "3": { "benchmarks": { "system_health.memory_desktop": { - "begin": 12 + "begin": 14 }, "system_health.memory_mobile": {}, "system_health.webview_startup": {}, "tab_switching.typical_25": {}, "tracing.tracing_with_background_memory_infra": {}, "v8.browsing_desktop": { - "end": 18 + "end": 22 } } }, "4": { "benchmarks": { "v8.browsing_desktop": { - "begin": 18 + "begin": 22 }, "v8.browsing_desktop-future": {}, "v8.browsing_mobile": {}, @@ -96,15 +95,15 @@ } }, "extra_infos": { - "num_stories": 1904, - "predicted_min_shard_time": 15542.0, - "predicted_min_shard_index": 2, - "predicted_max_shard_time": 15804.0, - "predicted_max_shard_index": 4, - "shard #0": 15666.0, - "shard #1": 15762.0, - "shard #2": 15542.0, - "shard #3": 15764.0, - "shard #4": 15804.0 + "num_stories": 1953, + "predicted_min_shard_time": 15490.0, + "predicted_min_shard_index": 3, + "predicted_max_shard_time": 15888.0, + "predicted_max_shard_index": 2, + "shard #0": 15752.0, + "shard #1": 15698.0, + "shard #2": 15888.0, + "shard #3": 15490.0, + "shard #4": 15820.0 } } \ No newline at end of file
diff --git a/tools/perf/core/undocumented_benchmarks.py b/tools/perf/core/undocumented_benchmarks.py index f20dfa7..e0b9659 100644 --- a/tools/perf/core/undocumented_benchmarks.py +++ b/tools/perf/core/undocumented_benchmarks.py
@@ -9,7 +9,6 @@ 'angle_perftests', 'components_perftests', 'dromaeo', - 'dummy_benchmark.histogram_benchmark_1', 'dummy_benchmark.noisy_benchmark_1', 'dummy_benchmark.stable_benchmark_1', 'gpu_perftests',
diff --git a/ui/events/blink/prediction/kalman_predictor.cc b/ui/events/blink/prediction/kalman_predictor.cc index c2d66ac..0d80f7a 100644 --- a/ui/events/blink/prediction/kalman_predictor.cc +++ b/ui/events/blink/prediction/kalman_predictor.cc
@@ -47,15 +47,15 @@ return x_predictor_.Stable() && y_predictor_.Stable(); } -bool KalmanPredictor::GeneratePrediction(base::TimeTicks frame_time, +bool KalmanPredictor::GeneratePrediction(base::TimeTicks predict_time, InputData* result) const { std::vector<InputData> pred_points; - base::TimeDelta dt = frame_time - last_point_.time_stamp; + base::TimeDelta dt = predict_time - last_point_.time_stamp; // Kalman filter is not very good when predicting backwards. Besides, // predicting backwards means increasing latency. Thus disable prediction when // dt < 0. - if (!HasPrediction() || dt < base::TimeDelta::Min() || dt > kMaxResampleTime) + if (!HasPrediction() || dt < base::TimeDelta() || dt > kMaxResampleTime) return false; gfx::Vector2dF position(last_point_.pos.x(), last_point_.pos.y());
diff --git a/ui/events/blink/prediction/kalman_predictor.h b/ui/events/blink/prediction/kalman_predictor.h index cf1edb33..07b783f0 100644 --- a/ui/events/blink/prediction/kalman_predictor.h +++ b/ui/events/blink/prediction/kalman_predictor.h
@@ -33,7 +33,7 @@ // Generate the prediction based on stored points and given time_stamp. // Return false if no prediction available. - bool GeneratePrediction(base::TimeTicks frame_time, + bool GeneratePrediction(base::TimeTicks predict_time, InputData* result) const override; private:
diff --git a/ui/events/blink/prediction/least_squares_predictor.cc b/ui/events/blink/prediction/least_squares_predictor.cc index 534d3de..f6126a5 100644 --- a/ui/events/blink/prediction/least_squares_predictor.cc +++ b/ui/events/blink/prediction/least_squares_predictor.cc
@@ -75,14 +75,14 @@ return x; } -bool LeastSquaresPredictor::GeneratePrediction(base::TimeTicks frame_time, +bool LeastSquaresPredictor::GeneratePrediction(base::TimeTicks predict_time, InputData* result) const { - if (!HasPrediction() || frame_time - time_.back() > kMaxResampleTime) + if (!HasPrediction() || predict_time - time_.back() > kMaxResampleTime) return false; gfx::Matrix3F time_matrix = GetXMatrix(); - double dt = (frame_time - time_[0]).InMillisecondsF(); + double dt = (predict_time - time_[0]).InMillisecondsF(); if (dt > 0) { gfx::Vector3dF b1, b2; if (SolveLeastSquares(time_matrix, x_queue_, b1) &&
diff --git a/ui/events/blink/prediction/least_squares_predictor.h b/ui/events/blink/prediction/least_squares_predictor.h index c5eb33b..edfe8296 100644 --- a/ui/events/blink/prediction/least_squares_predictor.h +++ b/ui/events/blink/prediction/least_squares_predictor.h
@@ -33,7 +33,7 @@ // Generate the prediction based on stored points and given time_stamp. // Return false if no prediction available. - bool GeneratePrediction(base::TimeTicks frame_time, + bool GeneratePrediction(base::TimeTicks predict_time, InputData* result) const override; private:
diff --git a/ui/events/event.cc b/ui/events/event.cc index e8748f6..4987bc3 100644 --- a/ui/events/event.cc +++ b/ui/events/event.cc
@@ -1083,10 +1083,9 @@ // Bit 30 of lParam represents the "previous key state". If set, the key // was already down, therefore this is an auto-repeat. is_repeat = (event.native_event().lParam & 0x40000000) != 0; - } else + } #endif - { - // Note that this is only reach for non-native events under Windows. + if (!is_repeat) { if (event.key_code() == (*last_key_event)->key_code() && event.flags() == ((*last_key_event)->flags() & ~ui::EF_IS_REPEAT) && (event.time_stamp() - (*last_key_event)->time_stamp())
diff --git a/ui/gfx/OWNERS b/ui/gfx/OWNERS index 225898f..26eb0a7 100644 --- a/ui/gfx/OWNERS +++ b/ui/gfx/OWNERS
@@ -28,16 +28,21 @@ per-file gpu_fence*=reveman@chromium.org per-file gpu_fence*=dcastagna@chromium.org per-file gpu_fence*=rjkroege@chromium.org +per-file gpu_fence*=spang@chromium.org per-file gpu_memory_buffer*=reveman@chromium.org per-file gpu_memory_buffer*=dcastagna@chromium.org per-file gpu_memory_buffer*=rjkroege@chromium.org +per-file gpu_memory_buffer*=spang@chromium.org per-file buffer_format*=reveman@chromium.org per-file buffer_format*=dcastagna@chromium.org per-file buffer_format*=rjkroege@chromium.org +per-file buffer_format*=spang@chromium.org per-file *buffer_types.*=reveman@chromium.org per-file *buffer_types.*=dcastagna@chromium.org per-file *buffer_types.*=rjkroege@chromium.org +per-file *buffer_types.*=spang@chromium.org per-file *pixmap.*=rjkroege@chromium.org +per-file *pixmap.*=spang@chromium.org # Vector icons. per-file *vector_icon*=estade@chromium.org
diff --git a/ui/gfx/color_utils.cc b/ui/gfx/color_utils.cc index 6bb5a66..9edd09b 100644 --- a/ui/gfx/color_utils.cc +++ b/ui/gfx/color_utils.cc
@@ -443,7 +443,7 @@ g_color_utils_luma_midpoint = (GetLuma(color) + 255) / 2; } -SkColor GetDarkestColorForTesting() { +SkColor GetDarkestColor() { return g_color_utils_darkest; }
diff --git a/ui/gfx/color_utils.h b/ui/gfx/color_utils.h index 75e2e83d..80b3504 100644 --- a/ui/gfx/color_utils.h +++ b/ui/gfx/color_utils.h
@@ -189,7 +189,7 @@ GFX_EXPORT void SetDarkestColor(SkColor color); // Returns the current color_utils darkest color so tests can clean up. -GFX_EXPORT SkColor GetDarkestColorForTesting(); +GFX_EXPORT SkColor GetDarkestColor(); } // namespace color_utils
diff --git a/ui/gfx/color_utils_unittest.cc b/ui/gfx/color_utils_unittest.cc index bb0a542..bb39cacb 100644 --- a/ui/gfx/color_utils_unittest.cc +++ b/ui/gfx/color_utils_unittest.cc
@@ -205,7 +205,7 @@ } TEST(ColorUtils, IsDarkDarkestColorChange) { - SkColor old_black_color = GetDarkestColorForTesting(); + SkColor old_black_color = GetDarkestColor(); ASSERT_FALSE(IsDark(SkColorSetARGB(255, 200, 200, 200))); SetDarkestColor(SkColorSetARGB(255, 200, 200, 200)); @@ -236,7 +236,7 @@ } TEST(ColorUtils, GetColorWithMinimumContrast_StopsAtDarkestColor) { - SkColor old_black_color = GetDarkestColorForTesting(); + SkColor old_black_color = GetDarkestColor(); const SkColor darkest_color = SkColorSetRGB(0x44, 0x44, 0x44); SetDarkestColor(darkest_color);
diff --git a/ui/gfx/linux/OWNERS b/ui/gfx/linux/OWNERS index 2d13a90..7543e31d 100644 --- a/ui/gfx/linux/OWNERS +++ b/ui/gfx/linux/OWNERS
@@ -3,3 +3,4 @@ dnicoara@chromium.org reveman@chromium.org rjkroege@chromium.org +spang@chromium.org
diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h index 21fd6e30..ae88b309 100644 --- a/ui/gl/gl_bindings.h +++ b/ui/gl/gl_bindings.h
@@ -440,6 +440,8 @@ #define GL_MAX_VIEWS_OVR 0x9631 #define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 +#define GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT 0x8868 + // Forward declare EGL types. typedef uint64_t EGLuint64CHROMIUM;
diff --git a/ui/latency/ipc/latency_info_param_traits_macros.h b/ui/latency/ipc/latency_info_param_traits_macros.h index b70087b..975d7fc 100644 --- a/ui/latency/ipc/latency_info_param_traits_macros.h +++ b/ui/latency/ipc/latency_info_param_traits_macros.h
@@ -11,7 +11,6 @@ IPC_ENUM_TRAITS_MAX_VALUE(ui::LatencyComponentType, ui::LATENCY_COMPONENT_TYPE_LAST) -IPC_ENUM_TRAITS_MAX_VALUE(ui::SourceEventType, - ui::SourceEventType::SOURCE_EVENT_TYPE_LAST) +IPC_ENUM_TRAITS_MAX_VALUE(ui::SourceEventType, ui::SourceEventType::LAST) #endif // UI_LATENCY_IPC_LATENCY_INFO_PARAM_TRAITS_MACROS_H_
diff --git a/ui/latency/latency_info.h b/ui/latency/latency_info.h index eade9fb..f69bb917 100644 --- a/ui/latency/latency_info.h +++ b/ui/latency/latency_info.h
@@ -93,7 +93,7 @@ LATENCY_COMPONENT_TYPE_LAST = INPUT_EVENT_LATENCY_FRAME_SWAP_COMPONENT, }; -enum SourceEventType { +enum class SourceEventType { UNKNOWN, WHEEL, MOUSE, @@ -104,7 +104,7 @@ TOUCHPAD, FRAME, OTHER, - SOURCE_EVENT_TYPE_LAST = OTHER, + LAST = OTHER, }; class LatencyInfo {
diff --git a/ui/latency/mojo/latency_info_struct_traits.cc b/ui/latency/mojo/latency_info_struct_traits.cc index a1ac873..680356c 100644 --- a/ui/latency/mojo/latency_info_struct_traits.cc +++ b/ui/latency/mojo/latency_info_struct_traits.cc
@@ -12,23 +12,23 @@ ui::mojom::SourceEventType UISourceEventTypeToMojo(ui::SourceEventType type) { switch (type) { - case ui::UNKNOWN: + case ui::SourceEventType::UNKNOWN: return ui::mojom::SourceEventType::UNKNOWN; - case ui::WHEEL: + case ui::SourceEventType::WHEEL: return ui::mojom::SourceEventType::WHEEL; - case ui::MOUSE: + case ui::SourceEventType::MOUSE: return ui::mojom::SourceEventType::MOUSE; - case ui::TOUCH: + case ui::SourceEventType::TOUCH: return ui::mojom::SourceEventType::TOUCH; - case ui::INERTIAL: + case ui::SourceEventType::INERTIAL: return ui::mojom::SourceEventType::INERTIAL; - case ui::KEY_PRESS: + case ui::SourceEventType::KEY_PRESS: return ui::mojom::SourceEventType::KEY_PRESS; - case ui::TOUCHPAD: + case ui::SourceEventType::TOUCHPAD: return ui::mojom::SourceEventType::TOUCHPAD; - case ui::FRAME: + case ui::SourceEventType::FRAME: return ui::mojom::SourceEventType::FRAME; - case ui::OTHER: + case ui::SourceEventType::OTHER: return ui::mojom::SourceEventType::OTHER; } NOTREACHED(); @@ -38,23 +38,23 @@ ui::SourceEventType MojoSourceEventTypeToUI(ui::mojom::SourceEventType type) { switch (type) { case ui::mojom::SourceEventType::UNKNOWN: - return ui::UNKNOWN; + return ui::SourceEventType::UNKNOWN; case ui::mojom::SourceEventType::WHEEL: - return ui::WHEEL; + return ui::SourceEventType::WHEEL; case ui::mojom::SourceEventType::MOUSE: - return ui::MOUSE; + return ui::SourceEventType::MOUSE; case ui::mojom::SourceEventType::TOUCH: - return ui::TOUCH; + return ui::SourceEventType::TOUCH; case ui::mojom::SourceEventType::INERTIAL: - return ui::INERTIAL; + return ui::SourceEventType::INERTIAL; case ui::mojom::SourceEventType::KEY_PRESS: - return ui::KEY_PRESS; + return ui::SourceEventType::KEY_PRESS; case ui::mojom::SourceEventType::TOUCHPAD: - return ui::TOUCHPAD; + return ui::SourceEventType::TOUCHPAD; case ui::mojom::SourceEventType::FRAME: - return ui::FRAME; + return ui::SourceEventType::FRAME; case ui::mojom::SourceEventType::OTHER: - return ui::OTHER; + return ui::SourceEventType::OTHER; } NOTREACHED(); return ui::SourceEventType::UNKNOWN;
diff --git a/ui/latency/mojo/latency_info_struct_traits.h b/ui/latency/mojo/latency_info_struct_traits.h index 00ab6f2..c6d9e7db 100644 --- a/ui/latency/mojo/latency_info_struct_traits.h +++ b/ui/latency/mojo/latency_info_struct_traits.h
@@ -15,7 +15,7 @@ "Enum size mismatch"); static_assert(static_cast<int>(ui::mojom::SourceEventType::kMaxValue) == - static_cast<int>(ui::SOURCE_EVENT_TYPE_LAST), + static_cast<int>(ui::SourceEventType::LAST), "Enum size mismatch"); template <>
diff --git a/ui/latency/mojo/struct_traits_unittest.cc b/ui/latency/mojo/struct_traits_unittest.cc index b764b6e5..4f03eecc 100644 --- a/ui/latency/mojo/struct_traits_unittest.cc +++ b/ui/latency/mojo/struct_traits_unittest.cc
@@ -52,7 +52,7 @@ EXPECT_EQ(10, latency.ukm_source_id()); EXPECT_TRUE(latency.terminated()); - latency.set_source_event_type(ui::TOUCH); + latency.set_source_event_type(ui::SourceEventType::TOUCH); mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy(); LatencyInfo output;
diff --git a/ui/views/controls/webview/unhandled_keyboard_event_handler.cc b/ui/views/controls/webview/unhandled_keyboard_event_handler.cc index d7bd9365..80ce19e 100644 --- a/ui/views/controls/webview/unhandled_keyboard_event_handler.cc +++ b/ui/views/controls/webview/unhandled_keyboard_event_handler.cc
@@ -16,12 +16,12 @@ UnhandledKeyboardEventHandler::~UnhandledKeyboardEventHandler() { } -void UnhandledKeyboardEventHandler::HandleKeyboardEvent( +bool UnhandledKeyboardEventHandler::HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event, FocusManager* focus_manager) { if (!focus_manager) { NOTREACHED(); - return; + return false; } // Previous calls to TranslateMessage can generate Char events as well as // RawKeyDown events, even if the latter triggered an accelerator. In these @@ -29,7 +29,7 @@ if (event.GetType() == blink::WebInputEvent::kChar && ignore_next_char_event_) { ignore_next_char_event_ = false; - return; + return false; } // It's necessary to reset this flag, because a RawKeyDown event may not // always generate a Char event. @@ -45,9 +45,8 @@ // set the flag and fix it if no event was handled. ignore_next_char_event_ = true; - if (focus_manager->ProcessAccelerator(accelerator)) { - return; - } + if (focus_manager->ProcessAccelerator(accelerator)) + return true; // ProcessAccelerator didn't handle the accelerator, so we know both // that |this| is still valid, and that we didn't want to set the flag. @@ -55,7 +54,9 @@ } if (event.os_event && !event.skip_in_browser) - HandleNativeKeyboardEvent(event.os_event, focus_manager); + return HandleNativeKeyboardEvent(event.os_event, focus_manager); + + return false; } } // namespace views
diff --git a/ui/views/controls/webview/unhandled_keyboard_event_handler.h b/ui/views/controls/webview/unhandled_keyboard_event_handler.h index 8f06105..67cb6563 100644 --- a/ui/views/controls/webview/unhandled_keyboard_event_handler.h +++ b/ui/views/controls/webview/unhandled_keyboard_event_handler.h
@@ -23,12 +23,12 @@ UnhandledKeyboardEventHandler(); ~UnhandledKeyboardEventHandler(); - void HandleKeyboardEvent(const content::NativeWebKeyboardEvent& event, + bool HandleKeyboardEvent(const content::NativeWebKeyboardEvent& event, FocusManager* focus_manager); private: // Platform specific handling for unhandled keyboard events. - static void HandleNativeKeyboardEvent(gfx::NativeEvent event, + static bool HandleNativeKeyboardEvent(gfx::NativeEvent event, FocusManager* focus_manager); // Whether to ignore the next Char keyboard event.
diff --git a/ui/views/controls/webview/unhandled_keyboard_event_handler_default.cc b/ui/views/controls/webview/unhandled_keyboard_event_handler_default.cc index 8d30e36..f6cb4a38 100644 --- a/ui/views/controls/webview/unhandled_keyboard_event_handler_default.cc +++ b/ui/views/controls/webview/unhandled_keyboard_event_handler_default.cc
@@ -10,10 +10,10 @@ namespace views { // static -void UnhandledKeyboardEventHandler::HandleNativeKeyboardEvent( +bool UnhandledKeyboardEventHandler::HandleNativeKeyboardEvent( gfx::NativeEvent event, FocusManager* focus_manager) { - focus_manager->OnKeyEvent(*static_cast<ui::KeyEvent*>(event)); + return !focus_manager->OnKeyEvent(*(event->AsKeyEvent())); } } // namespace views
diff --git a/ui/views/controls/webview/unhandled_keyboard_event_handler_mac.mm b/ui/views/controls/webview/unhandled_keyboard_event_handler_mac.mm index e87f913..5e004e41 100644 --- a/ui/views/controls/webview/unhandled_keyboard_event_handler_mac.mm +++ b/ui/views/controls/webview/unhandled_keyboard_event_handler_mac.mm
@@ -10,11 +10,12 @@ namespace views { // static -void UnhandledKeyboardEventHandler::HandleNativeKeyboardEvent( +bool UnhandledKeyboardEventHandler::HandleNativeKeyboardEvent( gfx::NativeEvent event, FocusManager* focus_manager) { [[base::mac::ObjCCastStrict<NativeWidgetMacNSWindow>([event window]) commandDispatcher] redispatchKeyEvent:event]; + return true; } } // namespace views
diff --git a/ui/views/controls/webview/unhandled_keyboard_event_handler_win.cc b/ui/views/controls/webview/unhandled_keyboard_event_handler_win.cc index e31aabb..04f7604c 100644 --- a/ui/views/controls/webview/unhandled_keyboard_event_handler_win.cc +++ b/ui/views/controls/webview/unhandled_keyboard_event_handler_win.cc
@@ -9,13 +9,14 @@ namespace views { // static -void UnhandledKeyboardEventHandler::HandleNativeKeyboardEvent( +bool UnhandledKeyboardEventHandler::HandleNativeKeyboardEvent( gfx::NativeEvent event, FocusManager* focus_manager) { // Any unhandled keyboard/character messages should be defproced. // This allows stuff like F10, etc to work correctly. const MSG& message(event->native_event()); DefWindowProc(message.hwnd, message.message, message.wParam, message.lParam); + return true; } } // namespace views
diff --git a/ui/views/controls/webview/web_dialog_view.cc b/ui/views/controls/webview/web_dialog_view.cc index 56fc98b2..e2023e4 100644 --- a/ui/views/controls/webview/web_dialog_view.cc +++ b/ui/views/controls/webview/web_dialog_view.cc
@@ -287,12 +287,13 @@ // A simplified version of BrowserView::HandleKeyboardEvent(). // We don't handle global keyboard shortcuts here, but that's fine since // they're all browser-specific. (This may change in the future.) -void WebDialogView::HandleKeyboardEvent(content::WebContents* source, +bool WebDialogView::HandleKeyboardEvent(content::WebContents* source, const NativeWebKeyboardEvent& event) { if (!event.os_event) - return; + return false; GetWidget()->native_widget_private()->RepostNativeEvent(event.os_event); + return true; } void WebDialogView::CloseContents(WebContents* source) {
diff --git a/ui/views/controls/webview/web_dialog_view.h b/ui/views/controls/webview/web_dialog_view.h index 29d18cb..6467993 100644 --- a/ui/views/controls/webview/web_dialog_view.h +++ b/ui/views/controls/webview/web_dialog_view.h
@@ -97,7 +97,7 @@ // Overridden from content::WebContentsDelegate: void SetContentsBounds(content::WebContents* source, const gfx::Rect& bounds) override; - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; void CloseContents(content::WebContents* source) override;
diff --git a/ui/views/examples/webview_example.cc b/ui/views/examples/webview_example.cc index f23b646f..3910b87 100644 --- a/ui/views/examples/webview_example.cc +++ b/ui/views/examples/webview_example.cc
@@ -31,10 +31,10 @@ webview_->GetWebContents()->Focus(); } -void WebViewExample::HandleKeyboardEvent( +bool WebViewExample::HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { - unhandled_keyboard_event_handler_.HandleKeyboardEvent( + return unhandled_keyboard_event_handler_.HandleKeyboardEvent( event, webview_->GetFocusManager()); }
diff --git a/ui/views/examples/webview_example.h b/ui/views/examples/webview_example.h index f04c87e..600feaa1 100644 --- a/ui/views/examples/webview_example.h +++ b/ui/views/examples/webview_example.h
@@ -28,7 +28,7 @@ void CreateExampleView(View* container) override; // content::WebContentsDelegate: - void HandleKeyboardEvent( + bool HandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override;
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc index 19b02d6..5fef993 100644 --- a/ui/views/widget/widget_unittest.cc +++ b/ui/views/widget/widget_unittest.cc
@@ -1915,10 +1915,12 @@ // View: void OnEvent(ui::Event* event) override { - // Guard against attempting to close the widget twice. - if (widget_) - widget_->CloseNow(); - widget_ = nullptr; + // Guard against closing twice and writing to freed memory. + if (widget_ && event->type() == ui::ET_MOUSE_PRESSED) { + Widget* widget = widget_; + widget_ = nullptr; + widget->CloseNow(); + } } private:
diff --git a/ui/views_bridge_mac/bridge_factory_impl.mm b/ui/views_bridge_mac/bridge_factory_impl.mm index 323abef..47e1e56 100644 --- a/ui/views_bridge_mac/bridge_factory_impl.mm +++ b/ui/views_bridge_mac/bridge_factory_impl.mm
@@ -67,7 +67,8 @@ void BridgeFactoryImpl::BindRequest( mojom::BridgeFactoryAssociatedRequest request) { - binding_.Bind(std::move(request)); + binding_.Bind(std::move(request), + ui::WindowResizeHelperMac::Get()->task_runner()); } void BridgeFactoryImpl::CreateBridgedNativeWidget(