diff --git a/BUILD.gn b/BUILD.gn index 281dccc8a..8571278 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -218,7 +218,9 @@ } else if (is_fuchsia) { deps += [ ":d8_fuchsia", - "build/fuchsia/fidlgen_js:fidlgen_js_unittests", + "//build/fuchsia/fidlgen_js:fidlgen_js_unittests", + "//fuchsia:gn_all", + "//headless", ] } @@ -763,15 +765,6 @@ } } - if (is_fuchsia) { - deps += [ - "//fuchsia:webrunner_unittests", - "//fuchsia/http:http_service_tests", - "//fuchsia/runners:cast_runner_unittests", - "//headless", - ] - } - if (enable_vulkan) { deps += [ "//gpu/vulkan/demo" ] }
diff --git a/DEPS b/DEPS index 37fe6b9..9b8bbcec 100644 --- a/DEPS +++ b/DEPS
@@ -121,11 +121,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'd20cf33472417ef8156553033f5faa2f2d8850bb', + 'skia_revision': '1345366c21ea285b4225ce9bf0de4ef401d76d72', # 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': 'd00f37dbe0937f28b8d74e49506789bbd16ff8b5', + 'v8_revision': '8aa4af2f9d67491825b354b6c7207ed47e0595f5', # 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. @@ -141,11 +141,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '5ebd2c0fafca2f0d570ca25605092b5c7aaadd42', + 'swiftshader_revision': 'ebe5f7fad06476b2828271977ee0d56ee45385ac', # 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': '96a7c58e4c7196b2f789b3e7177f580caed3417d', + 'pdfium_revision': 'a2e2d7f291cfa232c3e5ef48d086c0002b0e06df', # 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. @@ -694,7 +694,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'baf62c129325a527911fa12a625498ecb5cd39a8', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '6e669b46b4792ae79198377d36757053c9b445aa', 'condition': 'checkout_linux', }, @@ -1054,7 +1054,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'faa547c0731a568980a712c238b22692d29649f4', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '11f908788289acc0e395bdfc38fdf19fecfeec26', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1217,7 +1217,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'db52df17f0d012983dc281e4864c71485a86bd0e', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '9f3a44f5152816e3a0cb6902e0dadf365ff4e7d0', + Var('webrtc_git') + '/src.git' + '@' + '01f64e0eb22d855fc769b6976ba62dd0d94a071a', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1258,7 +1258,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0ec02f9abd06dcf9f97c6612927cd537d12baaad', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@26fd840339f85a6169bbbc0cd0d4cd2d847ea0e5', 'condition': 'checkout_src_internal', },
diff --git a/OWNERS b/OWNERS index e2b9e16..61637e8 100644 --- a/OWNERS +++ b/OWNERS
@@ -13,7 +13,6 @@ per-file .vpython=dpranke@chromium.org per-file .vpython=iannucci@chromium.org per-file .vpython=jbudorick@chromium.org -per-file .vpython=nednguyen@chromium.org per-file AUTHORS=* per-file BUILD.gn=file://build/OWNERS per-file codereview.settings=agable@chromium.org
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java b/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java index 3a9cc34b..18db7a5 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java
@@ -19,6 +19,8 @@ import org.chromium.base.MemoryPressureLevel; import org.chromium.base.ThreadUtils; import org.chromium.base.memory.MemoryPressureMonitor; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.List; @@ -70,7 +72,7 @@ public void freeMemoryForTests() { if (ActivityManager.isRunningInTestHarness()) { - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { // This variable is needed to prevent weird formatting by "git cl format". MemoryPressureMonitor pressureMonitor = MemoryPressureMonitor.INSTANCE; pressureMonitor.notifyPressure(MemoryPressureLevel.CRITICAL);
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java index 59c739c9..ee1f234d 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromium.java
@@ -67,9 +67,11 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.CachedMetrics.EnumeratedHistogramSample; import org.chromium.base.metrics.CachedMetrics.TimesHistogramSample; +import org.chromium.base.task.PostTask; import org.chromium.components.autofill.AutofillProvider; import org.chromium.content_public.browser.NavigationHistory; import org.chromium.content_public.browser.SmartClipProvider; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.io.BufferedWriter; import java.io.File; @@ -428,7 +430,7 @@ private void checkThread() { if (!ThreadUtils.runningOnUiThread()) { final RuntimeException threadViolation = createThreadException(); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { throw threadViolation; @@ -2306,7 +2308,7 @@ public void setBackgroundColor(final int color) { mFactory.startYourEngines(false); if (checkNeedsPost()) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { setBackgroundColor(color); @@ -2323,7 +2325,7 @@ // is still null. We set the layer type in initForReal in that case. if (mAwContents == null) return; if (checkNeedsPost()) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { setLayerType(layerType, paint);
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java index a873c92..20a6636 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java
@@ -48,6 +48,8 @@ import org.chromium.base.metrics.CachedMetrics; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.net.NetworkChangeNotifier; /** @@ -280,7 +282,7 @@ // We must post to the UI thread to cover the case that the user has invoked Chromium // startup by using the (thread-safe) CookieManager rather than creating a WebView. - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { synchronized (mLock) { @@ -457,7 +459,7 @@ return; } - ThreadUtils.postOnUiThread(() -> FieldTrialList.logActiveTrials()); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> FieldTrialList.logActiveTrials()); }); }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java index 7cb28892..ffa63d1 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java
@@ -51,8 +51,9 @@ import org.chromium.android_webview.permission.Resource; import org.chromium.base.Callback; import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.lang.ref.WeakReference; import java.security.Principal; @@ -433,14 +434,11 @@ // no further updates after onPageStarted, we'll fail the test by timing // out waiting for a Picture. if (mPictureListener != null) { - ThreadUtils.postOnUiThreadDelayed(new Runnable() { - @Override - public void run() { - if (mPictureListener != null) { - if (TRACE) Log.i(TAG, "onPageFinished-fake"); - mPictureListener.onNewPicture(mWebView, - mPictureListenerInvalidateOnly ? null : new Picture()); - } + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, () -> { + if (mPictureListener != null) { + if (TRACE) Log.i(TAG, "onPageFinished-fake"); + mPictureListener.onNewPicture( + mWebView, mPictureListenerInvalidateOnly ? null : new Picture()); } }, 100); }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index fad31c8..f8df2c5 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -59,6 +59,7 @@ import org.chromium.base.annotations.JNINamespace; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.PostTask; import org.chromium.components.autofill.AutofillProvider; import org.chromium.components.navigation_interception.InterceptNavigationDelegate; import org.chromium.components.navigation_interception.NavigationParams; @@ -77,6 +78,7 @@ import org.chromium.content_public.browser.SelectionClient; import org.chromium.content_public.browser.SelectionPopupController; import org.chromium.content_public.browser.SmartClipProvider; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.ViewEventSink; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsAccessibility; @@ -1838,7 +1840,7 @@ // This is a workaround for an issue with PlzNavigate and one of Samsung's OEM mail apps. // See http://crbug.com/781535. if (isSamsungMailApp() && SAMSUNG_WORKAROUND_BASE_URL.equals(loadUrlParams.getBaseUrl())) { - ThreadUtils.postOnUiThreadDelayed( + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, () -> loadUrl(loadUrlParams), SAMSUNG_WORKAROUND_DELAY); return; }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwGeolocationPermissions.java b/android_webview/java/src/org/chromium/android_webview/AwGeolocationPermissions.java index 6587df2..15e0365 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwGeolocationPermissions.java +++ b/android_webview/java/src/org/chromium/android_webview/AwGeolocationPermissions.java
@@ -6,7 +6,8 @@ import android.content.SharedPreferences; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.net.GURLUtils; import java.util.HashSet; @@ -100,7 +101,7 @@ */ public void getAllowed(String origin, final org.chromium.base.Callback<Boolean> callback) { final boolean finalAllowed = isOriginAllowed(origin); - ThreadUtils.postOnUiThread(() -> callback.onResult(finalAllowed)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> callback.onResult(finalAllowed)); } /** @@ -113,7 +114,7 @@ origins.add(name.substring(PREF_PREFIX.length())); } } - ThreadUtils.postOnUiThread(() -> callback.onResult(origins)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> callback.onResult(origins)); } /**
diff --git a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java index 0422649f..dc410ea 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java +++ b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
@@ -5,7 +5,8 @@ package org.chromium.android_webview; import org.chromium.android_webview.AwContents.VisualStateCallback; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsObserver; import org.chromium.content_public.common.ContentUrlConstants; @@ -121,7 +122,7 @@ // Only invoke the onPageCommitVisible callback when navigating to a different document, // but not when navigating to a different fragment within the same document. if (!isSameDocument) { - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { AwContents awContents = mAwContents.get(); if (awContents != null) { awContents.insertVisualStateCallbackIfNotDestroyed(
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java index d5e813b9..5840b9f 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/VisualStateTest.java
@@ -27,10 +27,12 @@ import org.chromium.android_webview.test.util.GraphicsTestUtils; import org.chromium.android_webview.test.util.JavascriptEventObserver; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.Feature; import org.chromium.content_public.browser.JavascriptInjector; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.test.util.DOMUtils; @@ -108,7 +110,8 @@ @Override public InputStream getData() { final DelayedInputStream stream = (DelayedInputStream) super.getData(); - ThreadUtils.postOnUiThreadDelayed(() -> stream.allowReads(), IMAGE_LOADING_DELAY_MS); + PostTask.postDelayedTask( + UiThreadTaskTraits.DEFAULT, () -> stream.allowReads(), IMAGE_LOADING_DELAY_MS); return stream; } } @@ -427,7 +430,7 @@ // JS will notify this observer once it has changed the background color of the page. final Object pageChangeNotifier = new Object() { public void onPageChanged() { - ThreadUtils.postOnUiThread( + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> awContents.insertVisualStateCallback(20, new VisualStateCallback() { @Override public void onComplete(long id) {
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 17631d33..93f9ea74 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1391,8 +1391,9 @@ testonly = true sources = [ "../ui/views/test/test_views_delegate_aura.cc", - "shell/app_list.cc", "shell/bubble.cc", + "shell/example_app_list_client.cc", + "shell/example_app_list_client.h", "shell/example_factory.h", "shell/example_session_controller_client.cc", "shell/example_session_controller_client.h",
diff --git a/ash/app_list/model/search/search_result.h b/ash/app_list/model/search/search_result.h index f3f7760..d3255cc 100644 --- a/ash/app_list/model/search/search_result.h +++ b/ash/app_list/model/search/search_result.h
@@ -141,6 +141,9 @@ ash::mojom::SearchResultMetadataPtr TakeMetadata() { return std::move(metadata_); } + ash::mojom::SearchResultMetadataPtr CloneMetadata() const { + return metadata_->Clone(); + } protected: void set_id(const std::string& id) { metadata_->id = id; }
diff --git a/ash/app_list/test/test_app_list_client.cc b/ash/app_list/test/test_app_list_client.cc index f54e2995..f800f497 100644 --- a/ash/app_list/test/test_app_list_client.cc +++ b/ash/app_list/test/test_app_list_client.cc
@@ -4,7 +4,7 @@ #include "ash/app_list/test/test_app_list_client.h" -#include "ash/shell.h" +#include <utility> namespace ash { @@ -18,4 +18,16 @@ return ptr; } +void TestAppListClient::GetSearchResultContextMenuModel( + const std::string& result_id, + GetContextMenuModelCallback callback) { + std::move(callback).Run({}); +} + +void TestAppListClient::GetContextMenuModel( + const std::string& id, + GetContextMenuModelCallback callback) { + std::move(callback).Run({}); +} + } // namespace ash
diff --git a/ash/app_list/test/test_app_list_client.h b/ash/app_list/test/test_app_list_client.h index 098c89f..28752b90 100644 --- a/ash/app_list/test/test_app_list_client.h +++ b/ash/app_list/test/test_app_list_client.h
@@ -33,7 +33,7 @@ int event_flags) override {} void GetSearchResultContextMenuModel( const std::string& result_id, - GetContextMenuModelCallback callback) override {} + GetContextMenuModelCallback callback) override; void SearchResultContextMenuItemSelected(const std::string& result_id, int command_id, int event_flags) override {} @@ -41,7 +41,7 @@ void ViewShown(int64_t display_id) override {} void ActivateItem(const std::string& id, int event_flags) override {} void GetContextMenuModel(const std::string& id, - GetContextMenuModelCallback callback) override {} + GetContextMenuModelCallback callback) override; void ContextMenuItemSelected(const std::string& id, int command_id, int event_flags) override {}
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index 8963047f..6d7b026 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -88,9 +88,6 @@ constexpr float kAppListAnimationDurationMs = 200; constexpr float kAppListAnimationDurationFromFullscreenMs = 250; -// The background corner radius in peeking and fullscreen state. -constexpr int kAppListBackgroundRadius = 28; - // Events within this threshold from the top of the view will be reserved for // home launcher gestures, if they can be processed. constexpr int kAppListHomeLaucherGesturesThreshold = 32; @@ -1225,6 +1222,12 @@ RecordStateTransitionForUma(new_state_override); model_->SetStateFullscreen(new_state_override); app_list_state_ = new_state_override; + + // Animations are skipped for side shelf mode, so trigger a layout to update + // children immediately. + if (is_side_shelf_) + Layout(); + if (new_state_override == AppListViewState::CLOSED) { return; }
diff --git a/ash/app_list/views/app_list_view.h b/ash/app_list/views/app_list_view.h index 1065c5e..cc8e466 100644 --- a/ash/app_list/views/app_list_view.h +++ b/ash/app_list/views/app_list_view.h
@@ -43,6 +43,11 @@ class SearchModel; class TransitionAnimationObserver; +namespace { +// The background corner radius in peeking and fullscreen state. +constexpr int kAppListBackgroundRadius = 28; +} + // AppListView is the top-level view and controller of app list UI. It creates // and hosts a AppsGridView and passes AppListModel to it for display. // TODO(newcomer|weidongg): Organize the cc file to match the order of @@ -241,6 +246,10 @@ onscreen_keyboard_shown_ = onscreen_keyboard_shown; } + int get_background_radius_for_test() const { + return kAppListBackgroundRadius; + } + views::View* GetAppListBackgroundShieldForTest(); SkColor GetAppListBackgroundShieldColorForTest();
diff --git a/ash/app_list/views/app_list_view_unittest.cc b/ash/app_list/views/app_list_view_unittest.cc index a148dd9..685c62e 100644 --- a/ash/app_list/views/app_list_view_unittest.cc +++ b/ash/app_list/views/app_list_view_unittest.cc
@@ -1342,13 +1342,22 @@ ASSERT_EQ(AppListViewState::PEEKING, view_->app_list_state()); } -// Tests that in side shelf mode, the app list opens in fullscreen by default. +// Tests that in side shelf mode, the app list opens in fullscreen by default +// and verifies that the top rounded corners of the app list background are +// hidden (see https://crbug.com/920082). TEST_F(AppListViewTest, ShowFullscreenWhenInSideShelfMode) { Initialize(0, false, true); Show(); - ASSERT_EQ(AppListViewState::FULLSCREEN_ALL_APPS, view_->app_list_state()); + EXPECT_EQ(AppListViewState::FULLSCREEN_ALL_APPS, view_->app_list_state()); + + // Get the end point of the rounded corner and transform it into screen + // coordinates. It should be on the screen's bottom line. + gfx::PointF end_of_rounded_corner(0, view_->get_background_radius_for_test()); + view_->GetAppListBackgroundShieldForTest()->GetTransform().TransformPoint( + &end_of_rounded_corner); + EXPECT_EQ(0.0f, end_of_rounded_corner.y()); } // Tests that in tablet mode, the app list opens in fullscreen by default.
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index 94f721b..b9899255 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -48,6 +48,7 @@ #include "ui/display/manager/display_manager.h" #include "ui/display/manager/managed_display_info.h" #include "ui/gfx/geometry/insets.h" +#include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/vector2d.h" @@ -358,15 +359,25 @@ Shell::Get()->login_screen_controller()->AddObserver(this); Shell::Get()->system_tray_notifier()->AddSystemTrayFocusObserver(this); keyboard::KeyboardController::Get()->AddObserver(this); - auth_error_bubble_ = LoginErrorBubble::CreateDefault(); - supervised_user_deprecation_bubble_ = LoginErrorBubble::CreateDefault(); + + auth_error_bubble_ = new LoginErrorBubble(); + AddChildView(auth_error_bubble_); + + supervised_user_deprecation_bubble_ = new LoginErrorBubble(); supervised_user_deprecation_bubble_->SetPersistent(true); - detachable_base_error_bubble_ = LoginErrorBubble::CreateDefault(); + AddChildView(supervised_user_deprecation_bubble_); + + detachable_base_error_bubble_ = new LoginErrorBubble(); detachable_base_error_bubble_->SetPersistent(true); + AddChildView(detachable_base_error_bubble_); + tooltip_bubble_ = new LoginTooltipView(base::UTF8ToUTF16("") /*message*/, nullptr /*anchor_view*/); - warning_banner_bubble_ = LoginErrorBubble::CreateDefault(); + AddChildView(tooltip_bubble_); + + warning_banner_bubble_ = new LoginErrorBubble(); warning_banner_bubble_->SetPersistent(true); + AddChildView(warning_banner_bubble_); // We reuse the focusable state on this view as a signal that focus should // switch to the system tray. LockContentsView should otherwise not be @@ -428,8 +439,6 @@ } chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( this); - - CleanupBubbles(); } void LockContentsView::FocusNextUser() { @@ -801,13 +810,14 @@ if (!big_user || !big_user->auth_user()) return; - if (tooltip_bubble_->IsVisible()) + if (tooltip_bubble_->visible()) tooltip_bubble_->Hide(); if (icon->autoshow_tooltip) { tooltip_bubble_->SetAnchorView(big_user->auth_user()->password_view()); tooltip_bubble_->SetText(icon->tooltip); tooltip_bubble_->Show(); + tooltip_bubble_->SetVisible(true); } } @@ -818,7 +828,7 @@ "warning banner."; return; } - if (warning_banner_bubble_->IsVisible()) + if (warning_banner_bubble_->visible()) warning_banner_bubble_->Hide(); // Shows warning banner as a persistent error bubble. views::Label* label = @@ -829,14 +839,14 @@ label->SetHorizontalAlignment(gfx::ALIGN_LEFT); label->SetEnabledColor(SK_ColorWHITE); - warning_banner_bubble_->SetContent(label); warning_banner_bubble_->SetAnchorView( CurrentBigUserView()->auth_user()->password_view()); + warning_banner_bubble_->SetContent(label); warning_banner_bubble_->Show(); } void LockContentsView::OnHideWarningBanner() { - if (warning_banner_bubble_->IsVisible()) + if (warning_banner_bubble_->visible()) warning_banner_bubble_->Hide(); } @@ -983,12 +993,12 @@ (pairing_status == DetachableBasePairingStatus::kAuthenticated && detachable_base_model_->PairedBaseMatchesLastUsedByUser( *CurrentBigUserView()->GetCurrentUser()->basic_user_info))) { - if (detachable_base_error_bubble_->IsVisible()) + if (detachable_base_error_bubble_->visible()) detachable_base_error_bubble_->Hide(); return; } - if (auth_error_bubble_->IsVisible()) + if (auth_error_bubble_->visible()) auth_error_bubble_->Hide(); base::string16 error_text = @@ -1323,10 +1333,10 @@ void LockContentsView::OnAuthenticate(bool auth_success) { if (auth_success) { - if (auth_error_bubble_->IsVisible()) + if (auth_error_bubble_->visible()) auth_error_bubble_->Hide(); - if (detachable_base_error_bubble_->IsVisible()) + if (detachable_base_error_bubble_->visible()) detachable_base_error_bubble_->Hide(); // Now that the user has been authenticated, update the user's last used @@ -1525,7 +1535,7 @@ supervised_user_deprecation_bubble_->SetAnchorView( CurrentBigUserView()->auth_user()->password_view()); supervised_user_deprecation_bubble_->Show(); - } else if (supervised_user_deprecation_bubble_->IsVisible()) { + } else if (supervised_user_deprecation_bubble_->visible()) { supervised_user_deprecation_bubble_->Hide(); } @@ -1534,7 +1544,7 @@ OnDetachableBasePairingStatusChanged( detachable_base_model_->GetPairingStatus()); - if (!detachable_base_error_bubble_->IsVisible()) + if (!detachable_base_error_bubble_->visible()) CurrentBigUserView()->RequestFocus(); } @@ -1629,9 +1639,6 @@ container->AddChildView(label); container->AddChildView(learn_more_button); - if (auth_error_bubble_->IsVisible()) - auth_error_bubble_->Hide(); - auth_error_bubble_->SetAnchorView(big_view->auth_user()->password_view()); auth_error_bubble_->SetContent(container); auth_error_bubble_->SetPersistent(false); @@ -1849,29 +1856,4 @@ } } -void LockContentsView::CleanupBubbles() { - // If any of the error bubbles have been shown once, it is hosted by a - // widget under the Ash menu container, so we should Close the widget when we - // destroy LockContentsView (otherwise it will live for the entire lifetime of - // the Menu container). If a bubble has never been shown, then we can just - // delete it, since it is owned directly by LockContentsView. - auto cleanup = [](LoginBaseBubbleView* bubble) { - if (bubble->GetWidget()) - bubble->GetWidget()->Close(); - else - delete bubble; - }; - - cleanup(auth_error_bubble_); - auth_error_bubble_ = nullptr; - cleanup(detachable_base_error_bubble_); - detachable_base_error_bubble_ = nullptr; - cleanup(tooltip_bubble_); - tooltip_bubble_ = nullptr; - cleanup(warning_banner_bubble_); - warning_banner_bubble_ = nullptr; - cleanup(supervised_user_deprecation_bubble_); - supervised_user_deprecation_bubble_ = nullptr; -} - } // namespace ash
diff --git a/ash/login/ui/lock_contents_view.h b/ash/login/ui/lock_contents_view.h index f24826f..5d0ca98 100644 --- a/ash/login/ui/lock_contents_view.h +++ b/ash/login/ui/lock_contents_view.h
@@ -339,10 +339,6 @@ // Performs the specified accelerator action. void PerformAction(AcceleratorAction action); - // Deletes the various bubbles, either by Close()-ing the hosting widget or - // deleting any orphaned views. - void CleanupBubbles(); - const LockScreen::ScreenType screen_type_; std::vector<UserState> users_; @@ -377,8 +373,9 @@ this}; ScopedSessionObserver session_observer_{this}; - // Error bubbles are owned by LockContentsView, or by the Ash menu container - // if they have been shown. Bubble for displaying authentication error. + // All error bubbles and the tooltip view are child views of LockContentsView, + // and will be torn down when LockContentsView is torn down. + // Bubble for displaying authentication error. LoginErrorBubble* auth_error_bubble_; // Bubble for displaying detachable base errors. LoginErrorBubble* detachable_base_error_bubble_;
diff --git a/ash/login/ui/lock_contents_view_unittest.cc b/ash/login/ui/lock_contents_view_unittest.cc index 3fa8427e..a69b4fe 100644 --- a/ash/login/ui/lock_contents_view_unittest.cc +++ b/ash/login/ui/lock_contents_view_unittest.cc
@@ -726,7 +726,7 @@ LockContentsView::TestApi test_api(lock); // Creating lock screen does not show tooltip bubble. - EXPECT_FALSE(test_api.tooltip_bubble()->IsVisible()); + EXPECT_FALSE(test_api.tooltip_bubble()->visible()); // Show an icon with |autoshow_tooltip| is false. Tooltip bubble is not // activated. @@ -735,13 +735,13 @@ icon->autoshow_tooltip = false; DataDispatcher()->ShowEasyUnlockIcon(users()[0]->basic_user_info->account_id, icon); - EXPECT_FALSE(test_api.tooltip_bubble()->IsVisible()); + EXPECT_FALSE(test_api.tooltip_bubble()->visible()); // Show icon with |autoshow_tooltip| set to true. Tooltip bubble is shown. icon->autoshow_tooltip = true; DataDispatcher()->ShowEasyUnlockIcon(users()[0]->basic_user_info->account_id, icon); - EXPECT_TRUE(test_api.tooltip_bubble()->IsVisible()); + EXPECT_TRUE(test_api.tooltip_bubble()->visible()); } // Verifies that easy unlock icon state persists when changing auth user. @@ -860,12 +860,12 @@ generator->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(test_api.auth_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.auth_error_bubble()->visible()); // The error bubble is expected to close on a user action - e.g. if they start // typing the password again. generator->PressKey(ui::KeyboardCode::VKEY_B, 0); - EXPECT_FALSE(test_api.auth_error_bubble()->IsVisible()); + EXPECT_FALSE(test_api.auth_error_bubble()->visible()); } // Gaia is never shown on lock, no mater how many times auth fails. @@ -957,17 +957,17 @@ LockContentsView::TestApi test_api(contents); ui::test::EventGenerator* generator = GetEventGenerator(); - EXPECT_FALSE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_FALSE(test_api.detachable_base_error_bubble()->visible()); // Change detachable base to a base different than the one previously used by // the user - verify that a detachable base error bubble is shown. detachable_base_model->SetPairingStatus( DetachableBasePairingStatus::kAuthenticated, "5678"); - EXPECT_TRUE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.detachable_base_error_bubble()->visible()); // Verify that the bubble is not hidden if the user starts typing. generator->PressKey(ui::KeyboardCode::VKEY_B, 0); - EXPECT_TRUE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.detachable_base_error_bubble()->visible()); // Switching to the user that doesn't have previously used detachable base // (and should thus not be warned about the detachable base missmatch) should @@ -978,7 +978,7 @@ secondary_test_api.user_view()->GetBoundsInScreen().CenterPoint()); generator->ClickLeftButton(); - EXPECT_FALSE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_FALSE(test_api.detachable_base_error_bubble()->visible()); // The error should be shown again when switching back to the primary user. LoginAuthUserView::TestApi primary_test_api( @@ -987,7 +987,7 @@ primary_test_api.user_view()->GetBoundsInScreen().CenterPoint()); generator->ClickLeftButton(); - EXPECT_TRUE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.detachable_base_error_bubble()->visible()); EXPECT_FALSE(primary_test_api.password_view()->HasFocus()); EXPECT_EQ("1234", @@ -1036,16 +1036,16 @@ LockContentsView::TestApi test_api(contents); ui::test::EventGenerator* generator = GetEventGenerator(); - EXPECT_FALSE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_FALSE(test_api.detachable_base_error_bubble()->visible()); // Show notification if unauthenticated base is attached. detachable_base_model->SetPairingStatus( DetachableBasePairingStatus::kNotAuthenticated, ""); - EXPECT_TRUE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.detachable_base_error_bubble()->visible()); // Verify that the bubble is not hidden if the user starts typing. generator->PressKey(ui::KeyboardCode::VKEY_B, 0); - EXPECT_TRUE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.detachable_base_error_bubble()->visible()); // Switching to another user should not hide the error bubble. LoginAuthUserView::TestApi secondary_test_api( @@ -1054,7 +1054,7 @@ secondary_test_api.user_view()->GetBoundsInScreen().CenterPoint()); generator->ClickLeftButton(); - EXPECT_TRUE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.detachable_base_error_bubble()->visible()); EXPECT_FALSE(secondary_test_api.password_view()->HasFocus()); // The last trusted detachable used by the user should not be overriden by @@ -1103,12 +1103,12 @@ // the user - verify that a detachable base error bubble is shown. detachable_base_model->SetPairingStatus( DetachableBasePairingStatus::kAuthenticated, "5678"); - EXPECT_TRUE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.detachable_base_error_bubble()->visible()); // The notification should be hidden if the base gets detached. detachable_base_model->SetPairingStatus(DetachableBasePairingStatus::kNone, ""); - EXPECT_FALSE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_FALSE(test_api.detachable_base_error_bubble()->visible()); } TEST_F(LockContentsViewUnitTest, DetachableBaseErrorClearsAuthError) { @@ -1136,7 +1136,7 @@ LockContentsView::TestApi test_api(contents); ui::test::EventGenerator* generator = GetEventGenerator(); - EXPECT_FALSE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_FALSE(test_api.detachable_base_error_bubble()->visible()); // Attempt and fail user auth - an auth error is expected to be shown. std::unique_ptr<MockLoginScreenClient> client = BindMockLoginScreenClient(); @@ -1149,8 +1149,8 @@ generator->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(test_api.auth_error_bubble()->IsVisible()); - EXPECT_FALSE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.auth_error_bubble()->visible()); + EXPECT_FALSE(test_api.detachable_base_error_bubble()->visible()); // Change detachable base to a base different than the one previously used by // the user - verify that a detachable base error bubble is shown, and the @@ -1158,8 +1158,8 @@ detachable_base_model->SetPairingStatus( DetachableBasePairingStatus::kAuthenticated, "5678"); - EXPECT_TRUE(test_api.detachable_base_error_bubble()->IsVisible()); - EXPECT_FALSE(test_api.auth_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.detachable_base_error_bubble()->visible()); + EXPECT_FALSE(test_api.auth_error_bubble()->visible()); } TEST_F(LockContentsViewUnitTest, AuthErrorDoesNotRemoveDetachableBaseError) { @@ -1187,7 +1187,7 @@ LockContentsView::TestApi test_api(contents); ui::test::EventGenerator* generator = GetEventGenerator(); - EXPECT_FALSE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_FALSE(test_api.detachable_base_error_bubble()->visible()); // Change detachable base to a base different than the one previously used by // the user - verify that a detachable base error bubble is shown, and the @@ -1195,7 +1195,7 @@ detachable_base_model->SetPairingStatus( DetachableBasePairingStatus::kAuthenticated, "5678"); - EXPECT_TRUE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.detachable_base_error_bubble()->visible()); // Attempt and fail user auth - an auth error is expected to be shown. // Detachable base error should not be hidden. @@ -1212,15 +1212,15 @@ generator->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(test_api.auth_error_bubble()->IsVisible()); - EXPECT_TRUE(test_api.detachable_base_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.auth_error_bubble()->visible()); + EXPECT_TRUE(test_api.detachable_base_error_bubble()->visible()); // User action, like pressing a key should close the auth error bubble, but // not the detachable base error bubble. generator->PressKey(ui::KeyboardCode::VKEY_A, 0); - EXPECT_TRUE(test_api.detachable_base_error_bubble()->IsVisible()); - EXPECT_FALSE(test_api.auth_error_bubble()->IsVisible()); + EXPECT_TRUE(test_api.detachable_base_error_bubble()->visible()); + EXPECT_FALSE(test_api.auth_error_bubble()->visible()); } TEST_F(LockContentsViewKeyboardUnitTest, SwitchPinAndVirtualKeyboard) { @@ -2039,19 +2039,19 @@ ui::test::EventGenerator* generator = GetEventGenerator(); // Creating lock screen does not show warning banner bubble. - EXPECT_FALSE(test_api.warning_banner_bubble()->IsVisible()); + EXPECT_FALSE(test_api.warning_banner_bubble()->visible()); // Verifies that a warning banner is shown by giving a non-empty message. DataDispatcher()->ShowWarningBanner(base::ASCIIToUTF16("foo")); - EXPECT_TRUE(test_api.warning_banner_bubble()->IsVisible()); + EXPECT_TRUE(test_api.warning_banner_bubble()->visible()); // Verifies that a warning banner is hidden by HideWarningBanner(). DataDispatcher()->HideWarningBanner(); - EXPECT_FALSE(test_api.warning_banner_bubble()->IsVisible()); + EXPECT_FALSE(test_api.warning_banner_bubble()->visible()); // Shows a warning banner again. DataDispatcher()->ShowWarningBanner(base::ASCIIToUTF16("foo")); - EXPECT_TRUE(test_api.warning_banner_bubble()->IsVisible()); + EXPECT_TRUE(test_api.warning_banner_bubble()->visible()); // Attempt and fail user auth - an auth error is expected to be shown. // The warning banner should not be hidden. @@ -2068,8 +2068,8 @@ generator->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(test_api.auth_error_bubble()->IsVisible()); - EXPECT_TRUE(test_api.warning_banner_bubble()->IsVisible()); + EXPECT_TRUE(test_api.auth_error_bubble()->visible()); + EXPECT_TRUE(test_api.warning_banner_bubble()->visible()); } TEST_F(LockContentsViewUnitTest, RemoveUserFocusMovesBackToPrimaryUser) {
diff --git a/ash/login/ui/login_base_bubble_view.cc b/ash/login/ui/login_base_bubble_view.cc index ab6689a..e673860 100644 --- a/ash/login/ui/login_base_bubble_view.cc +++ b/ash/login/ui/login_base_bubble_view.cc
@@ -4,6 +4,9 @@ #include "ash/login/ui/login_base_bubble_view.h" +#include <memory> + +#include "ash/login/ui/views_utils.h" #include "ash/public/cpp/shell_window_ids.h" #include "ash/shell.h" #include "base/scoped_observer.h" @@ -12,6 +15,7 @@ #include "ui/compositor/layer_animator.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/events/event_handler.h" +#include "ui/views/background.h" #include "ui/views/layout/box_layout.h" #include "ui/wm/core/coordinate_conversion.h" @@ -30,6 +34,9 @@ // Bottom margin of the bubble view. constexpr int kBubbleBottomMarginDp = 18; +// Spacing between the child view inside the bubble view. +constexpr int kBubbleBetweenChildSpacingDp = 6; + // The amount of time for bubble show/hide animation. constexpr base::TimeDelta kBubbleAnimationDuration = base::TimeDelta::FromMilliseconds(300); @@ -38,13 +45,10 @@ // This class handles keyboard, mouse, and focus events, and dismisses the // associated bubble in response. -class LoginBubbleHandler : public ui::EventHandler, - public aura::client::FocusChangeObserver { +class LoginBubbleHandler : public ui::EventHandler { public: LoginBubbleHandler(LoginBaseBubbleView* bubble) : bubble_(bubble) { Shell::Get()->AddPreTargetHandler(this); - focus_observer_.Add( - aura::client::GetFocusClient(Shell::GetPrimaryRootWindow())); } ~LoginBubbleHandler() override { Shell::Get()->RemovePreTargetHandler(this); } @@ -68,37 +72,22 @@ return; } - if (!bubble_->IsVisible()) + if (!bubble_->visible()) return; if (bubble_->GetBubbleOpener() && bubble_->GetBubbleOpener()->HasFocus()) return; - if (bubble_->GetWidget()->IsActive()) + if (login_views_utils::HasFocusInAnyChildView(bubble_)) return; if (!bubble_->IsPersistent()) bubble_->Hide(); } - // aura::client::FocusChangeObserver: - void OnWindowFocused(aura::Window* gained_focus, - aura::Window* lost_focus) override { - if (!bubble_->IsVisible()) - return; - - if (gained_focus && - bubble_->GetWidget()->GetNativeView()->Contains(gained_focus)) { - return; - } - - if (!bubble_->IsPersistent()) - bubble_->Hide(); - } - private: void ProcessPressedEvent(const ui::LocatedEvent* event) { - if (!bubble_->IsVisible()) + if (!bubble_->visible()) return; gfx::Point screen_location = event->location(); @@ -122,9 +111,6 @@ LoginBaseBubbleView* bubble_; - ScopedObserver<aura::client::FocusClient, aura::client::FocusChangeObserver> - focus_observer_{this}; - DISALLOW_COPY_AND_ASSIGN(LoginBubbleHandler); }; @@ -133,36 +119,28 @@ LoginBaseBubbleView::LoginBaseBubbleView(views::View* anchor_view, aura::Window* parent_window) - : BubbleDialogDelegateView(anchor_view, views::BubbleBorder::NONE), + : anchor_view_(anchor_view), bubble_handler_(std::make_unique<LoginBubbleHandler>(this)) { - set_margins(gfx::Insets(kBubbleTopMarginDp, kBubbleHorizontalMarginDp, - kBubbleBottomMarginDp, kBubbleHorizontalMarginDp)); - set_color(SK_ColorBLACK); - set_can_activate(false); - set_close_on_deactivate(false); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::kVertical, + gfx::Insets(kBubbleTopMarginDp, kBubbleHorizontalMarginDp, + kBubbleBottomMarginDp, kBubbleHorizontalMarginDp), + kBubbleBetweenChildSpacingDp)); + + SetVisible(false); + SetBackground(views::CreateSolidBackground(SK_ColorBLACK)); // Layer rendering is needed for animation. SetPaintToLayer(); - layer()->SetFillsBoundsOpaquely(false); - - set_parent_window(parent_window); } LoginBaseBubbleView::~LoginBaseBubbleView() = default; void LoginBaseBubbleView::Show() { - views::Widget* widget = GetWidget(); - - if (!widget) - widget = views::BubbleDialogDelegateView::CreateBubble(this); - layer()->GetAnimator()->RemoveObserver(this); - Layout(); - SizeToContents(); - - widget->ShowInactive(); - widget->StackAtTop(); + SetSize(GetPreferredSize()); + SetPosition(CalculatePosition()); ScheduleAnimation(true /*visible*/); @@ -172,12 +150,7 @@ } void LoginBaseBubbleView::Hide() { - if (GetWidget()) - ScheduleAnimation(false /*visible*/); -} - -bool LoginBaseBubbleView::IsVisible() { - return GetWidget() && GetWidget()->IsVisible(); + ScheduleAnimation(false /*visible*/); } LoginButton* LoginBaseBubbleView::GetBubbleOpener() const { @@ -190,31 +163,25 @@ void LoginBaseBubbleView::SetPersistent(bool persistent) {} -void LoginBaseBubbleView::OnBeforeBubbleWidgetInit( - views::Widget::InitParams* params, - views::Widget* widget) const { - // This case only gets called if the bubble has no anchor and no parent - // container was specified. In this case, the parent container should default - // to MenuContainer, so that login bubbles are visible over the shelf and - // virtual keyboard. Shell may be null in tests. - if (!params->parent && Shell::HasInstance()) { - params->parent = Shell::GetContainer(Shell::GetPrimaryRootWindow(), - kShellWindowId_MenuContainer); +gfx::Point LoginBaseBubbleView::CalculatePosition() { + if (GetAnchorView()) { + gfx::Point bottom_left = GetAnchorView()->bounds().bottom_left(); + ConvertPointToTarget(GetAnchorView()->parent() /*source*/, + parent() /*target*/, &bottom_left); + return bottom_left; } -} -int LoginBaseBubbleView::GetDialogButtons() const { - return ui::DIALOG_BUTTON_NONE; + return gfx::Point(); } void LoginBaseBubbleView::SetAnchorView(views::View* anchor_view) { - views::BubbleDialogDelegateView::SetAnchorView(anchor_view); + anchor_view_ = anchor_view; } void LoginBaseBubbleView::OnLayerAnimationEnded( ui::LayerAnimationSequence* sequence) { layer()->GetAnimator()->RemoveObserver(this); - GetWidget()->Hide(); + SetVisible(false); } gfx::Size LoginBaseBubbleView::CalculatePreferredSize() const { @@ -224,15 +191,20 @@ return size; } -void LoginBaseBubbleView::OnWidgetVisibilityChanged(views::Widget* widget, - bool visible) { - if (visible) - EnsureInScreen(); +void LoginBaseBubbleView::Layout() { + views::View::Layout(); + + // If a Layout() is called while the bubble is visible (i.e. due to Show()), + // its bounds may change because of the parent's LayoutManager. This allows + // the bubbles to always determine their own size and position. + if (visible()) { + SetSize(GetPreferredSize()); + SetPosition(CalculatePosition()); + } } -void LoginBaseBubbleView::OnWidgetBoundsChanged(views::Widget* widget, - const gfx::Rect& new_bounds) { - EnsureInScreen(); +void LoginBaseBubbleView::OnBlur() { + Hide(); } void LoginBaseBubbleView::ScheduleAnimation(bool visible) { @@ -251,6 +223,8 @@ std::swap(opacity_start, opacity_end); // We only need to handle animation ending if we're hiding the bubble. layer()->GetAnimator()->AddObserver(this); + } else { + SetVisible(true); } layer()->SetOpacity(opacity_start); @@ -264,26 +238,4 @@ } } -void LoginBaseBubbleView::EnsureInScreen() { - DCHECK(GetWidget()); - - const gfx::Rect view_bounds = GetBoundsInScreen(); - const gfx::Rect work_area = - display::Screen::GetScreen() - ->GetDisplayNearestWindow(GetWidget()->GetNativeWindow()) - .work_area(); - - int horizontal_offset = 0; - - // If the widget extends past the right side of the screen, make it go to - // the left instead. - if (work_area.right() < view_bounds.right()) { - horizontal_offset = -view_bounds.width(); - } - - set_anchor_view_insets( - anchor_view_insets().Offset(gfx::Vector2d(horizontal_offset, 0))); - OnAnchorBoundsChanged(); -} - } // namespace ash
diff --git a/ash/login/ui/login_base_bubble_view.h b/ash/login/ui/login_base_bubble_view.h index 91217b4..a93e3daf 100644 --- a/ash/login/ui/login_base_bubble_view.h +++ b/ash/login/ui/login_base_bubble_view.h
@@ -17,7 +17,7 @@ class LoginBubbleHandler; // Base bubble view for login screen bubbles. -class ASH_EXPORT LoginBaseBubbleView : public views::BubbleDialogDelegateView, +class ASH_EXPORT LoginBaseBubbleView : public views::View, public ui::LayerAnimationObserver { public: // Without specifying a parent_window, the bubble will default to being in the @@ -30,8 +30,6 @@ void Show(); void Hide(); - bool IsVisible(); - // Returns the button responsible for opening this bubble. virtual LoginButton* GetBubbleOpener() const; @@ -40,11 +38,11 @@ // Change the persistence of the bubble. virtual void SetPersistent(bool persistent); - // views::BubbleDialogDelegateView: - void OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, - views::Widget* widget) const override; - int GetDialogButtons() const override; + // Determine the position of the bubble prior to showing. + virtual gfx::Point CalculatePosition(); + void SetAnchorView(views::View* anchor_view); + views::View* GetAnchorView() const { return anchor_view_; } // ui::LayerAnimationObserver: void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override; @@ -54,15 +52,13 @@ // views::View: gfx::Size CalculatePreferredSize() const override; - - // views::WidgetObserver: - void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override; - void OnWidgetBoundsChanged(views::Widget* widget, - const gfx::Rect& new_bounds) override; + void Layout() override; + void OnBlur() override; private: void ScheduleAnimation(bool visible); - void EnsureInScreen(); + + views::View* anchor_view_; std::unique_ptr<LoginBubbleHandler> bubble_handler_;
diff --git a/ash/login/ui/login_base_bubble_view_unittest.cc b/ash/login/ui/login_base_bubble_view_unittest.cc index 23853bda..ddc5be7 100644 --- a/ash/login/ui/login_base_bubble_view_unittest.cc +++ b/ash/login/ui/login_base_bubble_view_unittest.cc
@@ -15,15 +15,6 @@ namespace { // Total width of the bubble view. constexpr int kBubbleTotalWidthDp = 178; - -// Horizontal margin of the bubble view. -constexpr int kBubbleHorizontalMarginDp = 14; - -// Top margin of the bubble view. -constexpr int kBubbleTopMarginDp = 13; - -// Bottom margin of the bubble view. -constexpr int kBubbleBottomMarginDp = 18; } // namespace class LoginBaseBubbleViewTest : public LoginTestBase { @@ -36,6 +27,7 @@ LoginTestBase::SetUp(); anchor_ = new views::View(); + anchor_->SetSize(gfx::Size(0, 25)); container_ = new views::View(); container_->SetLayoutManager( std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); @@ -50,6 +42,8 @@ bubble_->SetLayoutManager( std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); bubble_->AddChildView(label); + + container_->AddChildView(bubble_); } LoginBaseBubbleView* bubble_; @@ -61,58 +55,54 @@ }; TEST_F(LoginBaseBubbleViewTest, BasicProperties) { - EXPECT_FALSE(bubble_->IsVisible()); + EXPECT_FALSE(bubble_->visible()); bubble_->Show(); - EXPECT_TRUE(bubble_->IsVisible()); + EXPECT_TRUE(bubble_->visible()); - EXPECT_EQ(bubble_->GetDialogButtons(), ui::DIALOG_BUTTON_NONE); EXPECT_EQ(bubble_->width(), kBubbleTotalWidthDp); - EXPECT_EQ(bubble_->color(), SK_ColorBLACK); - EXPECT_EQ(bubble_->margins(), - gfx::Insets(kBubbleTopMarginDp, kBubbleHorizontalMarginDp, - kBubbleBottomMarginDp, kBubbleHorizontalMarginDp)); + EXPECT_EQ(bubble_->background()->get_color(), SK_ColorBLACK); bubble_->Hide(); - EXPECT_FALSE(bubble_->IsVisible()); + EXPECT_FALSE(bubble_->visible()); } TEST_F(LoginBaseBubbleViewTest, KeyEventHandling) { - EXPECT_FALSE(bubble_->IsVisible()); + EXPECT_FALSE(bubble_->visible()); // Verify that a random key event won't open the bubble. ui::test::EventGenerator* generator = GetEventGenerator(); container_->RequestFocus(); generator->PressKey(ui::KeyboardCode::VKEY_A, ui::EF_NONE); - EXPECT_FALSE(bubble_->IsVisible()); + EXPECT_FALSE(bubble_->visible()); // Verify that a key event will close the bubble if it is open. bubble_->Show(); - EXPECT_TRUE(bubble_->IsVisible()); + EXPECT_TRUE(bubble_->visible()); generator->PressKey(ui::KeyboardCode::VKEY_A, ui::EF_NONE); - EXPECT_FALSE(bubble_->IsVisible()); + EXPECT_FALSE(bubble_->visible()); } TEST_F(LoginBaseBubbleViewTest, MouseEventHandling) { - EXPECT_FALSE(bubble_->IsVisible()); + EXPECT_FALSE(bubble_->visible()); // Verify that a random mouse event won't open the bubble. ui::test::EventGenerator* generator = GetEventGenerator(); generator->MoveMouseTo(container_->GetBoundsInScreen().CenterPoint()); generator->ClickLeftButton(); - EXPECT_FALSE(bubble_->IsVisible()); + EXPECT_FALSE(bubble_->visible()); // Verify that a click event on the bubble won't close it. bubble_->Show(); - EXPECT_TRUE(bubble_->IsVisible()); + EXPECT_TRUE(bubble_->visible()); generator->MoveMouseTo(bubble_->GetBoundsInScreen().CenterPoint()); generator->ClickLeftButton(); - EXPECT_TRUE(bubble_->IsVisible()); + EXPECT_TRUE(bubble_->visible()); // Verify that a click event outside the bubble will close it if it is open. generator->MoveMouseTo(anchor_->GetBoundsInScreen().CenterPoint()); generator->ClickLeftButton(); - EXPECT_FALSE(bubble_->IsVisible()); + EXPECT_FALSE(bubble_->visible()); } } // namespace ash
diff --git a/ash/login/ui/login_error_bubble.cc b/ash/login/ui/login_error_bubble.cc index 73a42e6..2ef1ef7 100644 --- a/ash/login/ui/login_error_bubble.cc +++ b/ash/login/ui/login_error_bubble.cc
@@ -17,48 +17,20 @@ namespace ash { namespace { -// Vertical spacing between the anchor view and error bubble. -constexpr int kAnchorViewErrorBubbleVerticalSpacingDp = 48; - // The size of the alert icon in the error bubble. constexpr int kAlertIconSizeDp = 20; -// Margin/inset of the entries for the user menu. -constexpr int kUserMenuMarginWidth = 14; -constexpr int kUserMenuMarginHeight = 18; - -// Spacing between the child view inside the bubble view. -constexpr int kBubbleBetweenChildSpacingDp = 6; - } // namespace -// static -LoginErrorBubble* LoginErrorBubble::CreateDefault() { - aura::Window* menu_container = Shell::GetContainer( - Shell::GetPrimaryRootWindow(), kShellWindowId_MenuContainer); - return new LoginErrorBubble(nullptr /* content */, nullptr /*anchor_view*/, - menu_container /*parent_container*/, - false /*is_persistent*/); -} +LoginErrorBubble::LoginErrorBubble() + : LoginErrorBubble(nullptr /*content*/, + nullptr /*anchor_view*/, + false /*is_persistent*/) {} LoginErrorBubble::LoginErrorBubble(views::View* content, views::View* anchor_view, - aura::Window* parent_container, bool is_persistent) - : LoginBaseBubbleView(anchor_view, parent_container), - is_persistent_(is_persistent) { - set_anchor_view_insets( - gfx::Insets(kAnchorViewErrorBubbleVerticalSpacingDp, 0)); - - gfx::Insets margins(kUserMenuMarginHeight, kUserMenuMarginWidth); - - set_margins(gfx::Insets(0, margins.left(), 0, margins.right())); - - SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, - gfx::Insets(margins.top(), 0, margins.bottom(), 0), - kBubbleBetweenChildSpacingDp)); - + : LoginBaseBubbleView(anchor_view), is_persistent_(is_persistent) { auto* alert_view = new NonAccessibleView("AlertIconContainer"); alert_view->SetLayoutManager( std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); @@ -93,6 +65,16 @@ is_persistent_ = persistent; } +gfx::Size LoginErrorBubble::CalculatePreferredSize() const { + gfx::Size size; + + if (GetAnchorView()) + size.set_width(GetAnchorView()->width()); + + size.set_height(GetHeightForWidth(size.width())); + return size; +} + const char* LoginErrorBubble::GetClassName() const { return "LoginErrorBubble"; }
diff --git a/ash/login/ui/login_error_bubble.h b/ash/login/ui/login_error_bubble.h index eab8fc22..3acd155a 100644 --- a/ash/login/ui/login_error_bubble.h +++ b/ash/login/ui/login_error_bubble.h
@@ -13,14 +13,9 @@ class ASH_EXPORT LoginErrorBubble : public LoginBaseBubbleView { public: - // Factory method to create a non-persistent error bubble in the Ash menu - // container. The caller should manually Close() or delete the bubble, or - // else it will persist for the full lifetime of the Ash menu container. - static LoginErrorBubble* CreateDefault(); - + LoginErrorBubble(); LoginErrorBubble(views::View* content, views::View* anchor_view, - aura::Window* parent_container, bool is_persistent); ~LoginErrorBubble() override; @@ -31,6 +26,7 @@ void SetPersistent(bool persistent) override; // views::View: + gfx::Size CalculatePreferredSize() const override; const char* GetClassName() const override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
diff --git a/ash/login/ui/login_error_bubble_unittest.cc b/ash/login/ui/login_error_bubble_unittest.cc index 061b5aa..37e2611 100644 --- a/ash/login/ui/login_error_bubble_unittest.cc +++ b/ash/login/ui/login_error_bubble_unittest.cc
@@ -27,31 +27,32 @@ views::style::STYLE_PRIMARY); auto* bubble = new LoginErrorBubble(label /*content*/, anchor_view, - widget()->GetNativeView() /*container*/, true /*is_persistent*/); - EXPECT_FALSE(bubble->IsVisible()); + container->AddChildView(bubble); + + EXPECT_FALSE(bubble->visible()); bubble->Show(); - EXPECT_TRUE(bubble->IsVisible()); + EXPECT_TRUE(bubble->visible()); ui::test::EventGenerator* generator = GetEventGenerator(); generator->MoveMouseTo(anchor_view->GetBoundsInScreen().CenterPoint()); generator->ClickLeftButton(); - EXPECT_TRUE(bubble->IsVisible()); + EXPECT_TRUE(bubble->visible()); generator->MoveMouseTo(bubble->GetBoundsInScreen().CenterPoint()); generator->ClickLeftButton(); - EXPECT_TRUE(bubble->IsVisible()); + EXPECT_TRUE(bubble->visible()); generator->GestureTapAt(anchor_view->GetBoundsInScreen().CenterPoint()); - EXPECT_TRUE(bubble->IsVisible()); + EXPECT_TRUE(bubble->visible()); generator->GestureTapAt(bubble->GetBoundsInScreen().CenterPoint()); - EXPECT_TRUE(bubble->IsVisible()); + EXPECT_TRUE(bubble->visible()); generator->PressKey(ui::KeyboardCode::VKEY_A, ui::EF_NONE); - EXPECT_TRUE(bubble->IsVisible()); + EXPECT_TRUE(bubble->visible()); } } // namespace ash
diff --git a/ash/login/ui/login_expanded_public_account_view.cc b/ash/login/ui/login_expanded_public_account_view.cc index 541e275..87d7a6b 100644 --- a/ash/login/ui/login_expanded_public_account_view.cc +++ b/ash/login/ui/login_expanded_public_account_view.cc
@@ -13,6 +13,7 @@ #include "ash/login/ui/login_button.h" #include "ash/login/ui/login_user_view.h" #include "ash/login/ui/public_account_warning_dialog.h" +#include "ash/login/ui/views_utils.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" @@ -415,20 +416,10 @@ current_user_->basic_user_info->account_id, selected_language_item_.value, selected_keyboard_item_.value); } else if (sender == language_selection_) { - if (language_menu_view_ && language_menu_view_->IsVisible()) { + DCHECK(language_menu_view_); + if (language_menu_view_->visible()) { language_menu_view_->Hide(); } else { - if (language_menu_view_) { - language_menu_view_->GetWidget()->Close(); - language_menu_view_ = nullptr; - } - - language_menu_view_ = new LoginMenuView( - language_items_, language_selection_ /*anchor_view*/, - language_selection_ /*bubble_opener*/, - base::BindRepeating(&RightPaneView::OnLanguageSelected, - weak_factory_.GetWeakPtr())); - bool opener_had_focus = language_selection_->HasFocus(); language_menu_view_->Show(); @@ -437,19 +428,10 @@ language_menu_view_->RequestFocus(); } } else if (sender == keyboard_selection_) { - if (keyboard_menu_view_ && keyboard_menu_view_->IsVisible()) { + DCHECK(keyboard_menu_view_); + if (keyboard_menu_view_->visible()) { keyboard_menu_view_->Hide(); } else { - if (keyboard_menu_view_) { - keyboard_menu_view_->GetWidget()->Close(); - keyboard_menu_view_ = nullptr; - } - - keyboard_menu_view_ = new LoginMenuView( - keyboard_items_, keyboard_selection_ /*anchor_view*/, - keyboard_selection_ /*bubble_opener*/, - base::BindRepeating(&RightPaneView::OnKeyboardSelected, - weak_factory_.GetWeakPtr())); bool opener_had_focus = keyboard_selection_->HasFocus(); keyboard_menu_view_->Show(); @@ -496,7 +478,6 @@ } void OnLanguageSelected(LoginMenuView::Item item) { - language_menu_view_ = nullptr; language_changed_by_user_ = true; selected_language_item_ = item; language_selection_->SetText(base::UTF8ToUTF16(item.title)); @@ -511,7 +492,6 @@ } void OnKeyboardSelected(LoginMenuView::Item item) { - keyboard_menu_view_ = nullptr; selected_keyboard_item_ = item; keyboard_selection_->SetText(base::UTF8ToUTF16(item.title)); } @@ -534,6 +514,14 @@ if (selected_language_item_.value == locale->language_code) selected_language_item_ = item; } + + language_menu_view_ = new LoginMenuView( + language_items_, language_selection_ /*anchor_view*/, + language_selection_ /*bubble_opener*/, + base::BindRepeating(&RightPaneView::OnLanguageSelected, + weak_factory_.GetWeakPtr())); + login_views_utils::GetTopLevelParentView(this)->AddChildView( + language_menu_view_); } void PopulateKeyboardItems( @@ -550,6 +538,14 @@ if (keyboard->selected) selected_keyboard_item_ = item; } + + keyboard_menu_view_ = new LoginMenuView( + keyboard_items_, keyboard_selection_ /*anchor_view*/, + keyboard_selection_ /*bubble_opener*/, + base::BindRepeating(&RightPaneView::OnKeyboardSelected, + weak_factory_.GetWeakPtr())); + login_views_utils::GetTopLevelParentView(this)->AddChildView( + keyboard_menu_view_); } LoginBaseBubbleView* GetLanguageMenuView() { return language_menu_view_; } @@ -558,16 +554,6 @@ // Close language and keyboard menus and reset local states. void Reset() { - if (language_menu_view_) { - language_menu_view_->GetWidget()->Close(); - language_menu_view_ = nullptr; - } - - if (keyboard_menu_view_) { - keyboard_menu_view_->GetWidget()->Close(); - keyboard_menu_view_ = nullptr; - } - show_advanced_changed_by_user_ = false; language_changed_by_user_ = false; } @@ -587,11 +573,9 @@ views::StyledLabel* learn_more_label_ = nullptr; MonitoringWarningView* monitoring_warning_view_ = nullptr; - // |language_menu_view_| and |keyboard_menu_view_| are owned by their - // respective bubble widgets, which are always initialized with a Show() call - // after construction. menu_view_->GetWidget()->Close() is called on Reset() - // and before creating a new instance to avoid memory leaks. The views - // themselves should never be deleted directly. + // |language_menu_view_| and |keyboard_menu_view_| are parented by the top + // level view, either LockContentsView or LockDebugView. This allows the menu + // items to be clicked outside the bounds of the right pane view. LoginMenuView* language_menu_view_ = nullptr; LoginMenuView* keyboard_menu_view_ = nullptr; @@ -730,20 +714,14 @@ // Ignore press event inside the language and keyboard menu. LoginBaseBubbleView* language_menu_view = right_pane_->GetLanguageMenuView(); - LoginBaseBubbleView* keyboard_menu_view = right_pane_->GetKeyboardMenuView(); - if (language_menu_view) { - const gfx::Rect bounds = - language_menu_view->GetWidget()->GetWindowBoundsInScreen(); - if (bounds.Contains(event->root_location())) - return; - } + if (language_menu_view && + language_menu_view->GetBoundsInScreen().Contains(event->root_location())) + return; - if (keyboard_menu_view) { - const gfx::Rect bounds = - keyboard_menu_view->GetWidget()->GetWindowBoundsInScreen(); - if (bounds.Contains(event->root_location())) - return; - } + LoginBaseBubbleView* keyboard_menu_view = right_pane_->GetKeyboardMenuView(); + if (keyboard_menu_view && + keyboard_menu_view->GetBoundsInScreen().Contains(event->root_location())) + return; Hide(); }
diff --git a/ash/login/ui/login_expanded_public_account_view_unittest.cc b/ash/login/ui/login_expanded_public_account_view_unittest.cc index b40e7f8b..1dc294b 100644 --- a/ash/login/ui/login_expanded_public_account_view_unittest.cc +++ b/ash/login/ui/login_expanded_public_account_view_unittest.cc
@@ -162,14 +162,14 @@ views::View* link_view = styled_label_test.link_targets().begin()->first; TapOnView(link_view); EXPECT_NE(test_api.warning_dialog(), nullptr); - EXPECT_TRUE(test_api.warning_dialog()->IsVisible()); + EXPECT_TRUE(test_api.warning_dialog()->visible()); // When warning dialog is shown, tap outside of public account expanded view // should not hide it. TapOnView(other_view_); EXPECT_TRUE(public_account_->visible()); EXPECT_NE(test_api.warning_dialog(), nullptr); - EXPECT_TRUE(test_api.warning_dialog()->IsVisible()); + EXPECT_TRUE(test_api.warning_dialog()->visible()); // If the warning dialog is shown, escape key should close the waring dialog, // but not the public account view. @@ -222,10 +222,8 @@ EXPECT_TRUE(test_api.advanced_view()->visible()); // Tap on language selection button should bring up the language menu. - // Before the first show, language_menu_view is not initialized to anything. - EXPECT_EQ(nullptr, test_api.language_menu_view()); TapOnView(test_api.language_selection_button()); - EXPECT_TRUE(test_api.language_menu_view()->IsVisible()); + EXPECT_TRUE(test_api.language_menu_view()->visible()); // First language item is selected, and selected item should have focus. EXPECT_EQ(test_api.selected_language_item().value, kEnglishLanguageCode); @@ -235,13 +233,11 @@ // Select language item should close the language menu. GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); - EXPECT_EQ(nullptr, test_api.language_menu_view()); + EXPECT_FALSE(test_api.language_menu_view()->visible()); // Tap on keyboard selection button should bring up the keyboard menu. - // Before the first show, keyboard_menu_view is not initialized to anything. - EXPECT_EQ(nullptr, test_api.keyboard_menu_view()); TapOnView(test_api.keyboard_selection_button()); - EXPECT_TRUE(test_api.keyboard_menu_view()->IsVisible()); + EXPECT_TRUE(test_api.keyboard_menu_view()->visible()); // Second keyboard item is selected, and selected item should have focus. EXPECT_EQ(test_api.selected_keyboard_item().value, kKeyboardIdForItem2); @@ -251,7 +247,7 @@ // Select keyboard item should close the keyboard menu. GetEventGenerator()->PressKey(ui::KeyboardCode::VKEY_RETURN, 0); - EXPECT_EQ(nullptr, test_api.keyboard_menu_view()); + EXPECT_FALSE(test_api.keyboard_menu_view()->visible()); } TEST_P(LoginExpandedPublicAccountViewTest, ChangeMenuSelection) { @@ -263,7 +259,7 @@ // Try to change language selection. // Open language menu. TapOnView(test_api.language_selection_button()); - EXPECT_TRUE(test_api.language_menu_view()->IsVisible()); + EXPECT_TRUE(test_api.language_menu_view()->visible()); // Select second language item: // 1. Language menu will be closed automatically. @@ -278,14 +274,14 @@ EXPECT_EQ(test_api.selected_language_item().value, kEnglishLanguageCode); LoginMenuView::TestApi language_test_api(test_api.language_menu_view()); TapOnView(language_test_api.contents()->child_at(1)); - EXPECT_EQ(nullptr, test_api.language_menu_view()); + EXPECT_FALSE(test_api.language_menu_view()->visible()); EXPECT_EQ(test_api.selected_language_item().value, kFrenchLanguageCode); base::RunLoop().RunUntilIdle(); // Try to change keyboard selection. // Open keyboard menu. TapOnView(test_api.keyboard_selection_button()); - EXPECT_TRUE(test_api.keyboard_menu_view()->IsVisible()); + EXPECT_TRUE(test_api.keyboard_menu_view()->visible()); // Select first keyboard item: // 1. Keyboard menu will be closed automatically. @@ -293,7 +289,7 @@ EXPECT_EQ(test_api.selected_keyboard_item().value, kKeyboardIdForItem2); LoginMenuView::TestApi keyboard_test_api(test_api.keyboard_menu_view()); TapOnView(keyboard_test_api.contents()->child_at(0)); - EXPECT_EQ(nullptr, test_api.keyboard_menu_view()); + EXPECT_FALSE(test_api.keyboard_menu_view()->visible()); EXPECT_EQ(test_api.selected_keyboard_item().value, kKeyboardIdForItem1); }
diff --git a/ash/login/ui/login_menu_view.cc b/ash/login/ui/login_menu_view.cc index f83e98c..d4ec5c0 100644 --- a/ash/login/ui/login_menu_view.cc +++ b/ash/login/ui/login_menu_view.cc
@@ -73,7 +73,6 @@ return; on_highlight_.Run(true /*by_selection*/); - GetWidget()->Close(); } void OnHover(bool has_hover) { @@ -127,9 +126,7 @@ LoginButton* opener, const OnSelect& on_select) : LoginBaseBubbleView(anchor_view), opener_(opener), on_select_(on_select) { - set_can_activate(true); - set_margins(gfx::Insets()); - set_color(kMenuBackgroundColor); + SetBackground(views::CreateSolidBackground(kMenuBackgroundColor)); SetFocusBehavior(views::View::FocusBehavior::ALWAYS); scroller_ = new views::ScrollView(); @@ -174,6 +171,7 @@ } if (by_selection) { + SetVisible(false); MenuItemView* menu_view = static_cast<MenuItemView*>(highlight_item); on_select_.Run(menu_view->item()); }
diff --git a/ash/login/ui/login_tooltip_view.cc b/ash/login/ui/login_tooltip_view.cc index 8b7f3a8..c91ec00 100644 --- a/ash/login/ui/login_tooltip_view.cc +++ b/ash/login/ui/login_tooltip_view.cc
@@ -13,8 +13,6 @@ LoginTooltipView::LoginTooltipView(const base::string16& message, views::View* anchor_view) : LoginBaseBubbleView(anchor_view) { - SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); SetText(message); } @@ -32,4 +30,14 @@ node_data->role = ax::mojom::Role::kTooltip; } +gfx::Size LoginTooltipView::CalculatePreferredSize() const { + gfx::Size size; + + if (GetAnchorView()) + size.set_width(GetAnchorView()->width()); + + size.set_height(GetHeightForWidth(size.width())); + return size; +} + } // namespace ash
diff --git a/ash/login/ui/login_tooltip_view.h b/ash/login/ui/login_tooltip_view.h index c1836ba..cf3a6a2 100644 --- a/ash/login/ui/login_tooltip_view.h +++ b/ash/login/ui/login_tooltip_view.h
@@ -21,6 +21,9 @@ // LoginBaseBubbleView: void GetAccessibleNodeData(ui::AXNodeData* node_data) override; + // views::View: + gfx::Size CalculatePreferredSize() const override; + private: DISALLOW_COPY_AND_ASSIGN(LoginTooltipView); };
diff --git a/ash/login/ui/login_user_menu_view.cc b/ash/login/ui/login_user_menu_view.cc index ad7fec3..5ab0776 100644 --- a/ash/login/ui/login_user_menu_view.cc +++ b/ash/login/ui/login_user_menu_view.cc
@@ -38,9 +38,6 @@ // Margin around remove user button. constexpr int kUserMenuMarginAroundRemoveUserButtonDp = 4; -// Horizontal spacing with the anchor view. -constexpr int kAnchorViewUserMenuHorizontalSpacingDp = 98; - // Vertical spacing between the anchor view and user menu. constexpr int kAnchorViewUserMenuVerticalSpacingDp = 4; @@ -141,16 +138,8 @@ bubble_opener_(bubble_opener), on_remove_user_warning_shown_(on_remove_user_warning_shown), on_remove_user_requested_(on_remove_user_requested) { - // This view has content the user can interact with if the remove user - // button is displayed. - set_can_activate(show_remove_user); - - set_anchor_view_insets(gfx::Insets(kAnchorViewUserMenuVerticalSpacingDp, - kAnchorViewUserMenuHorizontalSpacingDp)); - // LoginUserMenuView does not use the parent margins. Further, because the // splitter spans the entire view set_margins cannot be used. - set_margins(gfx::Insets()); // The bottom margin is less the margin around the remove user button, which // is always visible. gfx::Insets margins( @@ -274,8 +263,8 @@ if (!remove_user_confirm_data_->visible()) { remove_user_confirm_data_->SetVisible(true); remove_user_label_->SetEnabledColor(kRemoveUserConfirmColor); + SetSize(GetPreferredSize()); - SizeToContents(); Layout(); // Fire an accessibility alert to make ChromeVox read the warning message @@ -290,15 +279,24 @@ return; } - // Immediately hide the widget with no animation before running the remove + // Immediately hide the bubble with no animation before running the remove // user callback. If an animation is triggered while the the views hierarchy // for this bubble is being torn down, we can get a crash. - GetWidget()->Hide(); + SetVisible(false); if (on_remove_user_requested_) std::move(on_remove_user_requested_).Run(); } +gfx::Point LoginUserMenuView::CalculatePosition() { + gfx::Point position = LoginBaseBubbleView::CalculatePosition(); + + if (GetAnchorView()) + position.set_y(position.y() + kAnchorViewUserMenuVerticalSpacingDp); + + return position; +} + void LoginUserMenuView::RequestFocus() { // This view has no actual interesting contents to focus, so immediately // forward to the button. @@ -306,26 +304,11 @@ remove_user_button_->RequestFocus(); } -void LoginUserMenuView::AddedToWidget() { - LoginBaseBubbleView::AddedToWidget(); - // Set up focus traversable parent so that keyboard focus can continue in - // the lock window, otherwise focus will be trapped inside the bubble. - if (GetAnchorView()) { - GetWidget()->SetFocusTraversableParent( - anchor_widget()->GetFocusTraversable()); - GetWidget()->SetFocusTraversableParentView(GetAnchorView()); - } +bool LoginUserMenuView::HasFocus() const { + return remove_user_button_ && remove_user_button_->HasFocus(); } const char* LoginUserMenuView::GetClassName() const { return "LoginUserMenuView"; } - -gfx::Size LoginUserMenuView::CalculatePreferredSize() const { - gfx::Size size = LoginBaseBubbleView::CalculatePreferredSize(); - // We don't use margins() directly which means that we need to account for - // the margin width here. Margin height is accounted for by the layout code. - size.Enlarge(kUserMenuMarginWidth, 0); - return size; -} } // namespace ash
diff --git a/ash/login/ui/login_user_menu_view.h b/ash/login/ui/login_user_menu_view.h index 7d29f83..d14a1fe 100644 --- a/ash/login/ui/login_user_menu_view.h +++ b/ash/login/ui/login_user_menu_view.h
@@ -47,15 +47,15 @@ // LoginBaseBubbleView: LoginButton* GetBubbleOpener() const override; + gfx::Point CalculatePosition() override; // views::ButtonListener: void ButtonPressed(views::Button* sender, const ui::Event& event) override; // views::View: void RequestFocus() override; - void AddedToWidget() override; + bool HasFocus() const override; const char* GetClassName() const override; - gfx::Size CalculatePreferredSize() const override; private: LoginButton* bubble_opener_ = nullptr;
diff --git a/ash/login/ui/login_user_menu_view_unittest.cc b/ash/login/ui/login_user_menu_view_unittest.cc index 749199a..81427f1 100644 --- a/ash/login/ui/login_user_menu_view_unittest.cc +++ b/ash/login/ui/login_user_menu_view_unittest.cc
@@ -38,9 +38,11 @@ &remove_warning_called), base::BindRepeating([](bool* remove_called) { *remove_called = true; }, &remove_called)); + anchor->AddChildView(bubble); + bubble->Show(); - EXPECT_TRUE(bubble->IsVisible()); + EXPECT_TRUE(bubble->visible()); // Focus the remove user button (the menu should forward focus to the remove // button). @@ -72,9 +74,10 @@ nullptr /*bubble_opener*/, true /*show_remove_user*/, base::DoNothing(), base::DoNothing()); + anchor->AddChildView(bubble); bubble->Show(); - EXPECT_TRUE(bubble->IsVisible()); + EXPECT_TRUE(bubble->visible()); LoginUserMenuView::TestApi test_api(bubble); views::View* remove_user_button = test_api.remove_user_button(); @@ -122,15 +125,17 @@ false /*is_owner*/, container /*anchor*/, bubble_opener, true /*show_remove_user*/, base::DoNothing(), base::DoNothing()); + container->AddChildView(bubble); + bubble->Show(); - EXPECT_TRUE(bubble->IsVisible()); + EXPECT_TRUE(bubble->visible()); EXPECT_TRUE(ink_drop_api.HasInkDrop()); EXPECT_EQ(ink_drop_api.GetInkDrop()->GetTargetInkDropState(), views::InkDropState::ACTIVATED); EXPECT_TRUE(ink_drop_api.GetInkDrop()->IsHighlightFadingInOrVisible()); bubble->Hide(); - EXPECT_FALSE(bubble->IsVisible()); + EXPECT_FALSE(bubble->visible()); EXPECT_EQ(ink_drop_api.GetInkDrop()->GetTargetInkDropState(), views::InkDropState::HIDDEN); EXPECT_FALSE(ink_drop_api.GetInkDrop()->IsHighlightFadingInOrVisible());
diff --git a/ash/login/ui/login_user_view.cc b/ash/login/ui/login_user_view.cc index be48aba..4c4b6f7 100644 --- a/ash/login/ui/login_user_view.cc +++ b/ash/login/ui/login_user_view.cc
@@ -422,17 +422,26 @@ this, base::Bind(&LoginUserView::OnHover, base::Unretained(this))); } -LoginUserView::~LoginUserView() { - if (menu_) { - menu_->GetWidget()->Close(); - menu_ = nullptr; - } -} +LoginUserView::~LoginUserView() = default; void LoginUserView::UpdateForUser(const mojom::LoginUserInfoPtr& user, bool animate) { current_user_ = user->Clone(); + if (menu_ && menu_->parent()) { + menu_->parent()->RemoveChildView(menu_); + delete menu_; + } + + menu_ = new LoginUserMenuView( + base::UTF8ToUTF16(current_user_->basic_user_info->display_name), + base::UTF8ToUTF16(current_user_->basic_user_info->display_email), + current_user_->basic_user_info->type, current_user_->is_device_owner, + dropdown_ /*anchor_view*/, dropdown_ /*bubble_opener*/, + current_user_->can_remove /*show_remove_user*/, on_remove_warning_shown_, + on_remove_); + menu_->SetVisible(false); + if (animate) { // Stop any existing animation. user_image_->layer()->GetAnimator()->StopAnimating(); @@ -529,30 +538,20 @@ // Handle click on the dropdown arrow. if (sender == dropdown_) { DCHECK(dropdown_); + DCHECK(menu_); // If menu is showing, just close it - if (menu_ && menu_->IsVisible()) { + if (menu_->visible()) { menu_->Hide(); return; } - // If the menu exists but is hidden, delete it and create a new menu. - if (menu_) { - menu_->GetWidget()->Close(); - menu_ = nullptr; - } - - menu_ = new LoginUserMenuView( - base::UTF8ToUTF16(current_user_->basic_user_info->display_name), - base::UTF8ToUTF16(current_user_->basic_user_info->display_email), - current_user_->basic_user_info->type, current_user_->is_device_owner, - dropdown_ /*anchor_view*/, dropdown_ /*bubble_opener*/, - current_user_->can_remove /*show_remove_user*/, - on_remove_warning_shown_, on_remove_); - bool opener_focused = menu_->GetBubbleOpener() && menu_->GetBubbleOpener()->HasFocus(); + if (!menu_->parent()) + login_views_utils::GetTopLevelParentView(this)->AddChildView(menu_); + menu_->Show(); // If the menu was opened by pressing Enter on the focused dropdown, focus @@ -644,6 +643,7 @@ AddChildView(tap_button_); if (dropdown_) AddChildView(dropdown_); + if (user_domain_) AddChildView(user_domain_);
diff --git a/ash/login/ui/login_user_view.h b/ash/login/ui/login_user_view.h index 59b69f4..61300eb 100644 --- a/ash/login/ui/login_user_view.h +++ b/ash/login/ui/login_user_view.h
@@ -120,9 +120,9 @@ LoginButton* dropdown_ = nullptr; TapButton* tap_button_ = nullptr; - // Bubble used for displaying the user dropdown menu. Owned by its widget, - // which is owned by LoginUserView. This widget is closed in - // LoginUserMenuView's d'tor. + // Bubble used for displaying the user dropdown menu. Its parent is the top + // level view, either LockContentsView or LockDebugView. This allows the menu + // to be clicked outside the bounds of the user view. LoginBaseBubbleView* menu_ = nullptr; // Show the domain information for public account user.
diff --git a/ash/login/ui/views_utils.cc b/ash/login/ui/views_utils.cc index 5b306df..a977b39 100644 --- a/ash/login/ui/views_utils.cc +++ b/ash/login/ui/views_utils.cc
@@ -74,5 +74,14 @@ return label; } +views::View* GetTopLevelParentView(views::View* view) { + views::View* v = view; + + while (v->parent() != nullptr) + v = v->parent(); + + return v; +} + } // namespace login_views_utils } // namespace ash
diff --git a/ash/login/ui/views_utils.h b/ash/login/ui/views_utils.h index d4fd2b1..4e1f7c0 100644 --- a/ash/login/ui/views_utils.h +++ b/ash/login/ui/views_utils.h
@@ -30,6 +30,9 @@ // Creates a standard text label for use in the login bubbles. views::Label* CreateBubbleLabel(const base::string16& message, SkColor color); +// Get the topmost level parent view for |view|. +views::View* GetTopLevelParentView(views::View* view); + } // namespace login_views_utils } // namespace ash
diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc deleted file mode 100644 index 3187358..0000000 --- a/ash/shell/app_list.cc +++ /dev/null
@@ -1,354 +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 <memory> -#include <string> -#include <utility> -#include <vector> - -#include "ash/app_list/app_list_controller_impl.h" -#include "ash/app_list/app_list_view_delegate.h" -#include "ash/app_list/model/app_list_item.h" -#include "ash/app_list/model/app_list_item_list.h" -#include "ash/app_list/model/app_list_model.h" -#include "ash/app_list/model/search/search_box_model.h" -#include "ash/app_list/model/search/search_model.h" -#include "ash/app_list/model/search/search_result.h" -#include "ash/session/session_controller.h" -#include "ash/shell.h" -#include "ash/shell/example_factory.h" -#include "ash/shell/toplevel_window.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/files/file_path.h" -#include "base/i18n/case_conversion.h" -#include "base/i18n/string_search.h" -#include "base/stl_util.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "ui/gfx/canvas.h" -#include "ui/gfx/font_list.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/views/examples/example_base.h" -#include "ui/views/examples/examples_window.h" - -namespace ash { -namespace shell { - -namespace { - -// WindowTypeShelfItem is an app item of app list. It carries a window -// launch type and launches corresponding example window when activated. -class WindowTypeShelfItem : public app_list::AppListItem { - public: - enum Type { - TOPLEVEL_WINDOW = 0, - NON_RESIZABLE_WINDOW, - LOCK_SCREEN, - WIDGETS_WINDOW, - EXAMPLES_WINDOW, - LAST_TYPE, - }; - - WindowTypeShelfItem(const std::string& id, Type type); - ~WindowTypeShelfItem() override; - - static gfx::ImageSkia GetIcon(Type type) { - static const SkColor kColors[] = { - SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN, - }; - - const int kIconSize = 128; - SkBitmap icon; - icon.allocN32Pixels(kIconSize, kIconSize); - icon.eraseColor(kColors[static_cast<int>(type) % base::size(kColors)]); - return gfx::ImageSkia::CreateFrom1xBitmap(icon); - } - - // The text below is not localized as this is an example code. - static std::string GetTitle(Type type) { - switch (type) { - case TOPLEVEL_WINDOW: - return "Create Window"; - case NON_RESIZABLE_WINDOW: - return "Create Non-Resizable Window"; - case LOCK_SCREEN: - return "Lock Screen"; - case WIDGETS_WINDOW: - return "Show Example Widgets"; - case EXAMPLES_WINDOW: - return "Open Views Examples Window"; - default: - return "Unknown window type."; - } - } - - // The text below is not localized as this is an example code. - static std::string GetDetails(Type type) { - // Assigns details only to some types so that we see both one-line - // and two-line results. - switch (type) { - case WIDGETS_WINDOW: - return "Creates a window to show example widgets"; - case EXAMPLES_WINDOW: - return "Creates a window to show views example."; - default: - return std::string(); - } - } - - static void ActivateItem(Type type, int event_flags) { - switch (type) { - case TOPLEVEL_WINDOW: { - ToplevelWindow::CreateParams params; - params.can_resize = true; - ToplevelWindow::CreateToplevelWindow(params); - break; - } - case NON_RESIZABLE_WINDOW: { - ToplevelWindow::CreateToplevelWindow(ToplevelWindow::CreateParams()); - break; - } - case LOCK_SCREEN: { - Shell::Get()->session_controller()->LockScreen(); - break; - } - case WIDGETS_WINDOW: { - CreateWidgetsWindow(); - break; - } - case EXAMPLES_WINDOW: { - views::examples::ShowExamplesWindow(base::DoNothing()); - break; - } - default: - break; - } - } - - void Activate(int event_flags) { ActivateItem(type_, event_flags); } - - private: - Type type_; - - DISALLOW_COPY_AND_ASSIGN(WindowTypeShelfItem); -}; - -WindowTypeShelfItem::WindowTypeShelfItem(const std::string& id, Type type) - : app_list::AppListItem(id), type_(type) { - std::string title(GetTitle(type)); - SetIcon(GetIcon(type)); - SetName(title); -} - -WindowTypeShelfItem::~WindowTypeShelfItem() = default; - -// ExampleSearchResult is an app list search result. It provides what icon to -// show, what should title and details text look like. It also carries the -// matching window launch type so that AppListViewDelegate knows how to open -// it. -class ExampleSearchResult : public app_list::SearchResult { - public: - ExampleSearchResult(WindowTypeShelfItem::Type type, - const base::string16& query) - : type_(type) { - SetIcon(WindowTypeShelfItem::GetIcon(type_)); - - base::string16 title = - base::UTF8ToUTF16(WindowTypeShelfItem::GetTitle(type_)); - set_title(title); - - Tags title_tags; - const size_t match_len = query.length(); - - // Highlight matching parts in title with bold. - // Note the following is not a proper way to handle i18n string. - title = base::i18n::ToLower(title); - size_t match_start = title.find(query); - while (match_start != base::string16::npos) { - title_tags.push_back( - Tag(Tag::MATCH, match_start, match_start + match_len)); - match_start = title.find(query, match_start + match_len); - } - set_title_tags(title_tags); - - base::string16 details = - base::UTF8ToUTF16(WindowTypeShelfItem::GetDetails(type_)); - set_details(details); - Tags details_tags; - details_tags.push_back(Tag(Tag::DIM, 0, details.length())); - set_details_tags(details_tags); - } - - WindowTypeShelfItem::Type type() const { return type_; } - - private: - WindowTypeShelfItem::Type type_; - - DISALLOW_COPY_AND_ASSIGN(ExampleSearchResult); -}; - -class ExampleAppListViewDelegate : public app_list::AppListViewDelegate { - public: - ExampleAppListViewDelegate() - : model_(std::make_unique<app_list::AppListModel>()), - search_model_(std::make_unique<app_list::SearchModel>()) { - PopulateApps(); - DecorateSearchBox(search_model_->search_box()); - } - - private: - void PopulateApps() { - for (int i = 0; i < static_cast<int>(WindowTypeShelfItem::LAST_TYPE); ++i) { - WindowTypeShelfItem::Type type = - static_cast<WindowTypeShelfItem::Type>(i); - std::string id = base::IntToString(i); - std::unique_ptr<WindowTypeShelfItem> shelf_item( - new WindowTypeShelfItem(id, type)); - model_->AddItem(std::move(shelf_item)); - } - } - - void DecorateSearchBox(app_list::SearchBoxModel* search_box_model) { - search_box_model->SetHintText(base::ASCIIToUTF16("Type to search...")); - } - - // Overridden from app_list::AppListViewDelegate: - app_list::AppListModel* GetModel() override { return model_.get(); } - - app_list::SearchModel* GetSearchModel() override { - return search_model_.get(); - } - - void OpenSearchResult(const std::string& result_id, - int event_flags) override { - const ExampleSearchResult* example_result = - static_cast<const ExampleSearchResult*>( - search_model_->FindSearchResult(result_id)); - WindowTypeShelfItem::ActivateItem(example_result->type(), event_flags); - } - - void LogSearchClick(const std::string& result_id, - int suggestion_index) override {} - - void InvokeSearchResultAction(const std::string& result_id, - int action_index, - int event_flags) override { - NOTIMPLEMENTED(); - } - - void StartAssistant() override { NOTIMPLEMENTED(); } - - void StartSearch(const base::string16& raw_query) override { - base::string16 query; - base::TrimWhitespace(raw_query, base::TRIM_ALL, &query); - query = base::i18n::ToLower(query); - - search_model_->results()->DeleteAll(); - if (query.empty()) - return; - - for (int i = 0; i < static_cast<int>(WindowTypeShelfItem::LAST_TYPE); ++i) { - WindowTypeShelfItem::Type type = - static_cast<WindowTypeShelfItem::Type>(i); - - base::string16 title = - base::UTF8ToUTF16(WindowTypeShelfItem::GetTitle(type)); - if (base::i18n::StringSearchIgnoringCaseAndAccents(query, title, NULL, - NULL)) { - search_model_->results()->Add( - std::make_unique<ExampleSearchResult>(type, query)); - } - } - } - - void ViewShown(int64_t display_id) override { - // Nothing needs to be done. - } - - void DismissAppList() override { - Shell::Get()->app_list_controller()->DismissAppList(); - } - - void ViewClosing() override { - // Nothing needs to be done. - } - - void ViewClosed() override { - // Nothing needs to be done. - } - - void GetWallpaperProminentColors( - GetWallpaperProminentColorsCallback callback) override { - NOTIMPLEMENTED(); - } - - void ActivateItem(const std::string& id, int event_flags) override { - WindowTypeShelfItem* item = - static_cast<WindowTypeShelfItem*>(model_->FindItem(id)); - if (!item) - return; - item->Activate(event_flags); - } - - void GetContextMenuModel(const std::string& id, - GetContextMenuModelCallback callback) override { - NOTIMPLEMENTED(); - } - - void GetSearchResultContextMenuModel( - const std::string& result_id, - GetContextMenuModelCallback callback) override { - NOTIMPLEMENTED(); - } - - void ContextMenuItemSelected(const std::string& id, - int command_id, - int event_flags) override { - NOTIMPLEMENTED(); - } - - void ShowWallpaperContextMenu(const gfx::Point& onscreen_location, - ui::MenuSourceType source_type) override { - NOTIMPLEMENTED(); - } - - void SearchResultContextMenuItemSelected(const std::string& result_id, - int command_id, - int event_flags) override { - NOTIMPLEMENTED(); - } - - bool ProcessHomeLauncherGesture(ui::GestureEvent* event, - const gfx::Point& screen_location) override { - NOTIMPLEMENTED(); - return false; - } - - bool CanProcessEventsOnApplistViews() override { - NOTIMPLEMENTED(); - return true; - } - - void GetNavigableContentsFactory( - content::mojom::NavigableContentsFactoryRequest request) override { - NOTIMPLEMENTED(); - } - - std::unique_ptr<app_list::AppListModel> model_; - std::unique_ptr<app_list::SearchModel> search_model_; - - DISALLOW_COPY_AND_ASSIGN(ExampleAppListViewDelegate); -}; - -} // namespace - -app_list::AppListViewDelegate* CreateAppListViewDelegate() { - return new ExampleAppListViewDelegate; -} - -} // namespace shell -} // namespace ash
diff --git a/ash/shell/content/client/shell_browser_main_parts.cc b/ash/shell/content/client/shell_browser_main_parts.cc index 8860ec0..ba370fc 100644 --- a/ash/shell/content/client/shell_browser_main_parts.cc +++ b/ash/shell/content/client/shell_browser_main_parts.cc
@@ -16,6 +16,7 @@ #include "ash/public/cpp/window_properties.h" #include "ash/shell.h" #include "ash/shell/content/embedded_browser.h" +#include "ash/shell/example_app_list_client.h" #include "ash/shell/example_session_controller_client.h" #include "ash/shell/shell_delegate_impl.h" #include "ash/shell/shell_views_delegate.h" @@ -146,6 +147,9 @@ base::Unretained(browser_context_.get()), GURL("https://www.google.com"))); + example_app_list_client_ = std::make_unique<ExampleAppListClient>( + Shell::Get()->app_list_controller()); + ash::Shell::GetPrimaryRootWindow()->GetHost()->Show(); // TODO(https://crbug.com/904148): These should not use |WarmService()|.
diff --git a/ash/shell/content/client/shell_browser_main_parts.h b/ash/shell/content/client/shell_browser_main_parts.h index 7286e929..7778da8 100644 --- a/ash/shell/content/client/shell_browser_main_parts.h +++ b/ash/shell/content/client/shell_browser_main_parts.h
@@ -31,6 +31,7 @@ namespace ash { namespace shell { +class ExampleAppListClient; class ExampleSessionControllerClient; class WindowWatcher; @@ -59,6 +60,7 @@ std::unique_ptr<wm::WMState> wm_state_; std::unique_ptr<ExampleSessionControllerClient> example_session_controller_client_; + std::unique_ptr<ExampleAppListClient> example_app_list_client_; std::unique_ptr<views::MusClient> mus_client_; DISALLOW_COPY_AND_ASSIGN(ShellBrowserMainParts);
diff --git a/ash/shell/example_app_list_client.cc b/ash/shell/example_app_list_client.cc new file mode 100644 index 0000000..2c49b70c --- /dev/null +++ b/ash/shell/example_app_list_client.cc
@@ -0,0 +1,258 @@ +// 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 "ash/shell/example_app_list_client.h" + +#include <algorithm> +#include <utility> + +#include "ash/app_list/app_list_controller_impl.h" +#include "ash/app_list/model/app_list_item.h" +#include "ash/app_list/model/search/search_result.h" +#include "ash/public/interfaces/constants.mojom.h" +#include "ash/session/session_controller.h" +#include "ash/shell.h" +#include "ash/shell/example_factory.h" +#include "ash/shell/toplevel_window.h" +#include "base/bind_helpers.h" +#include "base/i18n/case_conversion.h" +#include "base/i18n/string_search.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/views/examples/example_base.h" +#include "ui/views/examples/examples_window.h" + +namespace ash { +namespace shell { + +// WindowTypeShelfItem is an app item of app list. It carries a window +// launch type and launches corresponding example window when activated. +class WindowTypeShelfItem : public app_list::AppListItem { + public: + enum Type { + TOPLEVEL_WINDOW = 0, + NON_RESIZABLE_WINDOW, + LOCK_SCREEN, + WIDGETS_WINDOW, + EXAMPLES_WINDOW, + LAST_TYPE, + }; + + WindowTypeShelfItem(const std::string& id, Type type); + ~WindowTypeShelfItem() override; + + static gfx::ImageSkia GetIcon(Type type) { + static const SkColor kColors[] = { + SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorYELLOW, SK_ColorCYAN, + }; + + const int kIconSize = 128; + SkBitmap icon; + icon.allocN32Pixels(kIconSize, kIconSize); + icon.eraseColor(kColors[static_cast<int>(type) % base::size(kColors)]); + return gfx::ImageSkia::CreateFrom1xBitmap(icon); + } + + // The text below is not localized as this is an example code. + static std::string GetTitle(Type type) { + switch (type) { + case TOPLEVEL_WINDOW: + return "Create Window"; + case NON_RESIZABLE_WINDOW: + return "Create Non-Resizable Window"; + case LOCK_SCREEN: + return "Lock Screen"; + case WIDGETS_WINDOW: + return "Show Example Widgets"; + case EXAMPLES_WINDOW: + return "Open Views Examples Window"; + default: + return "Unknown window type."; + } + } + + // The text below is not localized as this is an example code. + static std::string GetDetails(Type type) { + // Assigns details only to some types so that we see both one-line + // and two-line results. + switch (type) { + case WIDGETS_WINDOW: + return "Creates a window to show example widgets"; + case EXAMPLES_WINDOW: + return "Creates a window to show views example."; + default: + return std::string(); + } + } + + static void ActivateItem(Type type, int event_flags) { + switch (type) { + case TOPLEVEL_WINDOW: { + ToplevelWindow::CreateParams params; + params.can_resize = true; + ToplevelWindow::CreateToplevelWindow(params); + break; + } + case NON_RESIZABLE_WINDOW: { + ToplevelWindow::CreateToplevelWindow(ToplevelWindow::CreateParams()); + break; + } + case LOCK_SCREEN: { + Shell::Get()->session_controller()->LockScreen(); + break; + } + case WIDGETS_WINDOW: { + CreateWidgetsWindow(); + break; + } + case EXAMPLES_WINDOW: { + views::examples::ShowExamplesWindow(base::DoNothing()); + break; + } + default: + break; + } + } + + Type type() const { return type_; } + + private: + Type type_; + + DISALLOW_COPY_AND_ASSIGN(WindowTypeShelfItem); +}; + +WindowTypeShelfItem::WindowTypeShelfItem(const std::string& id, Type type) + : app_list::AppListItem(id), type_(type) { + std::string title(GetTitle(type)); + SetIcon(GetIcon(type)); + SetName(title); +} + +WindowTypeShelfItem::~WindowTypeShelfItem() = default; + +// ExampleSearchResult is an app list search result. It provides what icon to +// show, what should title and details text look like. It also carries the +// matching window launch type so that AppListViewDelegate knows how to open +// it. +class ExampleSearchResult : public app_list::SearchResult { + public: + ExampleSearchResult(WindowTypeShelfItem::Type type, + const base::string16& query) + : type_(type) { + SetIcon(WindowTypeShelfItem::GetIcon(type_)); + + base::string16 title = + base::UTF8ToUTF16(WindowTypeShelfItem::GetTitle(type_)); + set_title(title); + + if (query.empty()) { + set_display_type(ash::SearchResultDisplayType::kRecommendation); + SetChipIcon(WindowTypeShelfItem::GetIcon(type_)); + } else { + Tags title_tags; + + // Highlight matching parts in title with bold. + // Note the following is not a proper way to handle i18n string. + title = base::i18n::ToLower(title); + const size_t match_len = query.length(); + size_t match_start = title.find(query); + while (match_start != base::string16::npos) { + title_tags.push_back( + Tag(Tag::MATCH, match_start, match_start + match_len)); + match_start = title.find(query, match_start + match_len); + } + set_title_tags(title_tags); + } + + base::string16 details = + base::UTF8ToUTF16(WindowTypeShelfItem::GetDetails(type_)); + set_details(details); + Tags details_tags; + details_tags.push_back(Tag(Tag::DIM, 0, details.length())); + set_details_tags(details_tags); + } + + WindowTypeShelfItem::Type type() const { return type_; } + + private: + WindowTypeShelfItem::Type type_; + + DISALLOW_COPY_AND_ASSIGN(ExampleSearchResult); +}; + +ExampleAppListClient::ExampleAppListClient(AppListControllerImpl* controller) + : controller_(controller) { + controller_->SetClient(CreateInterfacePtrAndBind()); + + PopulateApps(); + DecorateSearchBox(); +} + +ExampleAppListClient::~ExampleAppListClient() = default; + +void ExampleAppListClient::PopulateApps() { + for (int i = 0; i < static_cast<int>(WindowTypeShelfItem::LAST_TYPE); ++i) { + WindowTypeShelfItem::Type type = static_cast<WindowTypeShelfItem::Type>(i); + const std::string id = base::IntToString(i); + auto app = std::make_unique<WindowTypeShelfItem>(id, type); + controller_->AddItem(app->CloneMetadata()); + apps_.emplace_back(std::move(app)); + } +} + +void ExampleAppListClient::DecorateSearchBox() { + controller_->SetSearchHintText(base::ASCIIToUTF16("Type to search...")); +} + +void ExampleAppListClient::StartSearch(const base::string16& trimmed_query) { + base::string16 query; + query = base::i18n::ToLower(trimmed_query); + + search_results_.clear(); + std::vector<ash::mojom::SearchResultMetadataPtr> result_data; + for (int i = 0; i < static_cast<int>(WindowTypeShelfItem::LAST_TYPE); ++i) { + WindowTypeShelfItem::Type type = static_cast<WindowTypeShelfItem::Type>(i); + + const base::string16 title = + base::UTF8ToUTF16(WindowTypeShelfItem::GetTitle(type)); + if (query.empty() || base::i18n::StringSearchIgnoringCaseAndAccents( + query, title, nullptr, nullptr)) { + search_results_.emplace_back( + std::make_unique<ExampleSearchResult>(type, query)); + result_data.emplace_back(search_results_.back()->CloneMetadata()); + } + } + controller_->PublishSearchResults(std::move(result_data)); +} + +void ExampleAppListClient::OpenSearchResult(const std::string& result_id, + int event_flags) { + auto it = std::find_if( + search_results_.begin(), search_results_.end(), + [&result_id](const std::unique_ptr<ExampleSearchResult>& result) { + return result->id() == result_id; + }); + if (it == search_results_.end()) + return; + + WindowTypeShelfItem::ActivateItem((*it)->type(), event_flags); +} + +void ExampleAppListClient::ActivateItem(const std::string& id, + int event_flags) { + auto it = + std::find_if(apps_.begin(), apps_.end(), + [&id](const std::unique_ptr<WindowTypeShelfItem>& app) { + return app->id() == id; + }); + if (it == apps_.end()) + return; + + WindowTypeShelfItem::ActivateItem((*it)->type(), event_flags); +} + +} // namespace shell +} // namespace ash
diff --git a/ash/shell/example_app_list_client.h b/ash/shell/example_app_list_client.h new file mode 100644 index 0000000..810f1bf --- /dev/null +++ b/ash/shell/example_app_list_client.h
@@ -0,0 +1,49 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_SHELL_EXAMPLE_APP_LIST_CLIENT_H_ +#define ASH_SHELL_EXAMPLE_APP_LIST_CLIENT_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "ash/app_list/test/test_app_list_client.h" +#include "base/macros.h" + +namespace ash { + +class AppListControllerImpl; + +namespace shell { + +class WindowTypeShelfItem; +class ExampleSearchResult; + +class ExampleAppListClient : public TestAppListClient { + public: + explicit ExampleAppListClient(AppListControllerImpl* controller); + ~ExampleAppListClient() override; + + private: + void PopulateApps(); + void DecorateSearchBox(); + + // TestAppListClient: + void StartSearch(const base::string16& trimmed_query) override; + void OpenSearchResult(const std::string& result_id, int event_flags) override; + void ActivateItem(const std::string& id, int event_flags) override; + + AppListControllerImpl* controller_; + + std::vector<std::unique_ptr<WindowTypeShelfItem>> apps_; + std::vector<std::unique_ptr<ExampleSearchResult>> search_results_; + + DISALLOW_COPY_AND_ASSIGN(ExampleAppListClient); +}; + +} // namespace shell +} // namespace ash + +#endif // ASH_SHELL_EXAMPLE_APP_LIST_CLIENT_H_
diff --git a/base/android/java/src/org/chromium/base/task/TaskRunner.java b/base/android/java/src/org/chromium/base/task/TaskRunner.java index b901b64f..920ee0e 100644 --- a/base/android/java/src/org/chromium/base/task/TaskRunner.java +++ b/base/android/java/src/org/chromium/base/task/TaskRunner.java
@@ -27,12 +27,17 @@ void destroy(); /** + * Set this for instances that are cached between tests. + */ + void disableLifetimeCheck(); + + /** * Posts a task to run after a specified delay. * * @param task The task to be run. * @param delay The delay in milliseconds before the task can be run. */ - public void postDelayedTask(Runnable task, long delay); + void postDelayedTask(Runnable task, long delay); /** * Instructs the TaskRunner to initialize the native TaskRunner and migrate any tasks over to
diff --git a/base/android/java/src/org/chromium/base/task/TaskRunnerImpl.java b/base/android/java/src/org/chromium/base/task/TaskRunnerImpl.java index d672f08e..f351f68 100644 --- a/base/android/java/src/org/chromium/base/task/TaskRunnerImpl.java +++ b/base/android/java/src/org/chromium/base/task/TaskRunnerImpl.java
@@ -66,10 +66,8 @@ } } - /** - * Set this for instances that are cached between tests. - */ - void disableLifetimeCheck() { + @Override + public void disableLifetimeCheck() { LifetimeAssert.setSafeToGc(mLifetimeAssert, true); }
diff --git a/build/fuchsia/update_sdk.py b/build/fuchsia/update_sdk.py index 1adf8b8..90a5622 100755 --- a/build/fuchsia/update_sdk.py +++ b/build/fuchsia/update_sdk.py
@@ -26,7 +26,16 @@ def GetSdkHashForPlatform(): filename = '{platform}.sdk.sha1'.format(platform = GetHostOsFromPlatform()) - return os.path.join(os.path.dirname(__file__), filename) + hash_file = os.path.join(os.path.dirname(__file__), filename) + + with open(hash_file, 'r') as f: + sdk_hash = f.read().strip() + + if not sdk_hash: + print >>sys.stderr, 'No SHA1 found in %s' % hash_file + return 1 + + return sdk_hash def GetBucketForPlatform(): return 'gs://fuchsia/sdk/core/{platform}-amd64/'.format( @@ -78,12 +87,8 @@ sdk_root = os.path.join(REPOSITORY_ROOT, 'third_party', 'fuchsia-sdk') Cleanup(sdk_root) - hash_file = GetSdkHashForPlatform() - with open(hash_file, 'r') as f: - sdk_hash = f.read().strip() - + sdk_hash = GetSdkHashForPlatform() if not sdk_hash: - print >>sys.stderr, 'No SHA1 found in %s' % hash_file return 1 output_dir = os.path.join(sdk_root, 'sdk')
diff --git a/cc/paint/paint_op_reader.cc b/cc/paint/paint_op_reader.cc index a8b777f..96c632a 100644 --- a/cc/paint/paint_op_reader.cc +++ b/cc/paint/paint_op_reader.cc
@@ -33,9 +33,17 @@ static_cast<uint8_t>(PaintShader::Type::kShaderCount); } -bool IsValidSkShaderTileMode(SkShader::TileMode mode) { - // When Skia adds Decal, update this (skbug.com/7638) - return mode <= SkShader::kMirror_TileMode; +// SkShader::TileMode has no defined backing type, so read/write int32_t's. +// If read_mode is a valid tile mode, this returns true and updates mode to the +// equivalent enum value. Otherwise false is returned and mode is not modified. +bool ValidateAndGetSkShaderTileMode(int32_t read_mode, + SkShader::TileMode* mode) { + if (read_mode < 0 || read_mode >= SkShader::kTileModeCount) { + return false; + } + + *mode = static_cast<SkShader::TileMode>(read_mode); + return true; } bool IsValidPaintShaderScalingBehavior(PaintShader::ScalingBehavior behavior) { @@ -460,10 +468,16 @@ ReadSimple(&ref.flags_); ReadSimple(&ref.end_radius_); ReadSimple(&ref.start_radius_); - ReadSimple(&ref.tx_); - ReadSimple(&ref.ty_); - if (!IsValidSkShaderTileMode(ref.tx_) || !IsValidSkShaderTileMode(ref.ty_)) + + // See ValidateAndGetSkShaderTileMode + int32_t tx = 0; + int32_t ty = 0; + Read(&tx); + Read(&ty); + if (!ValidateAndGetSkShaderTileMode(tx, &ref.tx_) || + !ValidateAndGetSkShaderTileMode(ty, &ref.ty_)) { SetInvalid(); + } ReadSimple(&ref.fallback_color_); ReadSimple(&ref.scaling_behavior_); if (!IsValidPaintShaderScalingBehavior(ref.scaling_behavior_))
diff --git a/cc/paint/paint_op_writer.cc b/cc/paint/paint_op_writer.cc index 72783966..492e0fbc 100644 --- a/cc/paint/paint_op_writer.cc +++ b/cc/paint/paint_op_writer.cc
@@ -397,8 +397,10 @@ WriteSimple(shader->flags_); WriteSimple(shader->end_radius_); WriteSimple(shader->start_radius_); - WriteSimple(shader->tx_); - WriteSimple(shader->ty_); + // SkShader::TileMode does not have an explicitly defined backing type, so + // write a consistently sized value. + Write(static_cast<int32_t>(shader->tx_)); + Write(static_cast<int32_t>(shader->ty_)); WriteSimple(shader->fallback_color_); WriteSimple(shader->scaling_behavior_); if (shader->local_matrix_) {
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc index 5cb51724f..c4b19ee 100644 --- a/cc/tiles/gpu_image_decode_cache_unittest.cc +++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -284,6 +284,10 @@ PaintImage::kDefaultGeneratorClientId, color_space.ToSkColorSpace()); } + gfx::Size GetLargeImageSize() const { + return gfx::Size(1, max_texture_size_ + 1); + } + PaintImage CreatePaintImageInternal( const gfx::Size& size, sk_sp<SkColorSpace> color_space = nullptr, @@ -910,7 +914,7 @@ bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; - PaintImage image = CreatePaintImageInternal(gfx::Size(1, 24000)); + PaintImage image = CreatePaintImageInternal(GetLargeImageSize()); DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), @@ -1121,7 +1125,8 @@ bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; - PaintImage image = CreatePaintImageInternal(gfx::Size(1, 48000)); + PaintImage image = CreatePaintImageInternal( + gfx::Size(GetLargeImageSize().width(), GetLargeImageSize().height() * 2)); DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), quality, CreateMatrix(SkSize::Make(0.5f, 0.5f), is_decomposable), @@ -1142,8 +1147,8 @@ EXPECT_TRUE(decoded_draw_image.image()); EXPECT_TRUE(decoded_draw_image.is_budgeted()); // The mip level scale should never go below 0 in any dimension. - EXPECT_EQ(1, decoded_draw_image.image()->width()); - EXPECT_EQ(24000, decoded_draw_image.image()->height()); + EXPECT_EQ(GetLargeImageSize().width(), decoded_draw_image.image()->width()); + EXPECT_EQ(GetLargeImageSize().height(), decoded_draw_image.image()->height()); EXPECT_EQ(decoded_draw_image.filter_quality(), kMedium_SkFilterQuality); @@ -1241,7 +1246,7 @@ SkFilterQuality quality = kHigh_SkFilterQuality; cache->SetWorkingSetLimitsForTesting(0 /* max_bytes */, 0 /* max_items */); - PaintImage image = CreatePaintImageInternal(gfx::Size(1, 24000)); + PaintImage image = CreatePaintImageInternal(GetLargeImageSize()); DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), @@ -1533,13 +1538,14 @@ EXPECT_FALSE(low_result.task.get() == medium_result.task.get()); // Get the same image at kHigh_FilterQuality. We should re-use medium. - DrawImage large_draw_image( + DrawImage high_quality_draw_image( image, SkIRect::MakeWH(image.width(), image.height()), kHigh_SkFilterQuality, matrix, PaintImage::kDefaultFrameIndex); - ImageDecodeCache::TaskResult large_result = cache->GetTaskForImageAndRef( - large_draw_image, ImageDecodeCache::TracingInfo()); - EXPECT_TRUE(large_result.need_unref); - EXPECT_TRUE(medium_result.task.get() == large_result.task.get()); + ImageDecodeCache::TaskResult high_quality_result = + cache->GetTaskForImageAndRef(high_quality_draw_image, + ImageDecodeCache::TracingInfo()); + EXPECT_TRUE(high_quality_result.need_unref); + EXPECT_TRUE(medium_result.task.get() == high_quality_result.task.get()); TestTileTaskRunner::ProcessTask(low_result.task->dependencies()[0].get()); TestTileTaskRunner::ProcessTask(low_result.task.get()); @@ -1548,7 +1554,7 @@ cache->UnrefImage(low_draw_image); cache->UnrefImage(medium_draw_image); - cache->UnrefImage(large_draw_image); + cache->UnrefImage(high_quality_draw_image); } // Ensure that switching to a mipped version of an image after the initial @@ -1822,7 +1828,7 @@ SkFilterQuality quality = kHigh_SkFilterQuality; // Create an image that's too large to cache. - PaintImage image = CreatePaintImageInternal(gfx::Size(1, 24000)); + PaintImage image = CreatePaintImageInternal(GetLargeImageSize()); DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), @@ -2080,7 +2086,7 @@ SkFilterQuality quality = kHigh_SkFilterQuality; // Create an image that's too large to upload. - PaintImage image = CreatePaintImageInternal(gfx::Size(1, 24000)); + PaintImage image = CreatePaintImageInternal(GetLargeImageSize()); DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), @@ -2249,7 +2255,7 @@ bool is_decomposable = true; SkFilterQuality quality = kHigh_SkFilterQuality; - PaintImage image = CreateBitmapImageInternal(gfx::Size(10, 24000)); + PaintImage image = CreateBitmapImageInternal(GetLargeImageSize()); DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), quality, CreateMatrix(SkSize::Make(1.0f, 1.0f), is_decomposable), @@ -2359,21 +2365,21 @@ .set_paint_image_generator(generator) .TakePaintImage(); - DrawImage draw_image1( + DrawImage draw_image( paint_image, SkIRect::MakeWH(paint_image.width(), paint_image.height()), quality, CreateMatrix(SkSize::Make(0.5, 0.5), is_decomposable), PaintImage::kDefaultFrameIndex); - DecodedDrawImage decoded_image1 = - EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image1)); - ASSERT_TRUE(decoded_image1.image()); - EXPECT_EQ(decoded_image1.image()->width(), 50); - EXPECT_EQ(decoded_image1.image()->height(), 50); + DecodedDrawImage decoded_image = + EnsureImageBacked(cache->GetDecodedImageForDraw(draw_image)); + ASSERT_TRUE(decoded_image.image()); + EXPECT_EQ(decoded_image.image()->width(), 50); + EXPECT_EQ(decoded_image.image()->height(), 50); // We should have requested a scaled decode from the generator. ASSERT_EQ(generator->decode_infos().size(), 1u); EXPECT_EQ(generator->decode_infos().at(0).width(), 50); EXPECT_EQ(generator->decode_infos().at(0).height(), 50); - cache->DrawWithImageFinished(draw_image1, decoded_image1); + cache->DrawWithImageFinished(draw_image, decoded_image); } TEST_P(GpuImageDecodeCacheTest, DecodeToScaleNoneQuality) {
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedImageLoader.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedImageLoader.java index 7b3be4b..1265b25 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedImageLoader.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedImageLoader.java
@@ -20,12 +20,13 @@ import org.chromium.base.Callback; import org.chromium.base.DiscardableReferencePool; import org.chromium.base.SysUtils; -import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.cached_image_fetcher.CachedImageFetcher; import org.chromium.chrome.browser.cached_image_fetcher.InMemoryCachedImageFetcher; import org.chromium.chrome.browser.suggestions.ThumbnailGradient; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.Iterator; import java.util.List; @@ -84,7 +85,7 @@ Iterator<String> urlsIter, int widthPx, int heightPx, Consumer<Drawable> consumer) { if (!urlsIter.hasNext() || mCachedImageFetcher == null) { // Post to ensure callback is not run synchronously. - ThreadUtils.postOnUiThread(() -> consumer.accept(null)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> consumer.accept(null)); return; } @@ -95,7 +96,7 @@ loadDrawableWithIter(urlsIter, widthPx, heightPx, consumer); } else { // Post to ensure callback is not run synchronously. - ThreadUtils.postOnUiThread(() -> consumer.accept(drawable)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> consumer.accept(drawable)); } } else if (url.startsWith(OVERLAY_IMAGE_PREFIX)) { Uri uri = Uri.parse(url);
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 0957e5c..23594ae 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
@@ -24,8 +24,9 @@ import com.google.search.now.wire.feed.mockserver.MockServerProto.ConditionalResponse; import com.google.search.now.wire.feed.mockserver.MockServerProto.MockServer; -import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.io.FileInputStream; import java.io.IOException; @@ -118,7 +119,7 @@ if (mResponseDelay <= 0) { maybeAccept(httpResponse, responseConsumer); } else { - ThreadUtils.postOnUiThreadDelayed( + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, () -> maybeAccept(httpResponse, responseConsumer), mResponseDelay); } }
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index eea9faee..dca67fac 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -323,6 +323,8 @@ <data android:mimeType="audio/*" /> <data android:mimeType="image/*" /> <data android:mimeType="video/*" /> + <data android:scheme="file" /> + <data android:scheme="content" /> </intent-filter> </activity>
diff --git a/chrome/android/java/monochrome_public_apk.AndroidManifest.expected b/chrome/android/java/monochrome_public_apk.AndroidManifest.expected index 0a4d36b..f6ce084 100644 --- a/chrome/android/java/monochrome_public_apk.AndroidManifest.expected +++ b/chrome/android/java/monochrome_public_apk.AndroidManifest.expected
@@ -372,6 +372,8 @@ <data android:mimeType="audio/*" /> <data android:mimeType="image/*" /> <data android:mimeType="video/*" /> + <data android:scheme="file" /> + <data android:scheme="content" /> </intent-filter> </activity> <activity
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 1ab4aa1..96708ac5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -49,6 +49,7 @@ import org.chromium.base.metrics.CachedMetrics.EnumeratedHistogramSample; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.IntentHandler.IntentHandlerDelegate; import org.chromium.chrome.browser.IntentHandler.TabOpenType; @@ -148,6 +149,7 @@ import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.components.feature_engagement.Tracker; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsAccessibility; import org.chromium.content_public.common.ContentSwitches; @@ -2437,7 +2439,7 @@ Tracker tracker = TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile()); tracker.notifyEvent(EventConstants.SCREENSHOT_TAKEN_CHROME_IN_FOREGROUND); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { getToolbarManager().showDownloadPageTextBubble(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ServiceTabLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/ServiceTabLauncher.java index e5ea4f9..c2f8c24 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ServiceTabLauncher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ServiceTabLauncher.java
@@ -15,8 +15,8 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.ContextUtils; -import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.browserservices.BrowserServicesMetrics; import org.chromium.chrome.browser.browserservices.TrustedWebActivityClient; @@ -29,6 +29,7 @@ import org.chromium.chrome.browser.webapps.WebappDataStorage; import org.chromium.chrome.browser.webapps.WebappRegistry; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.common.Referrer; import org.chromium.content_public.common.ResourceRequestBody; @@ -73,7 +74,8 @@ // Note that this is used by PaymentRequestEvent.openWindow(). if (disposition == WindowOpenDisposition.NEW_POPUP) { if (!createPopupCustomTab(requestId, url, incognito)) { - ThreadUtils.postOnUiThread(() -> onWebContentsForRequestAvailable(requestId, null)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, + () -> onWebContentsForRequestAvailable(requestId, null)); } return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/SwipeRefreshHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/SwipeRefreshHandler.java index d94425b..f0c9341 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/SwipeRefreshHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/SwipeRefreshHandler.java
@@ -12,6 +12,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; import org.chromium.chrome.browser.gesturenav.SideSlideLayout; @@ -20,6 +21,7 @@ import org.chromium.chrome.browser.tab.TabWebContentsUserData; import org.chromium.components.feature_engagement.EventConstants; import org.chromium.components.feature_engagement.Tracker; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.third_party.android.swiperefresh.SwipeRefreshLayout; import org.chromium.ui.OverscrollAction; @@ -114,8 +116,8 @@ mSwipeRefreshLayout.setOnRefreshListener(() -> { cancelStopRefreshingRunnable(); - ThreadUtils.postOnUiThreadDelayed( - getStopRefreshingRunnable(), MAX_REFRESH_ANIMATION_DURATION_MS); + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, getStopRefreshingRunnable(), + MAX_REFRESH_ANIMATION_DURATION_MS); if (mAccessibilityRefreshString == null) { int resId = R.string.accessibility_swipe_refresh; mAccessibilityRefreshString = context.getResources().getString(resId); @@ -130,7 +132,7 @@ mDetachRefreshLayoutRunnable = null; detachSwipeRefreshLayoutIfNecessary(); }; - ThreadUtils.postOnUiThread(mDetachRefreshLayoutRunnable); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, mDetachRefreshLayoutRunnable); }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowBridge.java index 6bc5f7c..e8df2f06 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillNameFixFlowBridge.java
@@ -6,12 +6,13 @@ import android.app.Activity; -import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ResourceId; import org.chromium.chrome.browser.autofill.AutofillNameFixFlowPrompt.AutofillNameFixFlowPromptDelegate; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modaldialog.DialogDismissalCause; @@ -42,7 +43,7 @@ mNameFixFlowPrompt = null; // Clean up the native counterpart. This is posted to allow the native counterpart // to fully finish the construction of this glue object before we attempt to delete it. - ThreadUtils.postOnUiThread(() -> onPromptDismissed()); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> onPromptDismissed()); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java index 6919170..4af9c65c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantCoordinator.java
@@ -7,7 +7,7 @@ import android.view.View; import android.view.ViewGroup; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.autofill_assistant.header.AssistantHeaderModel; @@ -20,6 +20,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.snackbar.Snackbar; import org.chromium.chrome.browser.snackbar.SnackbarManager; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; /** @@ -119,7 +120,7 @@ mModel.getHeaderModel().set(AssistantHeaderModel.STATUS_MESSAGE, mActivity.getString(R.string.autofill_assistant_give_up)); } - ThreadUtils.postOnUiThreadDelayed( + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, () -> shutdownImmediately(reason), GRACEFUL_SHUTDOWN_DELAY_MS); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java index 755a801..05137cf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFacade.java
@@ -14,6 +14,7 @@ import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.autofill_assistant.metrics.DropOutReason; +import org.chromium.chrome.browser.metrics.UmaSessionStats; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.util.IntentUtils; @@ -52,6 +53,15 @@ "com.google.android.googlequicksearchbox", // GSA }; + /** + * Synthetic field trial names and group names should match those specified in + * google3/analysis/uma/dashboards/ + * .../variations/generate_server_hashes.py and + * .../website/components/variations_dash/variations_histogram_entry.js. + */ + private static final String SYNTHETIC_TRIAL = "AutofillAssistantTriggered"; + private static final String ENABLED_GROUP = "Enabled"; + /** Returns true if conditions are satisfied to attempt to start Autofill Assistant. */ public static boolean isConfigured(@Nullable Bundle intentExtras) { return getBooleanParameter(intentExtras, PARAMETER_ENABLED); @@ -59,6 +69,8 @@ /** Starts Autofill Assistant on the given {@code activity}. */ public static void start(ChromeActivity activity) { + // Register synthetic trial as soon as possible. + UmaSessionStats.registerSyntheticFieldTrial(SYNTHETIC_TRIAL, ENABLED_GROUP); // Have an "attempted starts" baseline for the drop out histogram. AutofillAssistantMetrics.recordDropOut(DropOutReason.AA_START); if (canStart(activity.getInitialIntent())) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java b/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java index 066d50be..53fe9f7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java
@@ -12,6 +12,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.ProcessInitException; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.init.BrowserParts; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.init.EmptyBrowserParts; @@ -19,6 +20,7 @@ import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerExternalUma; import org.chromium.components.background_task_scheduler.TaskParameters; import org.chromium.content_public.browser.BrowserStartupController; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -76,7 +78,7 @@ // Do not pass in wrappedCallback because this is a short-circuit reschedule. For UMA // purposes, tasks are started when runWithNative is called and does not consider // short-circuit reschedules such as this. - ThreadUtils.postOnUiThread(buildRescheduleRunnable(callback)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, buildRescheduleRunnable(callback)); return true; } @@ -115,14 +117,14 @@ protected final void runWithNative(final Context context, final Runnable startWithNativeRunnable, final Runnable rescheduleRunnable) { if (isNativeLoaded()) { - ThreadUtils.postOnUiThread(startWithNativeRunnable); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, startWithNativeRunnable); return; } final BrowserParts parts = new EmptyBrowserParts() { @Override public void finishNativeInitialization() { - ThreadUtils.postOnUiThread(startWithNativeRunnable); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, startWithNativeRunnable); } @Override public boolean startServiceManagerOnly() { @@ -130,11 +132,11 @@ } @Override public void onStartupFailure() { - ThreadUtils.postOnUiThread(rescheduleRunnable); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, rescheduleRunnable); } }; - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { // If task was stopped before we got here, don't start native initialization.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/PostMessageHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/PostMessageHandler.java index 5ae8239..3d50a33 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/PostMessageHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/PostMessageHandler.java
@@ -10,12 +10,13 @@ import android.support.customtabs.PostMessageBackend; import org.chromium.base.ContextUtils; -import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.browserservices.OriginVerifier.OriginVerificationListener; import org.chromium.chrome.browser.tab.Tab; import org.chromium.content_public.browser.MessagePort; import org.chromium.content_public.browser.MessagePort.MessageCallback; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsObserver; @@ -135,7 +136,7 @@ if (mWebContents == null || mWebContents.isDestroyed()) { return CustomTabsService.RESULT_FAILURE_MESSAGING_ERROR; } - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { // It is still possible that the page has navigated while this task is in the queue.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java b/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java index 7194d6b..ceefb78 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java
@@ -10,8 +10,10 @@ import org.chromium.base.Callback; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.task.PostTask; import org.chromium.components.signin.AccountManagerFacade; import org.chromium.components.signin.ChildAccountStatus; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.ui.base.WindowAndroid; /** @@ -65,7 +67,8 @@ Activity activity = windowAndroid.getActivity().get(); if (activity == null) { - ThreadUtils.postOnUiThread(() -> nativeOnReauthenticationResult(nativeCallback, false)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, + () -> nativeOnReauthenticationResult(nativeCallback, false)); return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java index 238bfc1..df9e78f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
@@ -17,13 +17,14 @@ import android.view.View.OnCreateContextMenuListener; import org.chromium.base.Callback; -import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.share.ShareHelper; import org.chromium.chrome.browser.share.ShareParams; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.MenuSourceType; import org.chromium.ui.base.WindowAndroid; @@ -126,7 +127,7 @@ List<Pair<Integer, List<ContextMenuItem>>> items = mPopulator.buildContextMenu(null, mActivity, mCurrentContextMenuParams); if (items.isEmpty()) { - ThreadUtils.postOnUiThread(mOnMenuClosed); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, mOnMenuClosed); return; } @@ -259,7 +260,7 @@ mPopulator.buildContextMenu(menu, v.getContext(), mCurrentContextMenuParams); if (items.isEmpty()) { - ThreadUtils.postOnUiThread(mOnMenuClosed); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, mOnMenuClosed); return; } ContextMenuUi menuUi = new PlatformContextMenuUi(menu);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java index 971b51f1..4e2f0a22 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java
@@ -31,6 +31,8 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -65,6 +67,7 @@ private static AtomicBoolean sDidBrowserCrashRecently = new AtomicBoolean(); @StringDef({ProcessType.BROWSER, ProcessType.RENDERER, ProcessType.GPU, ProcessType.OTHER}) + @Retention(RetentionPolicy.SOURCE) public @interface ProcessType { String BROWSER = "Browser"; String RENDERER = "Renderer";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crypto/CipherFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/crypto/CipherFactory.java index 6e18787..f976d9b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crypto/CipherFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/crypto/CipherFactory.java
@@ -10,8 +10,9 @@ import org.chromium.base.Log; import org.chromium.base.ObserverList; import org.chromium.base.SecureRandomInitializer; -import org.chromium.base.ThreadUtils; import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.io.IOException; import java.security.GeneralSecurityException; @@ -164,7 +165,7 @@ mData = data; // Posting an asynchronous task to notify the observers. - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { notifyCipherDataGenerated();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 7f79b6c..5e23274 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -42,6 +42,7 @@ import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.ActivityTabTaskDescriptionHelper; import org.chromium.chrome.browser.ChromeActivity; @@ -89,13 +90,13 @@ import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.NavigationEntry; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; import java.util.concurrent.TimeUnit; - /** * The activity for custom tabs. It will be launched on top of a client's task. */ @@ -713,12 +714,8 @@ // memory consumption, as the current renderer goes away. We create a renderer as a lot // of users open several Custom Tabs in a row. The delay is there to avoid jank in the // transition animation when closing the tab. - ThreadUtils.postOnUiThreadDelayed(new Runnable() { - @Override - public void run() { - WarmupManager.getInstance().createSpareWebContents(); - } - }, 500); + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, + () -> WarmupManager.getInstance().createSpareWebContents(), 500); } handleFinishAndClose();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java index add9ec0..5f440b18 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -45,6 +45,7 @@ import org.chromium.base.library_loader.ProcessInitException; import org.chromium.base.metrics.CachedMetrics.EnumeratedHistogramSample; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.ChromeApplication; @@ -68,6 +69,7 @@ import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.content_public.browser.BrowserStartupController; import org.chromium.content_public.browser.ChildProcessLauncherHelper; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.common.Referrer; import org.chromium.network.mojom.ReferrerPolicy; @@ -559,7 +561,7 @@ return false; } - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { doMayLaunchUrlOnUiThread( lowConfidence, session, uid, urlString, extras, otherLikelyBundles, true); }); @@ -579,7 +581,7 @@ if (!BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) .isStartupSuccessfullyCompleted()) { if (retryIfNotLoaded) { - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { doMayLaunchUrlOnUiThread(lowConfidence, session, uid, urlString, extras, otherLikelyBundles, false); }); @@ -684,7 +686,7 @@ if (!mClientManager.bindToPostMessageServiceForSession(session)) return false; final int uid = Binder.getCallingUid(); - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { // If the API is not enabled, we don't set the post message origin, which will avoid // PostMessageHandler initialization and disallow postMessage calls. if (!ChromeFeatureList.isEnabled(ChromeFeatureList.CCT_POST_MESSAGE_API)) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java index 39f1860..5a6862f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java
@@ -19,9 +19,9 @@ import android.view.ViewGroup; import org.chromium.base.Callback; -import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; import org.chromium.base.VisibleForTesting; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.UrlConstants; @@ -45,6 +45,7 @@ import org.chromium.chrome.browser.util.UrlUtilities; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationHandleProxy; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import java.lang.annotation.Retention; @@ -81,8 +82,8 @@ @Nullable private PostMessageHandler mDynamicModulePostMessageHandler; - @Retention(RetentionPolicy.SOURCE) @IntDef({View.VISIBLE, View.INVISIBLE, View.GONE}) + @Retention(RetentionPolicy.SOURCE) private @interface ToolbarVisibility {} // Default visibility of the Toolbar prior to any header customization. @@ -307,8 +308,10 @@ public boolean requestPostMessageChannel(Uri postMessageOrigin) { if (mDynamicModulePostMessageHandler == null) return false; - ThreadUtils.postOnUiThread(() -> - mDynamicModulePostMessageHandler.initializeWithPostMessageUri(postMessageOrigin)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, + () + -> mDynamicModulePostMessageHandler.initializeWithPostMessageUri( + postMessageOrigin)); return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java index 163fb551..c1bb778 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java
@@ -32,6 +32,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeTabbedActivity2; @@ -53,6 +54,7 @@ import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.NavigationEntry; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.common.Referrer; import org.chromium.network.mojom.ReferrerPolicy; import org.chromium.ui.base.PageTransition; @@ -557,7 +559,7 @@ // Loading URL will start a new navigation which cancels the current one // that this clobbering is being done for. It leads to UAF. To avoid that, // we're loading URL asynchronously. See https://crbug.com/732260. - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { // Tab might be closed when this is run. See https://crbug.com/662877
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitor.java b/chrome/android/java/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitor.java index e157129..b44a6d4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitor.java
@@ -4,13 +4,16 @@ package org.chromium.chrome.browser.feature_engagement; +import android.Manifest; import android.content.Context; +import android.content.pm.PackageManager; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Handler; import android.provider.MediaStore; import android.provider.MediaStore.Images.Media; +import android.support.v4.content.ContextCompat; import android.util.DisplayMetrics; import android.view.WindowManager; @@ -18,6 +21,9 @@ import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; +import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; /** * This class detects screenshots by monitoring the screenshots directory on internal and external @@ -77,7 +83,7 @@ if (!doesChangeLookLikeScreenshot(uri)) return; - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { if (mScreenshotMonitor == null) return; @@ -102,6 +108,15 @@ String[] mediaProjection = new String[] {MediaStore.Images.ImageColumns.DATE_TAKEN, MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.HEIGHT, MediaStore.MediaColumns.WIDTH, MediaStore.MediaColumns._ID}; + + // Check if READ_EXTERNAL_STORAGE permission are enabled. + if (ContextCompat.checkSelfPermission( + ContextUtils.getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + RecordUserAction.record("Tab.Screenshot.WithoutStoragePermission"); + return false; + } + try { cursor = ContextUtils.getApplicationContext().getContentResolver().query( storeUri, mediaProjection, null, null, null);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java index a76758e1..255957c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java
@@ -10,7 +10,9 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.io.IOException; import java.net.HttpURLConnection; @@ -52,7 +54,7 @@ } private static void postResult(final ConnectivityCheckerCallback callback, final int result) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { callback.onResult(result);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java index 3a491cd..540ba17 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityTask.java
@@ -11,7 +11,9 @@ import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.net.ConnectionType; import org.chromium.net.NetworkChangeNotifier; @@ -255,7 +257,7 @@ private void postCallbackResult() { if (mCallback == null) return; - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { mCallback.onResult(get());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/FeedbackCollector.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/FeedbackCollector.java index 1812d24..cdd2c1a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/FeedbackCollector.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/FeedbackCollector.java
@@ -15,8 +15,10 @@ import org.chromium.base.CollectionUtil; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.ArrayList; import java.util.HashMap; @@ -216,7 +218,7 @@ final Callback<FeedbackCollector> callback = mCallback; mCallback = null; - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { callback.onResult(FeedbackCollector.this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java index e07a2228..a4f7aba 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java
@@ -10,12 +10,13 @@ import android.graphics.Rect; import android.support.annotation.Nullable; -import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.tab.SadTab; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.ui.UiUtils; import org.chromium.ui.base.WindowAndroid; @@ -54,7 +55,7 @@ // If neither the compositor nor the Android view screenshot tasks were kicked off, admit // defeat and return a {@code null} screenshot. - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { onBitmapReceived(null); @@ -101,7 +102,7 @@ private boolean takeAndroidViewScreenshot(@Nullable final Activity activity) { if (activity == null) return false; - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { Bitmap bitmap = UiUtils.generateScaledScreenshot(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/StaticScreenshotSource.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/StaticScreenshotSource.java index b912d4e8..ee22958b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/StaticScreenshotSource.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/StaticScreenshotSource.java
@@ -6,7 +6,8 @@ import android.graphics.Bitmap; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; /** A implementation of {@link ScreenshotSource} that returns back a {@link Bitmap} given to it. */ class StaticScreenshotSource implements ScreenshotSource { @@ -23,7 +24,7 @@ // ScreenshotSource implementation. @Override public void capture(Runnable callback) { - ThreadUtils.postOnUiThread(callback); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, callback); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/DefaultSearchEngineFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/DefaultSearchEngineFirstRunFragment.java index 59e58bb..73f0a5d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/DefaultSearchEngineFirstRunFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/DefaultSearchEngineFirstRunFragment.java
@@ -11,14 +11,15 @@ import android.view.ViewGroup; import android.widget.Button; -import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.locale.DefaultSearchEngineDialogHelper; import org.chromium.chrome.browser.locale.LocaleManager; import org.chromium.chrome.browser.locale.LocaleManager.SearchEnginePromoType; import org.chromium.chrome.browser.search_engines.TemplateUrlService; import org.chromium.chrome.browser.widget.RadioButtonLayout; +import org.chromium.content_public.browser.UiThreadTaskTraits; /** A {@link Fragment} that presents a set of search engines for the user to choose from. */ public class DefaultSearchEngineFirstRunFragment extends Fragment implements FirstRunFragment { @@ -72,7 +73,7 @@ if (isVisibleToUser) { if (mSearchEnginePromoDialoType == LocaleManager.SearchEnginePromoType.DONT_SHOW) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { getPageDelegate().advanceToNextPage();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java index 98d60622..4e87d81 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/ChromeFullscreenManager.java
@@ -18,9 +18,9 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.ApplicationStatus.ActivityStateListener; import org.chromium.base.ApplicationStatus.WindowFocusChangedListener; -import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; import org.chromium.base.library_loader.LibraryLoader; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.fullscreen.FullscreenHtmlApiHandler.FullscreenHtmlApiDelegate; import org.chromium.chrome.browser.tab.BrowserControlsVisibilityDelegate; @@ -31,6 +31,7 @@ import org.chromium.chrome.browser.tabmodel.TabSelectionType; import org.chromium.chrome.browser.vr.VrModuleProvider; import org.chromium.chrome.browser.widget.ControlContainer; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.common.BrowserControlsState; import java.lang.annotation.Retention; @@ -264,12 +265,10 @@ // notification bar when this was done in onStart()). exitPersistentFullscreenMode(); } else if (newState == ActivityState.STARTED) { - ThreadUtils.postOnUiThreadDelayed(new Runnable() { - @Override - public void run() { - mBrowserVisibilityDelegate.showControlsTransient(); - } - }, ACTIVITY_RETURN_SHOW_REQUEST_DELAY_MS); + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, + () + -> mBrowserVisibilityDelegate.showControlsTransient(), + ACTIVITY_RETURN_SHOW_REQUEST_DELAY_MS); } else if (newState == ActivityState.DESTROYED) { ApplicationStatus.unregisterActivityStateListener(this); ApplicationStatus.unregisterWindowFocusChangedListener(this);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationLayout.java index a28b64f..75cffabd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationLayout.java
@@ -16,6 +16,9 @@ import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.tab.Tab; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * FrameLayout that supports side-wise slide gesture for history navigation. Inheriting * class may need to override {@link #isGestureConsumed()} if {@link #onTouchEvent} cannot @@ -24,6 +27,7 @@ */ public class HistoryNavigationLayout extends FrameLayout { @IntDef({GestureState.NONE, GestureState.STARTED, GestureState.DRAGGED}) + @Retention(RetentionPolicy.SOURCE) private @interface GestureState { int NONE = 0; int STARTED = 1;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/SideSlideLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/SideSlideLayout.java index 2697a55b..1560d89e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/SideSlideLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/SideSlideLayout.java
@@ -17,6 +17,9 @@ import org.chromium.chrome.R; import org.chromium.third_party.android.swiperefresh.CircleImageView; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * The SideSlideLayout can be used whenever the user navigates the contents * of a view using horizontal gesture. Shows an arrow widget moving horizontally @@ -34,6 +37,7 @@ UmaNavigationType.BACK_TOUCHPAD, UmaNavigationType.FORWARD_TOUCHSCREEN, UmaNavigationType.BACK_TOUCHSCREEN, UmaNavigationType.RELOAD_TOUCHPAD, UmaNavigationType.RELOAD_TOUCHSCREEN, UmaNavigationType.NAVIGATION_TYPE_COUNT}) + @Retention(RetentionPolicy.SOURCE) private @interface UmaNavigationType { int NAVIGATION_TYPE_NONE = 0; int FORWARD_TOUCHPAD = 1;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java index d5916fb..78885772c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java
@@ -14,6 +14,7 @@ import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder; import org.chromium.chrome.browser.notifications.NotificationBuilderFactory; import org.chromium.chrome.browser.notifications.NotificationConstants; +import org.chromium.chrome.browser.notifications.NotificationMetadata; import org.chromium.chrome.browser.notifications.NotificationUmaTracker; import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions; @@ -37,8 +38,13 @@ ChromeNotificationBuilder builder = NotificationBuilderFactory - .createChromeNotificationBuilder( - true /* preferCompat */, ChannelDefinitions.ChannelId.INCOGNITO) + .createChromeNotificationBuilder(true /* preferCompat */, + ChannelDefinitions.ChannelId.INCOGNITO, + null /* remoteAppPackageName */, + new NotificationMetadata( + NotificationUmaTracker.SystemNotificationType + .CLOSE_INCOGNITO, + INCOGNITO_TABS_OPEN_TAG, INCOGNITO_TABS_OPEN_ID)) .setContentTitle(title) .setContentIntent( IncognitoNotificationService.getRemoveAllIncognitoTabsIntent(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java index 9c3c9563..f09691a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java
@@ -26,6 +26,7 @@ import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.document.DocumentUtils; +import org.chromium.chrome.browser.notifications.PendingIntentProvider; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.content_public.browser.BrowserStartupController; @@ -43,10 +44,11 @@ "com.google.android.apps.chrome.incognito.CLOSE_ALL_INCOGNITO"; @VisibleForTesting - public static PendingIntent getRemoveAllIncognitoTabsIntent(Context context) { + public static PendingIntentProvider getRemoveAllIncognitoTabsIntent(Context context) { Intent intent = new Intent(context, IncognitoNotificationService.class); intent.setAction(ACTION_CLOSE_ALL_INCOGNITO); - return PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + return PendingIntentProvider.getService( + context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); } /** Empty public constructor needed by Android. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/DownloadProgressInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/DownloadProgressInfoBar.java index 01cab91..a646f11 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/DownloadProgressInfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/DownloadProgressInfoBar.java
@@ -13,12 +13,13 @@ import android.view.View; import android.widget.TextView; -import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.download.DownloadInfoBarController; import org.chromium.chrome.browser.tab.Tab; import org.chromium.components.offline_items_collection.ContentId; +import org.chromium.content_public.browser.UiThreadTaskTraits; /** * An {@link InfoBar} to provide information about currently running downloads. @@ -151,7 +152,7 @@ } private void restartIconAnimation() { - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { if (mAnimatedDrawable == null) return; mAnimatedDrawable.start(); });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderImpl.java index df09423..c57af3e8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderImpl.java
@@ -19,7 +19,9 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.instantapps.InstantAppsHandler; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.installedapp.mojom.InstalledAppProvider; import org.chromium.installedapp.mojom.RelatedApplication; import org.chromium.mojo.system.MojoException; @@ -27,7 +29,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; - /** * Android implementation of the InstalledAppProvider service defined in * installed_app_provider.mojom @@ -353,6 +354,6 @@ * @return True if the Runnable was successfully placed into the message queue. */ protected void delayThenRun(Runnable r, long delayMillis) { - ThreadUtils.postOnUiThreadDelayed(r, delayMillis); + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, r, delayMillis); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/locale/SogouPromoDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/locale/SogouPromoDialog.java index c8970253..389455c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/locale/SogouPromoDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/locale/SogouPromoDialog.java
@@ -36,9 +36,9 @@ public class SogouPromoDialog extends PromoDialog { // These constants are here to back a uma histogram. Append new constants at the end of this // list (do not rearrange) and don't forget to update NUM_ENTRIES. - @Retention(RetentionPolicy.SOURCE) @IntDef({UserChoice.USE_SOGOU, UserChoice.KEEP_GOOGLE, UserChoice.SETTINGS, UserChoice.BACK_KEY}) + @Retention(RetentionPolicy.SOURCE) private @interface UserChoice { int USE_SOGOU = 0; int KEEP_GOOGLE = 1;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java index b821b83..b433f07 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionItem.java
@@ -32,8 +32,8 @@ * show a progress indicator over the same space. See {@link State}. */ public class ActionItem extends OptionalLeaf { - @Retention(RetentionPolicy.SOURCE) @IntDef({State.HIDDEN, State.BUTTON, State.LOADING}) + @Retention(RetentionPolicy.SOURCE) public @interface State { int HIDDEN = 0; int BUTTON = 1;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ScrollToLoadListener.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ScrollToLoadListener.java index a76287e..e6146c217 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ScrollToLoadListener.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ScrollToLoadListener.java
@@ -7,7 +7,8 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; /** * The ScrollToLoadListener requests fetching more items when the user approaches the end of their @@ -77,7 +78,7 @@ if (sentinelBecameVisible || sentinelVisibleButTooFewItemsFetched) { mPreviousItemCount = mAdapter.getItemCount(); // We need to post this since onScrolled may run during a measure & layout pass. - ThreadUtils.postOnUiThread(mSections::fetchMore); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, mSections::fetchMore); } mSentinelPreviouslyVisible = sentinelVisible;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/ConnectivityDetector.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/ConnectivityDetector.java index d598503..750536f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/ConnectivityDetector.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/indicator/ConnectivityDetector.java
@@ -47,9 +47,9 @@ public static final int PROBE_WITH_URL_COUNT = 2; // Denotes the connection state. - @Retention(RetentionPolicy.SOURCE) @IntDef({ConnectionState.NONE, ConnectionState.DISCONNECTED, ConnectionState.NO_INTERNET, ConnectionState.CAPTIVE_PORTAL, ConnectionState.VALIDATED}) + @Retention(RetentionPolicy.SOURCE) public @interface ConnectionState { // Initial state or connection state can't be evaluated. int NONE = 0; @@ -67,10 +67,10 @@ } // Denotes how the connectivity check is done. - @Retention(RetentionPolicy.SOURCE) @IntDef({ConnectivityCheckingState.NOT_STARTED, ConnectivityCheckingState.FROM_SYSTEM, ConnectivityCheckingState.PROBE_DEFAULT_URL, ConnectivityCheckingState.PROBE_FALLBACK_URL}) + @Retention(RetentionPolicy.SOURCE) private @interface ConnectivityCheckingState { // Not started. int NOT_STARTED = 0; @@ -85,11 +85,11 @@ // The result of the HTTP probing. Defined in tools/metrics/histograms/enums.xml. // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. - @Retention(RetentionPolicy.SOURCE) @IntDef({ProbeResult.NO_INTERNET, ProbeResult.SERVER_ERROR, ProbeResult.NOT_VALIDATED, ProbeResult.VALIDATED_WITH_NO_CONTENT, ProbeResult.VALIDATED_WITH_OK_BUT_ZERO_CONTENT_LENGTH, ProbeResult.VALIDATED_WITH_OK_BUT_NO_CONTENT_LENGTH}) + @Retention(RetentionPolicy.SOURCE) private @interface ProbeResult { // The network is connected, but it can't reach the Internet, i.e. connecting to a hotspot // that is not conencted to Internet.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java b/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java index f9518e8..04958d11 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java
@@ -19,6 +19,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeVersionInfo; @@ -26,6 +27,7 @@ import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksReader; import org.chromium.chrome.browser.util.UrlUtilities; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.ArrayList; import java.util.List; @@ -307,7 +309,7 @@ */ public static void setOnInitializeAsyncFinished(final Runnable callback) { if (sIsInitialized) { - ThreadUtils.postOnUiThread(callback); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, callback); } else { sInitializeAsyncCallbacks.add(callback); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentInstrument.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentInstrument.java index dec8abe..5456047 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentInstrument.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentInstrument.java
@@ -7,8 +7,9 @@ import android.graphics.drawable.Drawable; import android.support.annotation.Nullable; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.widget.prefeditor.EditableOption; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.payments.mojom.PaymentDetailsModifier; import org.chromium.payments.mojom.PaymentItem; import org.chromium.payments.mojom.PaymentMethodData; @@ -178,7 +179,7 @@ * @param callback The callback to return abort result. */ public void abortPaymentApp(AbortCallback callback) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { callback.onInstrumentAbortResult(false);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java index 955b035..48d0a9d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java
@@ -16,11 +16,13 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNIAdditionalImport; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.components.payments.OriginSecurityChecker; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.payments.mojom.PaymentDetailsModifier; import org.chromium.payments.mojom.PaymentItem; @@ -90,7 +92,7 @@ ThreadUtils.assertOnUiThread(); if (!ChromeFeatureList.isEnabled(ChromeFeatureList.SERVICE_WORKER_PAYMENT_APPS)) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { callback.onHasServiceWorkerPaymentAppsResponse(false); @@ -111,7 +113,7 @@ ThreadUtils.assertOnUiThread(); if (!ChromeFeatureList.isEnabled(ChromeFeatureList.SERVICE_WORKER_PAYMENT_APPS)) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { callback.onGetServiceWorkerPaymentAppsInfo( @@ -142,7 +144,7 @@ ThreadUtils.assertOnUiThread(); if (sCanMakePaymentForTesting) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { callback.onCanMakePaymentResponse(true);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/SettingsAutofillAndPaymentsObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/SettingsAutofillAndPaymentsObserver.java index fdff69d..73d2ed5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/SettingsAutofillAndPaymentsObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/SettingsAutofillAndPaymentsObserver.java
@@ -5,7 +5,9 @@ package org.chromium.chrome.browser.payments; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.ArrayList; import java.util.List; @@ -84,7 +86,7 @@ */ public void notifyOnAddressUpdated(AutofillAddress address) { for (Observer observer : sObservers) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { observer.onAddressUpdated(address); @@ -100,7 +102,7 @@ */ public void notifyOnAddressDeleted(String guid) { for (Observer observer : sObservers) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { observer.onAddressDeleted(guid); @@ -116,7 +118,7 @@ */ public void notifyOnCreditCardUpdated(CreditCard card) { for (Observer observer : sObservers) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { observer.onCreditCardUpdated(card); @@ -132,7 +134,7 @@ */ public void notifyOnCreditCardDeleted(String guid) { for (Observer observer : sObservers) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { observer.onCreditCardDeleted(guid);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ManageSyncPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ManageSyncPreferences.java index fbd9263..3205e22 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ManageSyncPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ManageSyncPreferences.java
@@ -23,9 +23,9 @@ import android.view.MenuItem; import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.autofill.PersonalDataManager; @@ -39,6 +39,7 @@ import org.chromium.components.signin.ChromeSigninController; import org.chromium.components.sync.ModelType; import org.chromium.components.sync.PassphraseType; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.HashSet; import java.util.Set; @@ -187,7 +188,7 @@ public boolean onPreferenceChange(Preference preference, Object o) { // A change to Preference state hasn't been applied yet. Defer // updateSyncStateFromSelectedModelTypes so it gets the updated state from isChecked(). - ThreadUtils.postOnUiThread(this::updateSyncStateFromSelectedModelTypes); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, this::updateSyncStateFromSelectedModelTypes); return true; } @@ -201,7 +202,7 @@ public void syncStateChanged() { // This is invoked synchronously from ProfileSyncService.setChosenDataTypes, postpone the // update to let updateSyncStateFromSelectedModelTypes finish saving the state. - ThreadUtils.postOnUiThread(this::updateSyncPreferences); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, this::updateSyncPreferences); } /** @@ -232,7 +233,7 @@ mSyncEverything.isChecked(), getSelectedModelTypes()); PersonalDataManager.setPaymentsIntegrationEnabled(mSyncPaymentsIntegration.isChecked()); // Some calls to setChosenDataTypes don't trigger syncStateChanged, so schedule update here. - ThreadUtils.postOnUiThread(this::updateSyncPreferences); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, this::updateSyncPreferences); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java index 7b409164..8d44c5b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java
@@ -27,9 +27,9 @@ import org.chromium.base.BuildInfo; import org.chromium.base.ContextUtils; -import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsEnabledStateUtils; import org.chromium.chrome.browser.contextualsearch.ContextualSearchFieldTrial; @@ -50,6 +50,7 @@ import org.chromium.components.signin.ChromeSigninController; import org.chromium.components.sync.AndroidSyncSettings; import org.chromium.components.sync.ProtocolErrorClientAction; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -277,7 +278,7 @@ if (PREF_SYNC_REQUESTED.equals(key)) { assert canDisableSync(); SyncPreferenceUtils.enableSync((boolean) newValue); - ThreadUtils.postOnUiThread(this::updatePreferences); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, this::updatePreferences); } else if (PREF_SEARCH_SUGGESTIONS.equals(key)) { mPrefServiceBridge.setSearchSuggestEnabled((boolean) newValue); } else if (PREF_SAFE_BROWSING.equals(key)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/DialogManager.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/DialogManager.java index c4af4bf..8cd3b6e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/DialogManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/DialogManager.java
@@ -9,7 +9,8 @@ import android.support.annotation.IntDef; import android.support.annotation.Nullable; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -135,7 +136,7 @@ if (mDialogFragment != null) mDialogFragment.dismiss(); // Post the callback to ensure that it is always run asynchronously, even if hide() took a // shortcut for a missing shown(). - if (mCallback != null) ThreadUtils.postOnUiThread(mCallback); + if (mCallback != null) PostTask.postTask(UiThreadTaskTraits.DEFAULT, mCallback); reset(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/provider/ChromeBrowserProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/provider/ChromeBrowserProvider.java index b4c9385..e5e033130 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/provider/ChromeBrowserProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/provider/ChromeBrowserProvider.java
@@ -34,12 +34,14 @@ import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.ProcessInitException; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.database.SQLiteCursor; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.content_public.browser.BrowserStartupController; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -1160,7 +1162,7 @@ UserHandle callingUserHandle = Binder.getCallingUserHandle(); if (callingUserHandle != null && !callingUserHandle.equals(android.os.Process.myUserHandle())) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { getContext().getContentResolver().notifyChange(uri, null);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java b/chrome/android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java index 9cba473..3aa6620a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java
@@ -10,6 +10,8 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.ArrayList; import java.util.List; @@ -202,7 +204,7 @@ // If the load has already been completed, post a load complete to the observer. Done // as an asynchronous call to keep the client code predictable in the loaded/unloaded state. if (isLoaded()) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { if (!mLoadListeners.hasObserver(listener)) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GcmUma.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GcmUma.java index fe61a68..ef39d8c0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GcmUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/GcmUma.java
@@ -6,11 +6,12 @@ import android.content.Context; -import org.chromium.base.ThreadUtils; import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.task.PostTask; import org.chromium.content_public.browser.BrowserStartupController; import org.chromium.content_public.browser.BrowserStartupController.StartupCallback; +import org.chromium.content_public.browser.UiThreadTaskTraits; /** * Helper Class for GCM UMA Collection. @@ -59,7 +60,7 @@ } private static void onNativeLaunched(final Context context, final Runnable task) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java index 0ec0a21c..fb0a3ca 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java
@@ -19,10 +19,12 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.init.ProcessInitializationHandler; import org.chromium.components.signin.ChromeSigninController; import org.chromium.components.signin.OAuth2TokenService; import org.chromium.components.sync.SyncConstants; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.io.IOException; import java.util.UUID; @@ -40,7 +42,7 @@ public void deliverMessage(final String to, final Bundle data) { final Bundle dataToSend = createDeepCopy(data); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { doDeliverMessage(ContextUtils.getApplicationContext(), to, dataToSend);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java index 9a50b94b..3f09eff 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
@@ -24,6 +24,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; import org.chromium.chrome.browser.externalauth.UserRecoverableErrorHandler; import org.chromium.chrome.browser.sync.SyncUserDataWiper; @@ -32,6 +33,7 @@ import org.chromium.components.signin.AccountTrackerService; import org.chromium.components.signin.ChromeSigninController; import org.chromium.components.sync.AndroidSyncSettings; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.ArrayList; import java.util.List; @@ -328,7 +330,7 @@ } private void notifySignInAllowedChanged() { - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { for (SignInAllowedObserver observer : mSignInAllowedObservers) { observer.onSignInAllowedChanged(); } @@ -542,13 +544,13 @@ mCallbacksWaitingForPendingOperation.add(runnable); return; } - ThreadUtils.postOnUiThread(runnable); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, runnable); } private void notifyCallbacksWaitingForOperation() { ThreadUtils.assertOnUiThread(); for (Runnable callback : mCallbacksWaitingForPendingOperation) { - ThreadUtils.postOnUiThread(callback); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, callback); } mCallbacksWaitingForPendingOperation.clear(); } @@ -725,7 +727,7 @@ assert mSignOutState != null; if (mSignOutState.mCallback != null) { - ThreadUtils.postOnUiThread(mSignOutState.mCallback); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, mSignOutState.mCallback); } mSignOutState = null; notifyCallbacksWaitingForOperation();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java index 43d0327..579b6e8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java
@@ -31,8 +31,8 @@ import org.chromium.base.BuildInfo; import org.chromium.base.ContextUtils; import org.chromium.base.StrictModeContext; -import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.PersonalDataManager; import org.chromium.chrome.browser.invalidation.InvalidationController; @@ -52,6 +52,7 @@ import org.chromium.components.sync.ModelType; import org.chromium.components.sync.PassphraseType; import org.chromium.components.sync.ProtocolErrorClientAction; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -187,7 +188,7 @@ SyncPreferenceUtils.enableSync((boolean) newValue); // Must be done asynchronously because the switch state isn't updated // until after this function exits. - ThreadUtils.postOnUiThread(this::updateSyncStateFromSwitch); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, this::updateSyncStateFromSwitch); return true; }); @@ -210,13 +211,13 @@ @Override public boolean onPreferenceChange(Preference preference, Object newValue) { if (preference == mSyncEverything) { - ThreadUtils.postOnUiThread(this::updateDataTypeState); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, this::updateDataTypeState); return true; } if (isSyncTypePreference(preference)) { final boolean syncAutofillToggled = preference == mSyncAutofill; final boolean preferenceChecked = (boolean) newValue; - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { if (syncAutofillToggled) { // If the user checks the autofill sync checkbox, then enable and check the // payments integration checkbox.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java index 7a08e73..e6b4dd74 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java
@@ -4,9 +4,9 @@ package org.chromium.chrome.browser.tab; -import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.ChromeActivity; @@ -18,6 +18,7 @@ import org.chromium.components.navigation_interception.InterceptNavigationDelegate; import org.chromium.components.navigation_interception.NavigationParams; import org.chromium.content_public.browser.NavigationController; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.common.ConsoleMessageLevel; @@ -258,7 +259,7 @@ } // Defer closing a tab (and the associated WebContents) till the navigation // request and the throttle finishes the job with it. - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { mTab.getTabModelSelector().closeTab(mTab);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index feab79b..51c44b78 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -34,11 +34,11 @@ import org.chromium.base.Log; import org.chromium.base.ObserverList; import org.chromium.base.ObserverList.RewindableIterator; -import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; import org.chromium.base.UserDataHost; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.ChromeActionModeCallback; @@ -100,6 +100,7 @@ import org.chromium.content_public.browser.ImeEventObserver; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.SelectionPopupController; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsAccessibility; import org.chromium.content_public.common.BrowserControlsState; @@ -2867,7 +2868,7 @@ mDownloadIPHBubble.addOnDismissListener(new OnDismissListener() { @Override public void onDismiss() { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { hideMediaDownloadInProductHelp();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java index 2b39c16..604941d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
@@ -26,6 +26,7 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.ntp.NewTabPage; @@ -33,6 +34,7 @@ import org.chromium.chrome.browser.tab.TabIdManager; import org.chromium.chrome.browser.tab.TabState; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; @@ -1244,7 +1246,7 @@ TimeUnit.MILLISECONDS); } - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { // This eventually calls serializeTabModelSelector() which much be called
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java index 434abc7..2af807a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java
@@ -427,7 +427,7 @@ @Override public boolean shouldDisplaySearchTerms() { - return getDisplaySearchTerms() != null; + return getDisplaySearchTerms() != null && !isPreview(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java index eb98b15..6bbd85d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java
@@ -10,7 +10,7 @@ import android.view.View; import org.chromium.base.Callback; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeTabbedActivity; @@ -28,6 +28,7 @@ import org.chromium.components.feature_engagement.EventConstants; import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.components.feature_engagement.Tracker; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.ui.widget.ViewRectProvider; /** @@ -185,7 +186,7 @@ // Post a request to show the IPH bubble to allow time for a layout pass. Since the bubble // is shown on startup, the anchor view may not have a height initially see // https://crbug.com/871537. - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { if (activity.isActivityDestroyed()) return; if (TextUtils.equals(featureName, FeatureConstants.NTP_BUTTON_FEATURE)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 6f19bbe6..394f83d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -23,12 +23,12 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.Callback; -import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.CachedMetrics.ActionEvent; import org.chromium.base.metrics.CachedMetrics.EnumeratedHistogramSample; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeTabbedActivity; @@ -108,6 +108,7 @@ import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.NavigationEntry; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.AsyncViewProvider; import org.chromium.ui.base.DeviceFormFactor; @@ -1563,7 +1564,7 @@ // Record startup performance statistics long elapsedTime = SystemClock.elapsedRealtime() - activityCreationTimeMs; if (elapsedTime < RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS) { - ThreadUtils.postOnUiThreadDelayed(() -> { + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, () -> { onDeferredStartup(activityCreationTimeMs, activityName); }, RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS - elapsedTime); return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java index dab1986..4fa4a3b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java
@@ -42,6 +42,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.WindowDelegate; @@ -62,6 +63,7 @@ import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.widget.TintedDrawable; import org.chromium.components.url_formatter.UrlFormatter; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.common.ContentUrlConstants; import org.chromium.net.GURLUtils; import org.chromium.ui.base.Clipboard; @@ -368,7 +370,8 @@ && !title.equals(getToolbarDataProvider().getCurrentUrl()) && !title.equals(ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL)) { // Delay the title animation until security icon animation finishes. - ThreadUtils.postOnUiThreadDelayed(mTitleAnimationStarter, TITLE_ANIM_DELAY_MS); + PostTask.postDelayedTask( + UiThreadTaskTraits.DEFAULT, mTitleAnimationStarter, TITLE_ANIM_DELAY_MS); } mTitleBar.setText(title);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingController.java b/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingController.java index 475b6765..3b2b600 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingController.java
@@ -14,11 +14,12 @@ import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ObserverList; -import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.task.AsyncTask; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.preferences.developer.TracingPreferences; import org.chromium.content_public.browser.TracingControllerAndroid; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.ui.widget.Toast; import java.io.File; @@ -247,7 +248,7 @@ TracingNotificationManager.updateTracingActiveNotification(pair.first); - ThreadUtils.postOnUiThreadDelayed( + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, () -> { updateBufferUsage(); }, UPDATE_BUFFER_USAGE_INTERVAL_MILLIS); }); } @@ -303,7 +304,7 @@ // Delete the file after an hour. This won't work if the app quits in the meantime, so we // also check for old files when TraceController is created. File tracingTempFile = mTracingTempFile; - ThreadUtils.postOnUiThreadDelayed(() -> { + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, () -> { new DeleteTempFileTask(tracingTempFile) .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }, DELETE_AFTER_SHARE_TIMEOUT_MILLIS);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrDelegateFallback.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrDelegateFallback.java index c026a13..b34df98 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrDelegateFallback.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrDelegateFallback.java
@@ -14,12 +14,13 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.ContextUtils; import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; import org.chromium.base.compat.ApiHelperForN; import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.metrics.CachedMetrics; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.ui.widget.Toast; import java.util.concurrent.atomic.AtomicBoolean; @@ -157,7 +158,7 @@ onVrModuleInstallFinished(success); }); - ThreadUtils.postOnUiThreadDelayed(() -> { + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, () -> { if (enterVrHandled.getAndSet(true)) return; assert !VrModuleProvider.isModuleInstalled(); onVrModuleInstallFailure(activity);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrFallbackUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrFallbackUtils.java index 4ef5bad9..18dee2e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrFallbackUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrFallbackUtils.java
@@ -8,13 +8,14 @@ import android.content.Context; import android.support.v4.app.NotificationCompat; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.notifications.NotificationBuilderFactory; import org.chromium.chrome.browser.notifications.NotificationConstants; import org.chromium.chrome.browser.notifications.NotificationManagerProxy; import org.chromium.chrome.browser.notifications.NotificationManagerProxyImpl; import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions; +import org.chromium.content_public.browser.UiThreadTaskTraits; /** Class providing utils for when the VR module is not installed. */ /* package */ class VrFallbackUtils { @@ -23,7 +24,7 @@ /** Shows immersive notification informing the user that the VR browser is not ready yet. */ public static void showFailureNotification(Context context) { - ThreadUtils.postOnUiThreadDelayed(() -> { + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, () -> { NotificationManagerProxy notificationManager = new NotificationManagerProxyImpl(context); Notification notification = @@ -44,7 +45,7 @@ // Close notification after a few seconds as it is only really relevant right after // accessing the VR browser failed. - ThreadUtils.postOnUiThreadDelayed(() -> { + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, () -> { notificationManager.cancel(NotificationConstants.NOTIFICATION_ID_PREPARING_VR); }, PREPARING_VR_NOTIFICATION_TIMEOUT_MS); }, PREPARING_VR_NOTIFICATION_DELAY_MS);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrShell.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrShell.java index 251d1c7..7dc0a49 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr/VrShell.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/VrShell.java
@@ -32,6 +32,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.task.PostTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeTabbedActivity; @@ -54,6 +55,7 @@ import org.chromium.chrome.browser.vr.keyboard.VrInputMethodManagerWrapper; import org.chromium.content_public.browser.ImeAdapter; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.ViewEventSink; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.common.BrowserControlsState; @@ -569,7 +571,7 @@ @Override public void onRequestPermissionsResult( String[] permissions, int[] grantResults) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { VrShellDelegate.enterVrIfNecessary();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java index 776594a..00b5a48 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -25,11 +25,11 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApplicationStatus; import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; +import org.chromium.base.task.PostTask; import org.chromium.blink_public.platform.WebDisplayMode; import org.chromium.chrome.R; import org.chromium.chrome.browser.IntentHandler; @@ -57,6 +57,7 @@ import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.ScreenOrientationProvider; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.net.NetworkChangeNotifier; import org.chromium.ui.base.PageTransition; @@ -202,13 +203,14 @@ WebappActivity.this, getControlContainerLayoutId(), getToolbarLayoutId()); if (WebappActivity.this.isActivityFinishing()) return; if (mainView != null) { - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { if (WebappActivity.this.isActivityFinishing()) return; onLayoutInflated(mainView); }); } else { if (WebappActivity.this.isActivityFinishing()) return; - ThreadUtils.postOnUiThread(() -> WebappActivity.super.doLayoutInflation()); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, + () -> WebappActivity.super.doLayoutInflation()); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ThumbnailProviderImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ThumbnailProviderImpl.java index 93196a79..dc101dd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ThumbnailProviderImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ThumbnailProviderImpl.java
@@ -12,8 +12,10 @@ import org.chromium.base.DiscardableReferencePool; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.BitmapCache; import org.chromium.chrome.browser.util.ConversionUtils; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.ArrayDeque; import java.util.Deque; @@ -133,7 +135,7 @@ } private void processQueue() { - ThreadUtils.postOnUiThread(this::processNextRequest); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, this::processNextRequest); } private String getKey(String contentId, int bitmapSizePx) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ServicificationBackgroundService.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ServicificationBackgroundService.java index 3997bee8..f8f37cf 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ServicificationBackgroundService.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ServicificationBackgroundService.java
@@ -11,10 +11,12 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.ProcessInitException; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.init.BrowserParts; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; import org.chromium.chrome.browser.init.EmptyBrowserParts; import org.chromium.content_public.browser.BrowserStartupController; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; @@ -73,7 +75,7 @@ // the BrowserStartupControllerImpl#browserStartupComplete() is called on the UI thread when // the full browser starts. So we can use it to checks whether the // {@link mFullBrowserStartupDone} has been set to true. - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { Assert.assertFalse("The full browser is started instead of ServiceManager only.",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/OriginVerifierTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/OriginVerifierTest.java index ba79d0fd..7b05035 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/OriginVerifierTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/OriginVerifierTest.java
@@ -16,6 +16,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.chrome.browser.ChromeActivity; @@ -28,6 +29,7 @@ import org.chromium.chrome.browser.preferences.privacy.BrowsingDataBridge; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.HashSet; import java.util.Set; @@ -107,13 +109,15 @@ @SmallTest public void testOnlyHttpsAllowed() throws InterruptedException { Origin origin = new Origin(Uri.parse("LOL")); - ThreadUtils.postOnUiThread(() -> - mHandleAllUrlsVerifier.start(new TestOriginVerificationListener(), origin)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, + () -> mHandleAllUrlsVerifier.start(new TestOriginVerificationListener(), origin)); Assert.assertTrue( mVerificationResultSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); Assert.assertFalse(mLastVerified); - ThreadUtils.postOnUiThread(() -> - mHandleAllUrlsVerifier.start(new TestOriginVerificationListener(), mHttpOrigin)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, + () + -> mHandleAllUrlsVerifier.start( + new TestOriginVerificationListener(), mHttpOrigin)); Assert.assertTrue( mVerificationResultSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); Assert.assertFalse(mLastVerified); @@ -122,11 +126,14 @@ @Test @SmallTest public void testMultipleRelationships() throws Exception { - ThreadUtils.postOnUiThread(() -> - OriginVerifier.addVerificationOverride( - PACKAGE_NAME, mHttpsOrigin, CustomTabsService.RELATION_USE_AS_ORIGIN)); - ThreadUtils.postOnUiThread(() -> - mUseAsOriginVerifier.start(new TestOriginVerificationListener(), mHttpsOrigin)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, + () + -> OriginVerifier.addVerificationOverride(PACKAGE_NAME, mHttpsOrigin, + CustomTabsService.RELATION_USE_AS_ORIGIN)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, + () + -> mUseAsOriginVerifier.start( + new TestOriginVerificationListener(), mHttpsOrigin)); Assert.assertTrue( mVerificationResultSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); Assert.assertTrue(mLastVerified);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java index 20b50ef..8a20858 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java
@@ -98,7 +98,9 @@ public void incognitoNotificationClosesCustomTab() throws Exception { launchIncognitoCustomTab(); - IncognitoNotificationService.getRemoveAllIncognitoTabsIntent(mActivity).send(); + IncognitoNotificationService.getRemoveAllIncognitoTabsIntent(mActivity) + .getPendingIntent() + .send(); CriteriaHelper.pollUiThread(mActivity::isFinishing); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index ed52e482..6b60827 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -68,6 +68,7 @@ import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.task.PostTask; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisabledTest; @@ -114,6 +115,7 @@ import org.chromium.chrome.test.util.browser.LocationSettingsTestUtil; import org.chromium.chrome.test.util.browser.contextmenu.ContextMenuUtils; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContentsObserver; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; @@ -1511,7 +1513,7 @@ renderProcessCallback.notifyCalled(); } }; - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { WebContentsUtils.simulateRendererKilled( mCustomTabActivityTestRule.getActivity().getActivityTab().getWebContents(), false); @@ -2536,7 +2538,7 @@ } }; tabToBeReparented.addObserver(observer); - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { getActivity().openCurrentUrlInBrowser(true); Assert.assertNull(getActivity().getActivityTab()); });
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java index c7e93a9..eb07b24 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java
@@ -34,6 +34,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.library_loader.LibraryProcessType; +import org.chromium.base.task.PostTask; import org.chromium.base.test.util.AnnotationRule; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; @@ -55,6 +56,7 @@ import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.offlinepages.SavePageResult; import org.chromium.components.url_formatter.UrlFormatter; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.TestTouchUtils; @@ -278,7 +280,7 @@ ChromeTabbedActivity.class.getName(), /* result = */ null, false); CustomTabActivity customTabActivity = mCustomTabActivityTestRule.getActivity(); final Tab tab = customTabActivity.getActivityTab(); - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { Assert.assertEquals(publisherUrl, tab.getTrustedCdnPublisherUrl()); customTabActivity.openCurrentUrlInBrowser(true); Assert.assertNull(customTabActivity.getActivityTab());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitorTest.java index 866f4e4..757dc9d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitorTest.java
@@ -15,8 +15,10 @@ import org.chromium.base.Log; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.base.test.util.Feature; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @@ -132,7 +134,7 @@ private void startMonitoringOnUiThreadBlocking() { final Semaphore semaphore = new Semaphore(0); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { mTestScreenshotMonitor.startMonitoring(); @@ -150,7 +152,7 @@ private void stopMonitoringOnUiThreadBlocking() { final Semaphore semaphore = new Semaphore(0); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { mTestScreenshotMonitor.stopMonitoring(); @@ -169,7 +171,7 @@ private void assertScreenshotShowUiCountOnUiThreadBlocking(int expectedCount) { final Semaphore semaphore = new Semaphore(0); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { semaphore.release();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/ConsumerSyncWrapper.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/ConsumerSyncWrapper.java index a0e047e..1ff5769 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/ConsumerSyncWrapper.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/ConsumerSyncWrapper.java
@@ -8,7 +8,8 @@ import org.junit.Assert; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -52,7 +53,7 @@ static public <T> void waitForConsumer( Consumer<T> consumer, Consumer<Consumer<T>> operation, long timeoutMs) { ConsumerSyncWrapper<T> wrapper = new ConsumerSyncWrapper<>(consumer); - ThreadUtils.postOnUiThread(() -> operation.accept(wrapper)); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> operation.accept(wrapper)); wrapper.blockAndWrappedAccept(timeoutMs); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/ToastHWATest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/ToastHWATest.java index d8ad1bd..928be153 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/ToastHWATest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/ToastHWATest.java
@@ -21,6 +21,7 @@ import org.chromium.base.BaseSwitches; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisabledTest; @@ -35,6 +36,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.browser.contextmenu.ContextMenuUtils; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.net.test.EmbeddedTestServer; import org.chromium.ui.widget.Toast; @@ -170,7 +172,7 @@ final AtomicBoolean accelerated = new AtomicBoolean(); final CallbackHelper listenerCalled = new CallbackHelper(); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { // We are using Toast.makeText(context, ...) instead of new Toast(context)
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/Utils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/Utils.java index 09263697..7daa33b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/Utils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/Utils.java
@@ -12,8 +12,10 @@ import org.chromium.base.SysUtils; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.base.test.util.CallbackHelper; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.HashSet; import java.util.Set; @@ -82,7 +84,7 @@ final AtomicBoolean accelerated = new AtomicBoolean(); final CallbackHelper listenerCalled = new CallbackHelper(); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { final Dialog dialog = new Dialog(activity);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java index 3802b288..6035185 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java
@@ -57,8 +57,10 @@ } private void sendClearIncognitoIntent() throws CanceledException { - PendingIntent clearIntent = IncognitoNotificationService.getRemoveAllIncognitoTabsIntent( - InstrumentationRegistry.getTargetContext()); + PendingIntent clearIntent = + IncognitoNotificationService + .getRemoveAllIncognitoTabsIntent(InstrumentationRegistry.getTargetContext()) + .getPendingIntent(); clearIntent.send(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/init/ChainedTasksTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/init/ChainedTasksTest.java index 12b9ce0..a4e6564 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/init/ChainedTasksTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/init/ChainedTasksTest.java
@@ -11,7 +11,9 @@ import org.junit.runner.RunWith; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.ArrayList; import java.util.Arrays; @@ -158,7 +160,7 @@ tasks.start(false); Assert.assertTrue(secondTaskFinished.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); - ThreadUtils.postOnUiThread(new TestRunnable(messages, "High Priority")); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new TestRunnable(messages, "High Priority")); waitForHighPriorityTask.release(); Assert.assertTrue(finished.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/router/MockMediaRouteProvider.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/router/MockMediaRouteProvider.java index de97c09..ff4be40 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/router/MockMediaRouteProvider.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/router/MockMediaRouteProvider.java
@@ -7,7 +7,8 @@ import android.support.annotation.Nullable; import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.ArrayList; import java.util.HashMap; @@ -88,12 +89,10 @@ final ArrayList<MediaSink> sinks = new ArrayList<MediaSink>(); sinks.add(new MediaSink(SINK_ID1, SINK_NAME1, null)); sinks.add(new MediaSink(SINK_ID2, SINK_NAME2, null)); - ThreadUtils.postOnUiThreadDelayed(new Runnable() { - @Override - public void run() { - mManager.onSinksReceived(sourceId, MockMediaRouteProvider.this, sinks); - } - }, mSinksObservedDelayMillis); + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, + () + -> mManager.onSinksReceived(sourceId, MockMediaRouteProvider.this, sinks), + mSinksObservedDelayMillis); } @Override @@ -112,13 +111,11 @@ if (mCreateRouteDelayMillis == 0) { doCreateRoute(sourceId, sinkId, presentationId, origin, tabId, nativeRequestId); } else { - ThreadUtils.postOnUiThreadDelayed(new Runnable() { - @Override - public void run() { - doCreateRoute( - sourceId, sinkId, presentationId, origin, tabId, nativeRequestId); - } - }, mCreateRouteDelayMillis); + PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, + () + -> doCreateRoute(sourceId, sinkId, presentationId, origin, tabId, + nativeRequestId), + mCreateRouteDelayMillis); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NtpUiCaptureTestData.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NtpUiCaptureTestData.java index b72678c1..b6edce5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NtpUiCaptureTestData.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NtpUiCaptureTestData.java
@@ -12,7 +12,7 @@ import android.graphics.Bitmap; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.favicon.IconType; import org.chromium.chrome.browser.favicon.LargeIconBridge; import org.chromium.chrome.browser.ntp.snippets.KnownCategories; @@ -26,6 +26,7 @@ import org.chromium.chrome.test.util.browser.suggestions.FakeMostVisitedSites; import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource; import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.Arrays; import java.util.Calendar; @@ -193,7 +194,7 @@ @Override public boolean getLargeIconForUrl( String url, int desiredSizePx, LargeIconCallback callback) { - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { int fallbackColor = colorMap.containsKey(url) ? colorMap.get(url) : DEFAULT_ICON_COLOR; callback.onLargeIconAvailable(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java index 4bf6f924..153d074 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/snippets/ArticleSnippetsTest.java
@@ -29,6 +29,7 @@ import org.chromium.base.Callback; import org.chromium.base.DiscardableReferencePool; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.UrlUtils; @@ -66,6 +67,7 @@ import org.chromium.chrome.test.util.browser.suggestions.DummySuggestionsEventReporter; import org.chromium.chrome.test.util.browser.suggestions.FakeSuggestionsSource; import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.net.NetworkChangeNotifier; import java.io.IOException; @@ -492,7 +494,7 @@ public void makeFaviconRequest( SnippetArticle suggestion, final Callback<Bitmap> faviconCallback) { // Run the callback asynchronously in case the caller made that assumption. - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { // Return an arbitrary drawable. faviconCallback.onResult(getBitmap(R.drawable.star_green)); }); @@ -502,7 +504,7 @@ public void makeLargeIconRequest(final String url, final int largeIconSizePx, final LargeIconBridge.LargeIconCallback callback) { // Run the callback asynchronously in case the caller made that assumption. - ThreadUtils.postOnUiThread(() -> { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> { // Return an arbitrary drawable. callback.onLargeIconAvailable( getBitmap(R.drawable.star_green), largeIconSizePx, true, IconType.INVALID);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/BrandColorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/BrandColorTest.java index 1b67a0b7..ed5a7f4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/BrandColorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/BrandColorTest.java
@@ -18,6 +18,7 @@ import org.chromium.base.ObserverList.RewindableIterator; import org.chromium.base.SysUtils; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; @@ -34,6 +35,7 @@ import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.DisableInTabbedMode; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.test.InterstitialPageDelegateAndroid; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; @@ -171,7 +173,7 @@ @Feature({"Omnibox"}) public void testBrandColorWithLoadStarted() throws InterruptedException { startMainActivityWithURL(getUrlWithBrandColor(BRAND_COLOR_1)); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { Tab tab = mActivityTestRule.getActivity().getActivityTab();
diff --git a/chrome/browser/android/webapk/webapk_post_share_target_navigator.cc b/chrome/browser/android/webapk/webapk_post_share_target_navigator.cc index eb51ca1..33ee5cf8 100644 --- a/chrome/browser/android/webapk/webapk_post_share_target_navigator.cc +++ b/chrome/browser/android/webapk/webapk_post_share_target_navigator.cc
@@ -4,12 +4,13 @@ #include "chrome/browser/android/webapk/webapk_post_share_target_navigator.h" -#include <sstream> - #include <jni.h> +#include <sstream> + #include "base/android/jni_array.h" #include "base/android/jni_string.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversion_utils.h" #include "content/public/browser/web_contents.h" #include "jni/WebApkPostShareTargetNavigator_jni.h"
diff --git a/chrome/browser/chrome_browser_main_browsertest.cc b/chrome/browser/chrome_browser_main_browsertest.cc index d72118d..75ad33a 100644 --- a/chrome/browser/chrome_browser_main_browsertest.cc +++ b/chrome/browser/chrome_browser_main_browsertest.cc
@@ -36,31 +36,6 @@ namespace { -// ChromeBrowserMainExtraParts is used to initialize the network state. -class ChromeBrowserMainExtraPartsNetFactoryInstaller - : public ChromeBrowserMainExtraParts { - public: - explicit ChromeBrowserMainExtraPartsNetFactoryInstaller( - content::NetworkConnectionChangeSimulator* network_change_simulator) - : network_change_simulator_(network_change_simulator) { - EXPECT_TRUE(network_change_simulator_); - } - - // ChromeBrowserMainExtraParts: - void PreEarlyInitialization() override {} - void ServiceManagerConnectionStarted( - content::ServiceManagerConnection* connection) override { - network_change_simulator_->SetConnectionType( - network::mojom::ConnectionType::CONNECTION_NONE); - } - - private: - content::NetworkConnectionChangeSimulator* network_change_simulator_ = - nullptr; - - DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsNetFactoryInstaller); -}; - class ChromeBrowserMainBrowserTest : public InProcessBrowserTest { public: ChromeBrowserMainBrowserTest() { @@ -87,17 +62,8 @@ static_cast<ChromeBrowserMainParts*>(browser_main_parts); ChromeBrowserMainPartsTestApi(chrome_browser_main_parts) .EnableVariationsServiceInit(); - network_change_simulator_ = - std::make_unique<content::NetworkConnectionChangeSimulator>(); - extra_parts_ = new ChromeBrowserMainExtraPartsNetFactoryInstaller( - network_change_simulator_.get()); - chrome_browser_main_parts->AddParts(extra_parts_); } - std::unique_ptr<content::NetworkConnectionChangeSimulator> - network_change_simulator_; - ChromeBrowserMainExtraPartsNetFactoryInstaller* extra_parts_ = nullptr; - private: base::test::ScopedFeatureList scoped_feature_list_; @@ -110,16 +76,28 @@ // instead of performing an actual request. IN_PROC_BROWSER_TEST_F(ChromeBrowserMainBrowserTest, VariationsServiceStartsRequestOnNetworkChange) { - const int initial_request_count = - g_browser_process->variations_service()->request_count(); - ASSERT_TRUE(extra_parts_); - network_change_simulator_->SetConnectionType( + variations::VariationsService* variations_service = + g_browser_process->variations_service(); + variations_service->CancelCurrentRequestForTesting(); + + content::NetworkConnectionChangeSimulator network_change_simulator; + network_change_simulator.SetConnectionType( + network::mojom::ConnectionType::CONNECTION_NONE); + const int initial_request_count = variations_service->request_count(); + + // The variations service will only send a request the first time the + // connection goes online, or after the 30min delay. Tell it that it hasn't + // sent a request yet to make sure the next time we go online a request will + // be sent. + variations_service->GetResourceRequestAllowedNotifierForTesting() + ->SetObserverRequestedForTesting(true); + + network_change_simulator.SetConnectionType( network::mojom::ConnectionType::CONNECTION_WIFI); // NotifyObserversOfNetworkChangeForTests uses PostTask, so run the loop until // idle to ensure VariationsService processes the network change. base::RunLoop().RunUntilIdle(); - const int final_request_count = - g_browser_process->variations_service()->request_count(); + const int final_request_count = variations_service->request_count(); EXPECT_EQ(initial_request_count + 1, final_request_count); }
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 9f87ae1a..f109b8a8 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -494,6 +494,8 @@ #include "chrome/browser/extensions/bookmark_app_navigation_throttle.h" #include "chrome/browser/extensions/chrome_content_browser_client_extensions_part.h" #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" +#include "chrome/browser/extensions/convert_web_app.h" +#include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/user_script_listener.h" #include "chrome/browser/media/cast_transport_host_filter.h" #include "chrome/browser/speech/extension_api/tts_engine_extension_api.h" @@ -3152,13 +3154,38 @@ web_prefs->embedded_media_experience_enabled = tab_android->ShouldEnableEmbeddedMediaExperience(); - web_prefs->web_app_scope = tab_android->GetWebappManifestScope(); - web_prefs->picture_in_picture_enabled = tab_android->IsPictureInPictureEnabled(); } #endif // defined(OS_ANDROID) + // web_app_scope value is platform specific. +#if defined(OS_ANDROID) + if (tab_android) + web_prefs->web_app_scope = tab_android->GetWebappManifestScope(); +#elif BUILDFLAG(ENABLE_EXTENSIONS) + { + const extensions::Extension* extension = nullptr; + Browser* browser = chrome::FindBrowserWithWebContents(contents); + if (base::FeatureList::IsEnabled(features::kDesktopPWAWindowing) && + browser && browser->hosted_app_controller() && + browser->hosted_app_controller()->created_for_installed_pwa()) { + // When a new window is created to host a PWA, this method will return + // the scope of the given PWA. It will stay the same for the PWA as + // scopes never change after the window was created. It is not + // guaranteed that this method will be called on every navigation but + // this is not required for things to work, we only need it to be called + // at the window creation time. + extension = extensions::util::GetInstalledPwaForUrl( + contents->GetBrowserContext(), contents->GetLastCommittedURL()); + } + + web_prefs->web_app_scope = + extension ? extensions::GetScopeURLFromBookmarkApp(extension) + : GURL(); + } +#endif + #if BUILDFLAG(ENABLE_EXTENSIONS) Browser* browser = chrome::FindBrowserWithWebContents(contents); if (browser && browser->hosted_app_controller() &&
diff --git a/chrome/browser/chromeos/accessibility/chromevox_panel.cc b/chrome/browser/chromeos/accessibility/chromevox_panel.cc index deadc8f..b2474a0 100644 --- a/chrome/browser/chromeos/accessibility/chromevox_panel.cc +++ b/chrome/browser/chromeos/accessibility/chromevox_panel.cc
@@ -7,6 +7,7 @@ #include "ash/public/interfaces/accessibility_controller.mojom.h" #include "ash/public/interfaces/constants.mojom.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/common/service_manager_connection.h" #include "extensions/common/constants.h" #include "services/service_manager/public/cpp/connector.h"
diff --git a/chrome/browser/chromeos/android_sms/fcm_connection_establisher.cc b/chrome/browser/chromeos/android_sms/fcm_connection_establisher.cc index ba560bef..5d68e47 100644 --- a/chrome/browser/chromeos/android_sms/fcm_connection_establisher.cc +++ b/chrome/browser/chromeos/android_sms/fcm_connection_establisher.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/metrics/histogram_macros.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" #include "chromeos/components/multidevice/logging/logging.h" @@ -41,10 +42,10 @@ FcmConnectionEstablisher::PendingServiceWorkerMessage:: PendingServiceWorkerMessage( GURL service_worker_scope, - std::string message_content, + MessageType message_type, content::ServiceWorkerContext* service_worker_context) : service_worker_scope(service_worker_scope), - message_content(message_content), + message_type(message_type), service_worker_context(service_worker_context) {} FcmConnectionEstablisher::InFlightMessage::InFlightMessage( @@ -65,7 +66,7 @@ base::BindOnce( &FcmConnectionEstablisher::SendMessageToServiceWorkerWithRetries, weak_ptr_factory_.GetWeakPtr(), url, - GetMessageForConnectionMode(connection_mode), + GetMessageTypeForConnectionMode(connection_mode), service_worker_context)); } @@ -76,18 +77,33 @@ FROM_HERE, {content::BrowserThread::IO}, base::BindOnce( &FcmConnectionEstablisher::SendMessageToServiceWorkerWithRetries, - weak_ptr_factory_.GetWeakPtr(), url, kStopFcmMessage, + weak_ptr_factory_.GetWeakPtr(), url, MessageType::kStop, service_worker_context)); } // static -std::string FcmConnectionEstablisher::GetMessageForConnectionMode( +FcmConnectionEstablisher::MessageType +FcmConnectionEstablisher::GetMessageTypeForConnectionMode( ConnectionMode connection_mode) { switch (connection_mode) { case ConnectionMode::kStartConnection: - return kStartFcmMessage; + return MessageType::kStart; case ConnectionMode::kResumeExistingConnection: + return MessageType::kResume; + } + NOTREACHED(); +} + +// static +std::string FcmConnectionEstablisher::GetMessageStringForType( + MessageType message_type) { + switch (message_type) { + case MessageType::kStart: + return kStartFcmMessage; + case MessageType::kResume: return kResumeFcmMessage; + case MessageType::kStop: + return kStopFcmMessage; } NOTREACHED(); return ""; @@ -95,11 +111,11 @@ void FcmConnectionEstablisher::SendMessageToServiceWorkerWithRetries( const GURL& url, - std::string message_string, + MessageType message_type, content::ServiceWorkerContext* service_worker_context) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - message_queue_.emplace(url, message_string, service_worker_context); + message_queue_.emplace(url, message_type, service_worker_context); ProcessMessageQueue(); } @@ -119,11 +135,11 @@ void FcmConnectionEstablisher::SendInFlightMessage() { const PendingServiceWorkerMessage& message = in_flight_message_->message; blink::TransferableMessage msg; - msg.owned_encoded_message = - blink::EncodeStringMessage(base::UTF8ToUTF16(message.message_content)); + msg.owned_encoded_message = blink::EncodeStringMessage( + base::UTF8ToUTF16(GetMessageStringForType(message.message_type))); msg.encoded_message = msg.owned_encoded_message; - PA_LOG(VERBOSE) << "Dispatching message " << message.message_content; + PA_LOG(VERBOSE) << "Dispatching message " << message.message_type; message.service_worker_context->StartServiceWorkerAndDispatchMessage( message.service_worker_scope, std::move(msg), base::BindOnce(&FcmConnectionEstablisher::OnMessageDispatchResult, @@ -133,12 +149,16 @@ void FcmConnectionEstablisher::OnMessageDispatchResult(bool status) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(in_flight_message_); - PA_LOG(VERBOSE) << "Service worker message returned status: " << status; + PA_LOG(VERBOSE) << "Service worker message returned status " << status + << " for message " + << in_flight_message_->message.message_type; if (!status && in_flight_message_->retry_count < kMaxRetryCount) { base::TimeDelta retry_delay = kRetryDelay * (1 << in_flight_message_->retry_count); in_flight_message_->retry_count++; + UMA_HISTOGRAM_ENUMERATION("AndroidSms.FcmMessageDispatchRetry", + in_flight_message_->message.message_type); PA_LOG(VERBOSE) << "Scheduling retry with delay " << retry_delay; retry_timer_->Start( FROM_HERE, retry_delay, @@ -147,15 +167,37 @@ return; } - if (in_flight_message_->retry_count >= kMaxRetryCount) { + if (status) { + UMA_HISTOGRAM_ENUMERATION("AndroidSms.FcmMessageDispatchSuccess", + in_flight_message_->message.message_type); + } else { + UMA_HISTOGRAM_ENUMERATION("AndroidSms.FcmMessageDispatchFailure", + in_flight_message_->message.message_type); PA_LOG(WARNING) << "Max retries attempted when dispatching message " - << in_flight_message_->message.message_content; + << in_flight_message_->message.message_type; } in_flight_message_.reset(); ProcessMessageQueue(); } +std::ostream& operator<<( + std::ostream& stream, + const FcmConnectionEstablisher::MessageType& message_type) { + switch (message_type) { + case FcmConnectionEstablisher::MessageType::kStart: + stream << "MessageType::kStart"; + break; + case FcmConnectionEstablisher::MessageType::kResume: + stream << "MessageType::kResume"; + break; + case FcmConnectionEstablisher::MessageType::kStop: + stream << "MessageType::kStop"; + break; + } + return stream; +} + } // namespace android_sms } // namespace chromeos
diff --git a/chrome/browser/chromeos/android_sms/fcm_connection_establisher.h b/chrome/browser/chromeos/android_sms/fcm_connection_establisher.h index 70905ee..926623a 100644 --- a/chrome/browser/chromeos/android_sms/fcm_connection_establisher.h +++ b/chrome/browser/chromeos/android_sms/fcm_connection_establisher.h
@@ -36,13 +36,24 @@ content::ServiceWorkerContext* service_worker_context) override; private: + // This enum is used for logging metrics. It should be kept in sync with + // AndroidSmsFcmMessageType in enums.xml + enum class MessageType { + kStart = 0, + kResume = 1, + kStop = 2, + kMaxValue = kStop, + }; + friend std::ostream& operator<<(std::ostream& stream, + const MessageType& message_type); + struct PendingServiceWorkerMessage { PendingServiceWorkerMessage( GURL service_worker_scope, - std::string message_content, + MessageType message_type, content::ServiceWorkerContext* service_worker_context); GURL service_worker_scope; - std::string message_content; + MessageType message_type; content::ServiceWorkerContext* service_worker_context; }; @@ -57,12 +68,14 @@ FRIEND_TEST_ALL_PREFIXES(FcmConnectionEstablisherTest, TestTearDownConnection); - static std::string GetMessageForConnectionMode( + static MessageType GetMessageTypeForConnectionMode( ConnectionMode connection_mode); + static std::string GetMessageStringForType(MessageType message_type); + void SendMessageToServiceWorkerWithRetries( const GURL& url, - std::string message_string, + MessageType message_type, content::ServiceWorkerContext* service_worker_context); void ProcessMessageQueue();
diff --git a/chrome/browser/chromeos/android_sms/fcm_connection_establisher_unittest.cc b/chrome/browser/chromeos/android_sms/fcm_connection_establisher_unittest.cc index bb382db..12c95b7 100644 --- a/chrome/browser/chromeos/android_sms/fcm_connection_establisher_unittest.cc +++ b/chrome/browser/chromeos/android_sms/fcm_connection_establisher_unittest.cc
@@ -8,6 +8,7 @@ #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/metrics/histogram_tester.h" #include "base/timer/mock_timer.h" #include "chrome/browser/chromeos/android_sms/android_sms_urls.h" #include "content/public/test/fake_service_worker_context.h" @@ -44,6 +45,7 @@ TEST_F(FcmConnectionEstablisherTest, TestEstablishConnection) { auto mock_retry_timer = std::make_unique<base::MockOneShotTimer>(); base::MockOneShotTimer* mock_retry_timer_ptr = mock_retry_timer.get(); + base::HistogramTester histogram_tester; content::FakeServiceWorkerContext fake_service_worker_context; FcmConnectionEstablisher fcm_connection_establisher( @@ -64,11 +66,15 @@ message_dispatch_calls[0]); // Return success to result callback and verify that no retries are attempted + // and success histogram is recorded. std::move(std::get<content::ServiceWorkerContext::ResultCallback>( message_dispatch_calls[0])) .Run(true /* status */); ASSERT_EQ(1u, message_dispatch_calls.size()); EXPECT_FALSE(mock_retry_timer_ptr->IsRunning()); + histogram_tester.ExpectBucketCount( + "AndroidSms.FcmMessageDispatchSuccess", + FcmConnectionEstablisher::MessageType::kStart, 1); // Verify that when multiple requests are sent only the first one is // dispatched while the others are queued. @@ -91,6 +97,10 @@ .Run(false /* status */); ASSERT_EQ(2u, message_dispatch_calls.size()); EXPECT_TRUE(mock_retry_timer_ptr->IsRunning()); + // Retry shouldn't count success. + histogram_tester.ExpectBucketCount( + "AndroidSms.FcmMessageDispatchSuccess", + FcmConnectionEstablisher::MessageType::kStart, 1); mock_retry_timer_ptr->Fire(); ASSERT_EQ(3u, message_dispatch_calls.size()); VerifyTransferrableMessage(FcmConnectionEstablisher::kStartFcmMessage, @@ -119,6 +129,11 @@ &fake_service_worker_context); base::RunLoop().RunUntilIdle(); + int last_retry_bucket_count = histogram_tester.GetBucketCount( + "AndroidSms.FcmMessageDispatchRetry", + static_cast<base::HistogramBase::Sample>( + FcmConnectionEstablisher::MessageType::kStart)); + int retry_count = 0; while (true) { ASSERT_EQ(5u + retry_count, message_dispatch_calls.size()); @@ -134,6 +149,13 @@ } EXPECT_EQ(FcmConnectionEstablisher::kMaxRetryCount, retry_count); + histogram_tester.ExpectBucketCount( + "AndroidSms.FcmMessageDispatchRetry", + FcmConnectionEstablisher::MessageType::kStart, + retry_count + last_retry_bucket_count); + histogram_tester.ExpectBucketCount( + "AndroidSms.FcmMessageDispatchFailure", + FcmConnectionEstablisher::MessageType::kStart, 1); } TEST_F(FcmConnectionEstablisherTest, TestTearDownConnection) {
diff --git a/chrome/browser/chromeos/dbus/chrome_features_service_provider.h b/chrome/browser/chromeos/dbus/chrome_features_service_provider.h index 5b5acd1..54931c3 100644 --- a/chrome/browser/chromeos/dbus/chrome_features_service_provider.h +++ b/chrome/browser/chromeos/dbus/chrome_features_service_provider.h
@@ -25,16 +25,24 @@ // --dest=org.chromium.ChromeFeaturesService // /org/chromium/ChromeFeaturesService // org.chromium.ChromeFeaturesServiceInterface.IsCrostiniEnabled +// string:"|user id hash|" // -// % (returns true if Crostini is enabled, otherwise returns false) +// % (If |user id hash| is set correctly, returns true if Crostini is enabled +// for the user identified by the hash, and false otherwise) // // IsPluginVmEnabled: // % dbus-send --system --type=method_call --print-reply // --dest=org.chromium.ChromeFeaturesService // /org/chromium/ChromeFeaturesService // org.chromium.ChromeFeaturesServiceInterface.IsPluginVmEnabled +// string:"|user id hash|" // -// % (returns true if Plugin VMs are enabled, otherwise returns false) +// % (If |user id hash| is set correctly, returns true if Plugin VMs are enabled +// for the user identified by the hash, and false otherwise) +// +// Both methods will return an error if the user ID hash parameter is missing. +// Passing an empty string as the user ID hash to either method will +// result in the active user profile being used. class ChromeFeaturesServiceProvider : public CrosDBusService::ServiceProviderInterface {
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc index 9e8674e..c876501 100644 --- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc +++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -1271,6 +1271,13 @@ void AutotestPrivateSendAssistantTextQueryFunction::OnInteractionFinished( AssistantInteractionResolution resolution) { + // Only return a result to the caller and stop the timer when |result_| + // is not empty to avoid an early return before the entire interaction is + // completed. This happens when sending queries to modify device settings, + // e.g. "turn on bluetooth", which results in two rounds of interaction. + if (result_->empty()) + return; + if (resolution != AssistantInteractionResolution::kNormal) { Respond(Error("Interaction ends abnormally.")); timeout_timer_.AbandonAndStop();
diff --git a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc index 9318b44..3603371 100644 --- a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc +++ b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
@@ -28,7 +28,6 @@ #include "chrome/browser/extensions/chrome_extension_test_notification_observer.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.h" @@ -52,7 +51,6 @@ #include "extensions/browser/process_manager.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" -#include "google_apis/gaia/oauth2_token_service_delegate.h" #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_store.h" #include "net/test/embedded_test_server/http_request.h" @@ -60,6 +58,7 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "services/identity/public/cpp/identity_manager.h" +#include "services/identity/public/cpp/identity_test_utils.h" using net::test_server::BasicHttpResponse; using net::test_server::HttpRequest; @@ -740,8 +739,9 @@ ASSERT_NE(OAuth2LoginManager::SESSION_RESTORE_DONE, login_manager->state()); // Generate an auth error. - ProfileOAuth2TokenServiceFactory::GetForProfile(profile())->UpdateCredentials( - kTestEmail, OAuth2TokenServiceDelegate::kInvalidRefreshToken); + identity::SetInvalidRefreshTokenForAccount( + IdentityManagerFactory::GetInstance()->GetForProfile(profile()), + kTestEmail); // Let go /ListAccounts request. list_accounts_request_deferer.UnblockRequest();
diff --git a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc index ac65679..a23e5f4 100644 --- a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
@@ -2707,6 +2707,8 @@ TEST_F(ConsumerDeviceStatusCollectorTimeLimitEnabledTest, ActivityKeptInPref) { EXPECT_TRUE( profile_pref_service_.GetDictionary(prefs::kUserActivityTimes)->empty()); + base::Time initial_time = base::Time::Now() + kHour; + status_collector_->SetBaselineTime(initial_time); DeviceStateTransitions test_states[] = { DeviceStateTransitions::kEnterSessionActive, @@ -2732,6 +2734,7 @@ base::BindRepeating(&GetEmptyCPUTempInfo), base::BindRepeating(&GetEmptyAndroidStatus), base::BindRepeating(&GetEmptyTpmStatus)); + status_collector_->SetBaselineTime(initial_time); SimulateStateChanges(test_states, sizeof(test_states) / sizeof(DeviceStateTransitions));
diff --git a/chrome/browser/extensions/api/messaging/native_messaging_policy_handler.cc b/chrome/browser/extensions/api/messaging/native_messaging_policy_handler.cc index 207bae8..4dbc135 100644 --- a/chrome/browser/extensions/api/messaging/native_messaging_policy_handler.cc +++ b/chrome/browser/extensions/api/messaging/native_messaging_policy_handler.cc
@@ -31,7 +31,9 @@ void NativeMessagingHostListPolicyHandler::ApplyList( std::unique_ptr<base::ListValue> filtered_list, PrefValueMap* prefs) { - prefs->SetValue(pref_path_, std::move(filtered_list)); + DCHECK(filtered_list); + prefs->SetValue(pref_path_, + base::Value::FromUniquePtrValue(std::move(filtered_list))); } } // namespace extensions
diff --git a/chrome/browser/extensions/extension_storage_monitor_browsertest.cc b/chrome/browser/extensions/extension_storage_monitor_browsertest.cc index fdd1eff..8aebcca 100644 --- a/chrome/browser/extensions/extension_storage_monitor_browsertest.cc +++ b/chrome/browser/extensions/extension_storage_monitor_browsertest.cc
@@ -395,9 +395,7 @@ // Exercises the case where two hosted apps are same-origin but have non- // overlapping extents. Disabling one should not suppress storage monitoring for // the other. -// Disabled for flakiness. crbug.com/799022 -IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, - DISABLED_TwoHostedAppsInSameOrigin) { +IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, TwoHostedAppsInSameOrigin) { ASSERT_TRUE(embedded_test_server()->Start()); GURL url1 = embedded_test_server()->GetURL(
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 8ee3295..b57c0ec 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1300,7 +1300,7 @@ const char kNostatePrefetchName[] = "NoState Prefetch"; const char kNostatePrefetchDescription[] = - R"*(If enabled, pre-downloads resources to improve page load speed.)*"; + "If enabled, pre-downloads resources to improve page load speed."; const char kNotificationIndicatorName[] = "Notification Indicators"; const char kNotificationIndicatorDescription[] = @@ -3509,12 +3509,12 @@ // Force UI Mode const char kUiModeName[] = "Force Ui Mode"; const char kUiModeDescription[] = - R"*(This flag can be used to force a certain mode on to a chromebook, )*" - R"*(despite its current orientation. "Tablet" means that the )*" - R"*(chromebook will act as if it were in tablet mode. "Clamshell" )*" - R"*(means that the chromebook will act as if it were in clamshell )*" - R"*(mode . "Auto" means that the chromebook will alternate between )*" - R"*(the two, based on its orientation.)*"; + "This flag can be used to force a certain mode on to a chromebook, " + "despite its current orientation. \"Tablet\" means that the " + "chromebook will act as if it were in tablet mode. \"Clamshell\" " + "means that the chromebook will act as if it were in clamshell " + "mode. \"Auto\" means that the chromebook will alternate between " + "the two, based on its orientation."; const char kUiModeTablet[] = "Tablet"; const char kUiModeClamshell[] = "Clamshell"; const char kUiModeAuto[] = "Auto (default)";
diff --git a/chrome/browser/media/unified_autoplay_browsertest.cc b/chrome/browser/media/unified_autoplay_browsertest.cc index 6877beb..78c22c4d 100644 --- a/chrome/browser/media/unified_autoplay_browsertest.cc +++ b/chrome/browser/media/unified_autoplay_browsertest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/test/scoped_feature_list.h" +#include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" @@ -11,7 +12,9 @@ #include "components/content_settings/core/browser/host_content_settings_map.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/common/web_preferences.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_frame_navigation_observer.h" #include "content/public/test/test_navigation_observer.h" @@ -27,6 +30,27 @@ static constexpr char const kTestPagePath[] = "/media/unified_autoplay.html"; +class ChromeContentBrowserClientOverrideWebAppScope + : public ChromeContentBrowserClient { + public: + ChromeContentBrowserClientOverrideWebAppScope() = default; + ~ChromeContentBrowserClientOverrideWebAppScope() override = default; + + void OverrideWebkitPrefs(content::RenderViewHost* rvh, + content::WebPreferences* web_prefs) override { + ChromeContentBrowserClient::OverrideWebkitPrefs(rvh, web_prefs); + + web_prefs->web_app_scope = web_app_scope_; + } + + void set_web_app_scope(const GURL& web_app_scope) { + web_app_scope_ = web_app_scope; + } + + private: + GURL web_app_scope_; +}; + } // anonymous namespace // Integration tests for the unified autoplay policy that require the //chrome @@ -325,6 +349,69 @@ EXPECT_FALSE(AttemptPlay(GetWebContents())); } +IN_PROC_BROWSER_TEST_F(UnifiedAutoplayBrowserTest, + MatchingWebAppScopeAllowsAutoplay_Origin) { + GURL kTestPageUrl( + embedded_test_server()->GetURL("example.com", kTestPagePath)); + + ChromeContentBrowserClientOverrideWebAppScope browser_client; + browser_client.set_web_app_scope(kTestPageUrl.GetOrigin()); + + content::ContentBrowserClient* old_browser_client = + content::SetBrowserClientForTesting(&browser_client); + + GetWebContents()->GetRenderViewHost()->OnWebkitPreferencesChanged(); + + ui_test_utils::NavigateToURL(browser(), kTestPageUrl); + content::WaitForLoadStop(GetWebContents()); + + EXPECT_TRUE(AttemptPlay(GetWebContents())); + + content::SetBrowserClientForTesting(old_browser_client); +} + +IN_PROC_BROWSER_TEST_F(UnifiedAutoplayBrowserTest, + MatchingWebAppScopeAllowsAutoplay_Path) { + GURL kTestPageUrl( + embedded_test_server()->GetURL("example.com", kTestPagePath)); + + ChromeContentBrowserClientOverrideWebAppScope browser_client; + browser_client.set_web_app_scope(kTestPageUrl.GetWithoutFilename()); + + content::ContentBrowserClient* old_browser_client = + content::SetBrowserClientForTesting(&browser_client); + + GetWebContents()->GetRenderViewHost()->OnWebkitPreferencesChanged(); + + ui_test_utils::NavigateToURL(browser(), kTestPageUrl); + content::WaitForLoadStop(GetWebContents()); + + EXPECT_TRUE(AttemptPlay(GetWebContents())); + + content::SetBrowserClientForTesting(old_browser_client); +} + +IN_PROC_BROWSER_TEST_F(UnifiedAutoplayBrowserTest, + NotMatchingWebAppScopeDoesNotAllowAutoplay) { + GURL kTestPageUrl( + embedded_test_server()->GetURL("example.com", kTestPagePath)); + + ChromeContentBrowserClientOverrideWebAppScope browser_client; + browser_client.set_web_app_scope(GURL("http://www.foobar.com")); + + content::ContentBrowserClient* old_browser_client = + content::SetBrowserClientForTesting(&browser_client); + + GetWebContents()->GetRenderViewHost()->OnWebkitPreferencesChanged(); + + ui_test_utils::NavigateToURL(browser(), kTestPageUrl); + content::WaitForLoadStop(GetWebContents()); + + EXPECT_FALSE(AttemptPlay(GetWebContents())); + + content::SetBrowserClientForTesting(old_browser_client); +} + // Integration tests for the new unified autoplay sound settings UI. class UnifiedAutoplaySettingBrowserTest : public UnifiedAutoplayBrowserTest {
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list_unittest.cc b/chrome/browser/media/webrtc/native_desktop_media_list_unittest.cc index e54a139..ba6720d81 100644 --- a/chrome/browser/media/webrtc/native_desktop_media_list_unittest.cc +++ b/chrome/browser/media/webrtc/native_desktop_media_list_unittest.cc
@@ -68,7 +68,6 @@ DCHECK(callback_); std::unique_ptr<webrtc::DesktopFrame> frame( new webrtc::BasicDesktopFrame(webrtc::DesktopSize(10, 10))); - memset(frame->data(), 0, frame->stride() * frame->size().height()); callback_->OnCaptureResult(webrtc::DesktopCapturer::Result::SUCCESS, std::move(frame)); }
diff --git a/chrome/browser/password_manager/password_store_signin_notifier_impl.h b/chrome/browser/password_manager/password_store_signin_notifier_impl.h index 5d54b38..7b32a1d 100644 --- a/chrome/browser/password_manager/password_store_signin_notifier_impl.h +++ b/chrome/browser/password_manager/password_store_signin_notifier_impl.h
@@ -27,10 +27,8 @@ void SubscribeToSigninEvents(PasswordStore* store) override; void UnsubscribeFromSigninEvents() override; - // SigninManagerBase::Observer implementations. - void OnPrimaryAccountCleared(const AccountInfo& account_info) override; - // IdentityManager::Observer implementations. + void OnPrimaryAccountCleared(const AccountInfo& account_info) override; void OnAccountRemovedWithInfo(const AccountInfo& info) override; private:
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc index f8aa3b9..7a08fdf6 100644 --- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc +++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -9,6 +9,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" +#include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/devtools/devtools_window_testing.h" #include "chrome/browser/extensions/browsertest_util.h" #include "chrome/browser/extensions/extension_browsertest.h" @@ -26,8 +27,10 @@ #include "content/public/browser/notification_service.h" #include "content/public/browser/overlay_window.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" +#include "content/public/common/web_preferences.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" #include "media/base/media_switches.h" @@ -2024,6 +2027,31 @@ EXPECT_TRUE(in_picture_in_picture); } +namespace { + +class ChromeContentBrowserClientOverrideWebAppScope + : public ChromeContentBrowserClient { + public: + ChromeContentBrowserClientOverrideWebAppScope() = default; + ~ChromeContentBrowserClientOverrideWebAppScope() override = default; + + void OverrideWebkitPrefs(content::RenderViewHost* rvh, + content::WebPreferences* web_prefs) override { + ChromeContentBrowserClient::OverrideWebkitPrefs(rvh, web_prefs); + + web_prefs->web_app_scope = web_app_scope_; + } + + void set_web_app_scope(const GURL& web_app_scope) { + web_app_scope_ = web_app_scope; + } + + private: + GURL web_app_scope_; +}; + +} // namespace + class WebAppPictureInPictureWindowControllerBrowserTest : public extensions::ExtensionBrowserTest { public: @@ -2060,6 +2088,20 @@ web_contents_ = app_browser->tab_strip_model()->GetActiveWebContents(); EXPECT_TRUE(content::WaitForLoadStop(web_contents_)); ASSERT_NE(nullptr, web_contents_); + + SetWebAppScope(app_url.GetOrigin()); + } + + void SetWebAppScope(const GURL web_app_scope) { + ChromeContentBrowserClientOverrideWebAppScope browser_client_; + browser_client_.set_web_app_scope(web_app_scope); + + content::ContentBrowserClient* original_browser_client_ = + content::SetBrowserClientForTesting(&browser_client_); + + web_contents_->GetRenderViewHost()->OnWebkitPreferencesChanged(); + + content::SetBrowserClientForTesting(original_browser_client_); } content::WebContents* web_contents() { return web_contents_; } @@ -2098,6 +2140,34 @@ } // Show pwa page and check that Auto Picture-in-Picture is not triggered if +// document is not inside the scope specified in the Web App Manifest. +IN_PROC_BROWSER_TEST_F( + WebAppPictureInPictureWindowControllerBrowserTest, + AutoPictureInPictureNotTriggeredIfDocumentNotInWebAppScope) { + InstallAndLaunchPWA(); + SetWebAppScope(GURL("http://www.foobar.com")); + bool result = false; + ASSERT_TRUE(content::ExecuteScriptAndExtractBool(web_contents(), + "playVideo();", &result)); + ASSERT_TRUE(result); + ASSERT_TRUE(content::ExecuteScript(web_contents(), + "video.autoPictureInPicture = true;")); + + // Hide page and check that the video did not entered + // Picture-in-Picture automatically. + web_contents()->WasHidden(); + base::string16 expected_title = base::ASCIIToUTF16("hidden"); + EXPECT_EQ( + expected_title, + content::TitleWatcher(web_contents(), expected_title).WaitAndGetTitle()); + + bool in_picture_in_picture = false; + ASSERT_TRUE(ExecuteScriptAndExtractBool( + web_contents(), "isInPictureInPicture();", &in_picture_in_picture)); + EXPECT_FALSE(in_picture_in_picture); +} + +// Show pwa page and check that Auto Picture-in-Picture is not triggered if // video is not playing. IN_PROC_BROWSER_TEST_F(WebAppPictureInPictureWindowControllerBrowserTest, AutoPictureInPictureNotTriggeredIfVideoNotPlaying) {
diff --git a/chrome/browser/resources/local_ntp/doodles.js b/chrome/browser/resources/local_ntp/doodles.js index f75b650..9708c8a 100644 --- a/chrome/browser/resources/local_ntp/doodles.js +++ b/chrome/browser/resources/local_ntp/doodles.js
@@ -557,6 +557,7 @@ case doodles.LOGO_TYPE.INTERACTIVE: logoDoodleIframe.title = doodles.targetDoodle.metadata.altText; logoDoodleIframe.src = doodles.targetDoodle.metadata.fullPageUrl; + logoDoodleIframe.allow = 'autoplay'; document.body.style.setProperty( '--logo-iframe-width', doodles.targetDoodle.metadata.iframeWidthPx + 'px');
diff --git a/chrome/browser/resources/print_preview/data/destination_match.js b/chrome/browser/resources/print_preview/data/destination_match.js index e30339c..9e3e930 100644 --- a/chrome/browser/resources/print_preview/data/destination_match.js +++ b/chrome/browser/resources/print_preview/data/destination_match.js
@@ -8,8 +8,7 @@ * Converts DestinationOrigin to PrinterType. * @param {!print_preview.DestinationOrigin} origin The printer's * destination origin. - * return {?print_preview.PrinterType} The corresponding PrinterType. - * Returns null if no match is found. + * return {!print_preview.PrinterType} The corresponding PrinterType. */ const originToType = function(origin) { if (origin === print_preview.DestinationOrigin.LOCAL || @@ -22,7 +21,8 @@ if (origin === print_preview.DestinationOrigin.EXTENSION) { return print_preview.PrinterType.EXTENSION_PRINTER; } - return null; + assert(print_preview.CloudOrigins.includes(origin)); + return print_preview.PrinterType.CLOUD_PRINTER; }; class DestinationMatch { @@ -107,12 +107,11 @@ } /** - * @return {!Set<?print_preview.PrinterType>} The printer types that - * correspond to this destination match. A null element in the set - * indicates the match may represent a Cloud destination. + * @return {!Set<!print_preview.PrinterType>} The printer types that + * correspond to this destination match. */ getTypes() { - return new Set(this.origins_.map(origin => originToType(origin))); + return new Set(this.origins_.map(originToType)); } }
diff --git a/chrome/browser/resources/print_preview/data/destination_store.js b/chrome/browser/resources/print_preview/data/destination_store.js index bc5c9814..66c3e9e 100644 --- a/chrome/browser/resources/print_preview/data/destination_store.js +++ b/chrome/browser/resources/print_preview/data/destination_store.js
@@ -372,64 +372,59 @@ return; } - const serializedDestination = { - id: '', - origin: this.platformOrigin_, + let startedAutoSelect = false; + let selected = false; + // Run through the destinations forward. As soon as we find a + // destination, don't select any future destinations, just fetch their + // capabilities in case the user switches to them later. + for (const destination of recentDestinations) { + const candidate = this.destinationMap_.get( + print_preview.createRecentDestinationKey(destination)); + const shouldSelectDestination = + !this.useSystemDefaultAsDefault_ && !selected && !startedAutoSelect; + if (candidate != undefined) { + // Destination is already in the store. Select it, if we haven't + // started selecting a destination already. + if (shouldSelectDestination) { + this.selectDestination(candidate); + selected = true; + } + } else { + // Pre-fetch the destination and start auto select if needed. + const startedFetch = this.fetchPreselectedDestination_( + destination, shouldSelectDestination); + startedAutoSelect = + startedAutoSelect || (startedFetch && shouldSelectDestination); + } + } + + if ((selected || startedAutoSelect) && !this.useSystemDefaultAsDefault_) { + // Return early since we already selected a destination. + return; + } + + // Try the system default + const serializedSystemDefault = { + id: this.systemDefaultDestinationId_, + origin: this.systemDefaultDestinationId_ == + print_preview.Destination.GooglePromotedId.SAVE_AS_PDF ? + print_preview.DestinationOrigin.LOCAL : + this.platformOrigin_, account: '', capabilities: null, displayName: '', extensionId: '', extensionName: '', }; - let foundDestination = false; - // Run through the destinations forward. As soon as we find a - // destination, don't select any future destinations, just mark - // them recent. Otherwise, there is a race condition between selecting - // destinations/updating the print ticket and this selecting a new - // destination that causes random print preview errors. - for (const destination of recentDestinations) { - const candidate = this.destinationMap_.get( - print_preview.createRecentDestinationKey(destination)); - if (candidate != undefined) { - if (!foundDestination && !this.useSystemDefaultAsDefault_) { - this.selectDestination(candidate); - } - foundDestination = true; - } else { - // Only automatically select the destination if we are not using the - // system default and we have not already found a destination to - // select. - const autoSelect = - !foundDestination && !this.useSystemDefaultAsDefault_; - const foundNewDestination = - this.fetchPreselectedDestination_(destination, autoSelect); - foundDestination = foundDestination || foundNewDestination; - } - } - - if (foundDestination && !this.useSystemDefaultAsDefault_) { - this.startAutoSelectTimeout_(); - return; - } - - // Try the system default - serializedDestination.id = this.systemDefaultDestinationId_; - serializedDestination.origin = serializedDestination.id == - print_preview.Destination.GooglePromotedId.SAVE_AS_PDF ? - print_preview.DestinationOrigin.LOCAL : - this.platformOrigin_; - serializedDestination.account = ''; const systemDefaultCandidate = this.destinationMap_.get( - print_preview.createRecentDestinationKey(serializedDestination)); + print_preview.createRecentDestinationKey(serializedSystemDefault)); if (systemDefaultCandidate != undefined) { this.selectDestination(systemDefaultCandidate); - this.startAutoSelectTimeout_(); return; } if (this.fetchPreselectedDestination_( - serializedDestination, true /* autoSelect */)) { - this.startAutoSelectTimeout_(); + serializedSystemDefault, true /* autoSelect */)) { return; } @@ -461,57 +456,64 @@ this.createExactDestinationMatch_(origin, id); } + let error = false; const type = print_preview.originToType(origin); - if (type == print_preview.PrinterType.LOCAL_PRINTER) { - this.nativeLayer_.getPrinterCapabilities(id, type).then( - this.onCapabilitiesSet_.bind(this, origin, id), - this.onGetCapabilitiesFail_.bind(this, origin, id)); - return true; + switch (type) { + case print_preview.PrinterType.LOCAL_PRINTER: + this.nativeLayer_.getPrinterCapabilities(id, type).then( + this.onCapabilitiesSet_.bind(this, origin, id), + this.onGetCapabilitiesFail_.bind(this, origin, id)); + break; + case print_preview.PrinterType.PRIVET_PRINTER: + case print_preview.PrinterType.EXTENSION_PRINTER: + // TODO(noamsml): Resolve a specific printer instead of listing all + // privet or extension printers in this case. + this.startLoadDestinations_(type); + + if (autoSelect) { + // Create a fake selectedDestination_ that is not actually in the + // destination store. When the real destination is created, this + // destination will be overwritten. + const params = + (origin === print_preview.DestinationOrigin.PRIVET) ? {} : { + description: '', + extensionId: serializedDestination.extensionId, + extensionName: serializedDestination.extensionName, + provisionalType: print_preview.DestinationProvisionalType.NONE + }; + this.selectedDestination_ = new print_preview.Destination( + id, print_preview.DestinationType.LOCAL, origin, + serializedDestination.displayName, + print_preview.DestinationConnectionStatus.ONLINE, params); + + if (serializedDestination.capabilities) { + this.selectedDestination_.capabilities = + serializedDestination.capabilities; + this.dispatchEvent(new CustomEvent( + DestinationStore.EventType + .SELECTED_DESTINATION_CAPABILITIES_READY)); + } + } + break; + case print_preview.PrinterType.CLOUD_PRINTER: + if (this.cloudPrintInterface_) { + this.inFlightCloudPrintRequests_.add(key); + this.cloudPrintInterface_.printer( + id, origin, serializedDestination.account); + } else { + // No cloud print interface. + error = true; + } + break; + default: + // Unknown type. + error = true; } - if (this.cloudPrintInterface_ && - print_preview.CloudOrigins.includes(origin)) { - this.inFlightCloudPrintRequests_.add(key); - this.cloudPrintInterface_.printer( - id, origin, serializedDestination.account); - return true; + if (!error && autoSelect) { + this.startAutoSelectTimeout_(); } - - if (origin == print_preview.DestinationOrigin.PRIVET || - origin == print_preview.DestinationOrigin.EXTENSION) { - // TODO(noamsml): Resolve a specific printer instead of listing all - // privet or extension printers in this case. - this.startLoadDestinations_(type); - - if (!autoSelect) { - return true; - } - - // Create a fake selectedDestination_ that is not actually in the - // destination store. When the real destination is created, this - // destination will be overwritten. - const params = - (origin === print_preview.DestinationOrigin.PRIVET) ? {} : { - description: '', - extensionId: serializedDestination.extensionId, - extensionName: serializedDestination.extensionName, - provisionalType: print_preview.DestinationProvisionalType.NONE - }; - this.selectedDestination_ = new print_preview.Destination( - id, print_preview.DestinationType.LOCAL, origin, - serializedDestination.displayName, - print_preview.DestinationConnectionStatus.ONLINE, params); - - if (serializedDestination.capabilities) { - this.selectedDestination_.capabilities = - serializedDestination.capabilities; - this.dispatchEvent( - new CustomEvent(DestinationStore.EventType - .SELECTED_DESTINATION_CAPABILITIES_READY)); - } - return true; - } - return false; + return !error; } /** @@ -523,7 +525,8 @@ this.autoSelectMatchingDestination_ = destinationMatch; const types = destinationMatch.getTypes(); types.forEach(type => { - if (type != null) { // Local, extension, or privet printer + if (type != print_preview.PrinterType.CLOUD_PRINTER) { + // Local, extension, or privet printer this.startLoadDestinations_(type); } else if (print_preview.CloudOrigins.some(origin => { return destinationMatch.matchOrigin(origin); @@ -669,8 +672,8 @@ */ selectDestination(destination) { this.autoSelectMatchingDestination_ = null; - // When auto select expires, DESTINATION_SELECT event has to be dispatched - // anyway (see isAutoSelectDestinationInProgress() logic). + // Clear the timeout. Otherwise, when it expires, we will fall back to the + // default destination. if (this.autoSelectTimeout_) { clearTimeout(this.autoSelectTimeout_); this.autoSelectTimeout_ = null; @@ -709,7 +712,7 @@ // known yet. if (destination.capabilities == null) { const type = print_preview.originToType(destination.origin); - if (type !== null) { + if (type !== print_preview.PrinterType.CLOUD_PRINTER) { this.nativeLayer_.getPrinterCapabilities(destination.id, type) .then( (caps) => this.onCapabilitiesSet_( @@ -1146,13 +1149,10 @@ this.inFlightCloudPrintRequests_.clear(); this.selectDestination(null); this.loadedCloudOrigins_.clear(); - for (const printerType of Object.values(print_preview.PrinterType)) { - if (printerType !== print_preview.PrinterType.PDF_PRINTER) { - this.destinationSearchStatus_.set( - printerType, - print_preview.DestinationStorePrinterSearchStatus.START); - } - } + this.destinationSearchStatus_.forEach((status, type) => { + this.destinationSearchStatus_.set( + type, print_preview.DestinationStorePrinterSearchStatus.START); + }); this.startAutoSelectTimeout_(); this.dispatchEvent( new CustomEvent(DestinationStore.EventType.DESTINATIONS_RESET));
diff --git a/chrome/browser/resources/settings/controls/settings_slider.html b/chrome/browser/resources/settings/controls/settings_slider.html index 872792b..15257fa0 100644 --- a/chrome/browser/resources/settings/controls/settings_slider.html +++ b/chrome/browser/resources/settings/controls/settings_slider.html
@@ -26,7 +26,7 @@ display: flex; flex-direction: column; margin: 8px 0; - min-width: 200px; + min-width: var(--cr-text-element-min-width); } #labels {
diff --git a/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html b/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html index a25cf48..bdeecaf6 100644 --- a/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html +++ b/chrome/browser/resources/settings/google_assistant_page/google_assistant_page.html
@@ -14,7 +14,11 @@ <dom-module id="settings-google-assistant-page"> <template> - <style include="settings-shared md-select"></style> + <style include="settings-shared md-select"> + .text-area { + margin-inline-end: 24px; + } + </style> <settings-toggle-button id="googleAssistantEnable" class="first primary-toggle" pref="{{prefs.settings.voice_interaction.enabled}}"
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index 8c36199..070889d 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -30,6 +30,7 @@ #include "chrome/browser/sync/glue/theme_data_type_controller.h" #include "chrome/browser/sync/model_type_store_service_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" +#include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h" #include "chrome/browser/sync/session_sync_service_factory.h" #include "chrome/browser/sync/user_event_service_factory.h" #include "chrome/browser/themes/theme_service.h" @@ -63,10 +64,12 @@ #include "components/password_manager/core/browser/sync/password_model_worker.h" #include "components/search_engines/search_engine_data_type_controller.h" #include "components/search_engines/search_engine_model_type_controller.h" +#include "components/send_tab_to_self/send_tab_to_self_service.h" #include "components/spellcheck/spellcheck_buildflags.h" #include "components/sync/base/pref_names.h" #include "components/sync/base/report_unrecoverable_error.h" #include "components/sync/driver/async_directory_type_controller.h" +#include "components/sync/driver/model_type_controller.h" #include "components/sync/driver/sync_api_component_factory.h" #include "components/sync/driver/sync_driver_switches.h" #include "components/sync/driver/sync_util.h" @@ -75,6 +78,7 @@ #include "components/sync/engine/sequenced_model_worker.h" #include "components/sync/engine/ui_model_worker.h" #include "components/sync/model/model_type_store_service.h" +#include "components/sync/model_impl/forwarding_model_type_controller_delegate.h" #include "components/sync/user_events/user_event_service.h" #include "components/sync_bookmarks/bookmark_sync_service.h" #include "components/sync_preferences/pref_service_syncable.h" @@ -454,6 +458,16 @@ } #endif // defined(OS_CHROMEOS) + if (!disabled_types.Has(syncer::SEND_TAB_TO_SELF) && + base::FeatureList::IsEnabled(switches::kSyncSendTabToSelf)) { + controllers.push_back(std::make_unique<syncer::ModelTypeController>( + syncer::SEND_TAB_TO_SELF, + std::make_unique<syncer::ForwardingModelTypeControllerDelegate>( + SendTabToSelfSyncServiceFactory::GetForProfile(profile_) + ->GetControllerDelegate() + .get()))); + } + return controllers; } @@ -620,6 +634,7 @@ case syncer::AUTOFILL_WALLET_METADATA: case syncer::BOOKMARKS: case syncer::DEVICE_INFO: + case syncer::SEND_TAB_TO_SELF: case syncer::SESSIONS: case syncer::TYPED_URLS: NOTREACHED();
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc index 6b3eff2..ab3c7ee 100644 --- a/chrome/browser/sync/profile_sync_service_factory.cc +++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -35,6 +35,7 @@ #include "chrome/browser/sync/chrome_sync_client.h" #include "chrome/browser/sync/device_info_sync_service_factory.h" #include "chrome/browser/sync/model_type_store_service_factory.h" +#include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h" #include "chrome/browser/sync/session_sync_service_factory.h" #include "chrome/browser/sync/user_event_service_factory.h" #include "chrome/browser/themes/theme_service_factory.h" @@ -152,6 +153,7 @@ DependsOn(invalidation::ProfileInvalidationProviderFactory::GetInstance()); DependsOn(ModelTypeStoreServiceFactory::GetInstance()); DependsOn(PasswordStoreFactory::GetInstance()); + DependsOn(SendTabToSelfSyncServiceFactory::GetInstance()); DependsOn(SpellcheckServiceFactory::GetInstance()); #if BUILDFLAG(ENABLE_SUPERVISED_USERS) DependsOn(SupervisedUserSettingsServiceFactory::GetInstance());
diff --git a/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc b/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc index c3f1f1f..f74fb3a 100644 --- a/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc +++ b/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc
@@ -8,10 +8,11 @@ #include "base/memory/singleton.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/chrome_device_id_helper.h" +#include "chrome/browser/sync/device_info_sync_service_factory.h" #include "chrome/common/channel_info.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/send_tab_to_self/send_tab_to_self_service.h" -#include "components/sync/device_info/local_device_info_provider_impl.h" +#include "components/sync/device_info/device_info_sync_service.h" #include "ui/base/device_form_factor.h" // static @@ -30,7 +31,9 @@ SendTabToSelfSyncServiceFactory::SendTabToSelfSyncServiceFactory() : BrowserContextKeyedServiceFactory( "SendTabToSelfSyncService", - BrowserContextDependencyManager::GetInstance()) {} + BrowserContextDependencyManager::GetInstance()) { + DependsOn(DeviceInfoSyncServiceFactory::GetInstance()); +} SendTabToSelfSyncServiceFactory::~SendTabToSelfSyncServiceFactory() {} @@ -38,19 +41,12 @@ content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); - syncer::LocalDeviceInfoProviderImpl::SigninScopedDeviceIdCallback - signin_scoped_device_id_callback = - base::BindRepeating(&GetSigninScopedDeviceIdForProfile, profile); - - std::unique_ptr<syncer::LocalDeviceInfoProviderImpl> - local_device_info_provider = - std::make_unique<syncer::LocalDeviceInfoProviderImpl>( - chrome::GetChannel(), chrome::GetVersionString(), - ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET, - signin_scoped_device_id_callback); + syncer::LocalDeviceInfoProvider* local_device_info_provider = + DeviceInfoSyncServiceFactory::GetForProfile(profile) + ->GetLocalDeviceInfoProvider(); // TODO(jeffreycohen): use KeyedService to provide a DeviceInfo ptr. return new send_tab_to_self::SendTabToSelfService(chrome::GetChannel(), - nullptr); + local_device_info_provider); }
diff --git a/chrome/browser/sync/test/integration/send_tab_to_self_helper.cc b/chrome/browser/sync/test/integration/send_tab_to_self_helper.cc new file mode 100644 index 0000000..7e2c6e4 --- /dev/null +++ b/chrome/browser/sync/test/integration/send_tab_to_self_helper.cc
@@ -0,0 +1,106 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/sync/test/integration/send_tab_to_self_helper.h" + +#include "base/logging.h" +#include "chrome/browser/sync/test/integration/sync_test.h" +#include "components/send_tab_to_self/send_tab_to_self_entry.h" +#include "components/send_tab_to_self/send_tab_to_self_model.h" +#include "components/send_tab_to_self/send_tab_to_self_model_observer.h" +#include "components/send_tab_to_self/send_tab_to_self_service.h" + +namespace send_tab_to_self_helper { + +SendTabToSelfUrlChecker::SendTabToSelfUrlChecker( + send_tab_to_self::SendTabToSelfService* service, + const GURL& url) + : url_(url), service_(service) { + service->GetSendTabToSelfModel()->AddObserver(this); +} + +SendTabToSelfUrlChecker::~SendTabToSelfUrlChecker() { + service_->GetSendTabToSelfModel()->RemoveObserver(this); +} + +bool SendTabToSelfUrlChecker::IsExitConditionSatisfied() { + send_tab_to_self::SendTabToSelfModel* model = + service_->GetSendTabToSelfModel(); + for (auto const& guid : model->GetAllGuids()) { + if (model->GetEntryByGUID(guid)->GetURL() == url_) { + return true; + } + } + return false; +} + +std::string SendTabToSelfUrlChecker::GetDebugMessage() const { + return "Waiting for data for url '" + url_.spec() + "' to be populated."; +} + +void SendTabToSelfUrlChecker::SendTabToSelfModelLoaded() { + CheckExitCondition(); +} + +void SendTabToSelfUrlChecker::SendTabToSelfModelChanged() { + CheckExitCondition(); +} + +SendTabToSelfModelEqualityChecker::SendTabToSelfModelEqualityChecker( + send_tab_to_self::SendTabToSelfService* service0, + send_tab_to_self::SendTabToSelfService* service1) + : service0_(service0), service1_(service1) { + service0->GetSendTabToSelfModel()->AddObserver(this); + service1->GetSendTabToSelfModel()->AddObserver(this); +} + +SendTabToSelfModelEqualityChecker::~SendTabToSelfModelEqualityChecker() { + service0_->GetSendTabToSelfModel()->RemoveObserver(this); + service1_->GetSendTabToSelfModel()->RemoveObserver(this); +} + +bool SendTabToSelfModelEqualityChecker::IsExitConditionSatisfied() { + const send_tab_to_self::SendTabToSelfModel* model0 = + service0_->GetSendTabToSelfModel(); + const send_tab_to_self::SendTabToSelfModel* model1 = + service1_->GetSendTabToSelfModel(); + + if (model0->GetAllGuids() != model1->GetAllGuids()) { + return false; + } + for (auto const& guid : model0->GetAllGuids()) { + const send_tab_to_self::SendTabToSelfEntry* entry0 = + model0->GetEntryByGUID(guid); + const send_tab_to_self::SendTabToSelfEntry* entry1 = + model1->GetEntryByGUID(guid); + + DCHECK_NE(entry0, nullptr); + DCHECK_NE(entry1, nullptr); + + if (entry0->GetGUID() != entry1->GetGUID() || + entry0->GetURL() != entry1->GetURL() || + entry0->GetTitle() != entry1->GetTitle() || + entry0->GetSharedTime() != entry1->GetSharedTime() || + entry0->GetOriginalNavigationTime() != + entry1->GetOriginalNavigationTime() || + entry0->GetDeviceName() != entry1->GetDeviceName()) { + return false; + } + } + return true; +} + +std::string SendTabToSelfModelEqualityChecker::GetDebugMessage() const { + return "Waiting for services to converge"; +} + +void SendTabToSelfModelEqualityChecker::SendTabToSelfModelLoaded() { + CheckExitCondition(); +} + +void SendTabToSelfModelEqualityChecker::SendTabToSelfModelChanged() { + CheckExitCondition(); +} + +} // namespace send_tab_to_self_helper
diff --git a/chrome/browser/sync/test/integration/send_tab_to_self_helper.h b/chrome/browser/sync/test/integration/send_tab_to_self_helper.h new file mode 100644 index 0000000..56fe2894 --- /dev/null +++ b/chrome/browser/sync/test/integration/send_tab_to_self_helper.h
@@ -0,0 +1,74 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SYNC_TEST_INTEGRATION_SEND_TAB_TO_SELF_HELPER_H_ +#define CHROME_BROWSER_SYNC_TEST_INTEGRATION_SEND_TAB_TO_SELF_HELPER_H_ + +#include <string> +#include <vector> + +#include "chrome/browser/sync/test/integration/status_change_checker.h" +#include "components/send_tab_to_self/send_tab_to_self_model_observer.h" +#include "url/gurl.h" + +namespace send_tab_to_self { +class SendTabToSelfService; +} // namespace send_tab_to_self + +namespace send_tab_to_self_helper { + +// Class that allows waiting until a particular |url| is exposed by the +// SendTabToSelfModel in|service|. +class SendTabToSelfUrlChecker + : public StatusChangeChecker, + public send_tab_to_self::SendTabToSelfModelObserver { + public: + SendTabToSelfUrlChecker(send_tab_to_self::SendTabToSelfService* service, + const GURL& url); + ~SendTabToSelfUrlChecker() override; + + // StatusChangeChecker implementation. + bool IsExitConditionSatisfied() override; + std::string GetDebugMessage() const override; + + // SendTabToSelfModelObserver implementation. + void SendTabToSelfModelLoaded() override; + void SendTabToSelfModelChanged() override; + + private: + const GURL url_; + send_tab_to_self::SendTabToSelfService* const service_; + + DISALLOW_COPY_AND_ASSIGN(SendTabToSelfUrlChecker); +}; + +// Class that allows waiting the number of entries in until |service0| +// matches the number of entries in |service1|. +class SendTabToSelfModelEqualityChecker + : public StatusChangeChecker, + public send_tab_to_self::SendTabToSelfModelObserver { + public: + SendTabToSelfModelEqualityChecker( + send_tab_to_self::SendTabToSelfService* service0, + send_tab_to_self::SendTabToSelfService* service1); + ~SendTabToSelfModelEqualityChecker() override; + + // StatusChangeChecker implementation. + bool IsExitConditionSatisfied() override; + std::string GetDebugMessage() const override; + + // SendTabToSelfModelObserver implementation. + void SendTabToSelfModelLoaded() override; + void SendTabToSelfModelChanged() override; + + private: + send_tab_to_self::SendTabToSelfService* const service0_; + send_tab_to_self::SendTabToSelfService* const service1_; + + DISALLOW_COPY_AND_ASSIGN(SendTabToSelfModelEqualityChecker); +}; + +} // namespace send_tab_to_self_helper + +#endif // CHROME_BROWSER_SYNC_TEST_INTEGRATION_SEND_TAB_TO_SELF_HELPER_H_
diff --git a/chrome/browser/sync/test/integration/single_client_send_tab_to_self_sync_test.cc b/chrome/browser/sync/test/integration/single_client_send_tab_to_self_sync_test.cc new file mode 100644 index 0000000..fef3bdd5 --- /dev/null +++ b/chrome/browser/sync/test/integration/single_client_send_tab_to_self_sync_test.cc
@@ -0,0 +1,52 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h" +#include "chrome/browser/sync/test/integration/send_tab_to_self_helper.h" +#include "chrome/browser/sync/test/integration/sync_test.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "url/gurl.h" + +namespace { + +class SingleClientSendTabToSelfSyncTest : public SyncTest { + public: + SingleClientSendTabToSelfSyncTest() : SyncTest(SINGLE_CLIENT) { + scoped_list_.InitAndEnableFeature(switches::kSyncSendTabToSelf); + } + + ~SingleClientSendTabToSelfSyncTest() override {} + + private: + base::test::ScopedFeatureList scoped_list_; + + DISALLOW_COPY_AND_ASSIGN(SingleClientSendTabToSelfSyncTest); +}; + +IN_PROC_BROWSER_TEST_F(SingleClientSendTabToSelfSyncTest, + DownloadWhenSyncEnabled) { + const std::string kUrl("https://www.example.com"); + const std::string kGuid("kGuid"); + + sync_pb::EntitySpecifics specifics; + sync_pb::SendTabToSelfSpecifics* send_tab_to_self = + specifics.mutable_send_tab_to_self(); + send_tab_to_self->set_url(kUrl); + send_tab_to_self->set_guid(kGuid); + + fake_server_->InjectEntity( + syncer::PersistentUniqueClientEntity::CreateFromSpecificsForTesting( + "non_unique_name", kGuid, specifics, /*creation_time=*/0, + /*last_modified_time=*/0)); + + ASSERT_TRUE(SetupSync()); + + EXPECT_TRUE(send_tab_to_self_helper::SendTabToSelfUrlChecker( + SendTabToSelfSyncServiceFactory::GetForProfile(GetProfile(0)), + GURL(kUrl)) + .Wait()); +} + +} // namespace
diff --git a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc index 744d125..e6f9ea5 100644 --- a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc
@@ -67,6 +67,20 @@ EXPECT_NE(0, histogram_tester.GetBucketCount( "Sync.ModelTypeEntityChange3.PREFERENCE", /*REMOTE_NON_INITIAL_UPDATE=*/4)); + + // Metrics below are instrumented for the USS codepath only. + if (GetParam()) { + EXPECT_EQ( + 1U, + histogram_tester + .GetAllSamples( + "Sync.NonReflectionUpdateFreshnessPossiblySkewed.PREFERENCE") + .size()); + EXPECT_NE(0U, histogram_tester + .GetAllSamples( + "Sync.NonReflectionUpdateFreshnessPossiblySkewed") + .size()); + } } IN_PROC_BROWSER_TEST_P(TwoClientPreferencesSyncTest, E2E_ENABLED(BooleanPref)) {
diff --git a/chrome/browser/sync/test/integration/two_client_send_tab_to_self_sync_test.cc b/chrome/browser/sync/test/integration/two_client_send_tab_to_self_sync_test.cc new file mode 100644 index 0000000..fde87c7 --- /dev/null +++ b/chrome/browser/sync/test/integration/two_client_send_tab_to_self_sync_test.cc
@@ -0,0 +1,80 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h" +#include "chrome/browser/sync/test/integration/send_tab_to_self_helper.h" +#include "chrome/browser/sync/test/integration/sync_test.h" +#include "components/send_tab_to_self/send_tab_to_self_model.h" +#include "components/send_tab_to_self/send_tab_to_self_service.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "url/gurl.h" + +class TwoClientSendTabToSelfSyncTest : public SyncTest { + public: + TwoClientSendTabToSelfSyncTest() : SyncTest(TWO_CLIENT) { + scoped_list_.InitAndEnableFeature(switches::kSyncSendTabToSelf); + } + + ~TwoClientSendTabToSelfSyncTest() override {} + + private: + base::test::ScopedFeatureList scoped_list_; + + DISALLOW_COPY_AND_ASSIGN(TwoClientSendTabToSelfSyncTest); +}; + +IN_PROC_BROWSER_TEST_F(TwoClientSendTabToSelfSyncTest, + AddedUrlFoundWhenBothClientsAlreadySyncing) { + const GURL kUrl("https://www.example.com"); + const std::string kTitle("example"); + const base::Time kTime = base::Time::FromDoubleT(0); + + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + send_tab_to_self::SendTabToSelfModel* model0 = + SendTabToSelfSyncServiceFactory::GetForProfile(GetProfile(0)) + ->GetSendTabToSelfModel(); + + model0->AddEntry(kUrl, kTitle, kTime); + + send_tab_to_self::SendTabToSelfService* service1 = + SendTabToSelfSyncServiceFactory::GetForProfile(GetProfile(1)); + + EXPECT_TRUE( + send_tab_to_self_helper::SendTabToSelfUrlChecker(service1, kUrl).Wait()); +} + +IN_PROC_BROWSER_TEST_F(TwoClientSendTabToSelfSyncTest, + ModelsMatchAfterAddWhenBothClientsAlreadySyncing) { + const GURL kGurl0("https://www.example0.com"); + const std::string kTitle0("example0"); + const base::Time kTime0 = base::Time::FromDoubleT(0); + + const GURL kGurl1("https://www.example1.com"); + const std::string kTitle1("example1"); + const base::Time kTime1 = base::Time::FromDoubleT(1); + + const GURL kGurl2("https://www.example2.com"); + const std::string kTitle2("example2"); + const base::Time kTime2 = base::Time::FromDoubleT(2); + + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + send_tab_to_self::SendTabToSelfModel* model0 = + SendTabToSelfSyncServiceFactory::GetForProfile(GetProfile(0)) + ->GetSendTabToSelfModel(); + + model0->AddEntry(kGurl0, kTitle0, kTime0); + model0->AddEntry(kGurl1, kTitle1, kTime1); + + SendTabToSelfSyncServiceFactory::GetForProfile(GetProfile(1)) + ->GetSendTabToSelfModel() + ->AddEntry(kGurl2, kTitle2, kTime2); + + EXPECT_TRUE(send_tab_to_self_helper::SendTabToSelfModelEqualityChecker( + SendTabToSelfSyncServiceFactory::GetForProfile(GetProfile(1)), + SendTabToSelfSyncServiceFactory::GetForProfile(GetProfile(0))) + .Wait()); +}
diff --git a/chrome/browser/ui/tab_ui_helper.h b/chrome/browser/ui/tab_ui_helper.h index 9ceef10..0c16790 100644 --- a/chrome/browser/ui/tab_ui_helper.h +++ b/chrome/browser/ui/tab_ui_helper.h
@@ -12,6 +12,7 @@ #include "base/task/cancelable_task_tracker.h" #include "components/favicon_base/favicon_callback.h" #include "components/favicon_base/favicon_types.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h"
diff --git a/chrome/browser/ui/tabs/tab_activity_simulator.cc b/chrome/browser/ui/tabs/tab_activity_simulator.cc index e6b1544..c3fe2ef 100644 --- a/chrome/browser/ui/tabs/tab_activity_simulator.cc +++ b/chrome/browser/ui/tabs/tab_activity_simulator.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/test/navigation_simulator.h" #include "content/public/test/web_contents_tester.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/discover/wait_for_did_start_navigate.h b/chrome/browser/ui/webui/chromeos/login/discover/wait_for_did_start_navigate.h index 1c28383..a6d32dd1 100644 --- a/chrome/browser/ui/webui/chromeos/login/discover/wait_for_did_start_navigate.h +++ b/chrome/browser/ui/webui/chromeos/login/discover/wait_for_did_start_navigate.h
@@ -7,7 +7,7 @@ #include "base/macros.h" #include "base/run_loop.h" -#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" #include "url/gurl.h" namespace chromeos {
diff --git a/chrome/browser/ui/webui/help/version_updater_chromeos.cc b/chrome/browser/ui/webui/help/version_updater_chromeos.cc index 66060e64..943d9bd0 100644 --- a/chrome/browser/ui/webui/help/version_updater_chromeos.cc +++ b/chrome/browser/ui/webui/help/version_updater_chromeos.cc
@@ -218,8 +218,8 @@ // One time permission is set successfully, so we can proceed to update. CheckForUpdate(callback_, VersionUpdater::PromoteCallback()); } else { - // TODO(weidongg/691108): invoke callback to signal about page to show - // appropriate error message. + // TODO(https://crbug.com/927452): invoke callback to signal about page to + // show appropriate error message. LOG(ERROR) << "Error setting update over cellular one time permission."; callback_.Run(VersionUpdater::FAILED, 0, false, std::string(), 0, base::string16());
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider.cc index 73ae295..231e5f7 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider.cc
@@ -56,25 +56,6 @@ void CGaiaCredentialProvider::FinalRelease() { LOGFN(INFO); ClearTransient(); - - // Delete the startup sentinel file if any still exists. It can still exist - // in 2 cases: - - // 1. The FinalRelease should only occur after the user has logged in, so if - // they never selected any gaia credential and just used normal credentials - // this function will be called in that situation and it is guaranteed that - // the user has at least been able provide some input to winlogon. - // 2. When no usage scenario is supported, none of the credentials will be - // selected and thus the gcpw startup sentinel file will not be deleted. - // So in the case where the user is asked for CPUS_CRED_UI enough times, - // the sentinel file size will keep growing without being deleted and - // eventually GCPW will be disabled completed. In the unsupported usage - // scenario, FinalRelease will be called shortly after SetUsageScenario - // if the function returns E_NOTIMPL so try to catch potential crashes - // of the destruction of the provider when it is not used because - // crashes in this case will prevent the cred ui from coming up and not - // allow the user to access their desired resource. - DeleteStartupSentinel(); } HRESULT CGaiaCredentialProvider::CreateGaiaCredential() { @@ -380,6 +361,26 @@ ClearTransient(); HRESULT hr = DestroyCredentials(); LOGFN(INFO) << "hr=" << putHR(hr); + + // Delete the startup sentinel file if any still exists. It can still exist + // in 2 cases: + + // 1. The UnAdvise should only occur after the user has logged in, so if + // they never selected any gaia credential and just used normal credentials + // this function will be called in that situation and it is guaranteed that + // the user has at least been able provide some input to winlogon. + // 2. When no usage scenario is supported, none of the credentials will be + // selected and thus the gcpw startup sentinel file will not be deleted. + // So in the case where the user is asked for CPUS_CRED_UI enough times, + // the sentinel file size will keep growing without being deleted and + // eventually GCPW will be disabled completely. In the unsupported usage + // scenario, FinalRelease will be called shortly after SetUsageScenario + // if the function returns E_NOTIMPL so try to catch potential crashes + // of the destruction of the provider when it is not used because + // crashes in this case will prevent the cred ui from coming up and not + // allow the user to access their desired resource. + DeleteStartupSentinel(); + return S_OK; }
diff --git a/chrome/services/media_gallery_util/BUILD.gn b/chrome/services/media_gallery_util/BUILD.gn index db40c64..3292488 100644 --- a/chrome/services/media_gallery_util/BUILD.gn +++ b/chrome/services/media_gallery_util/BUILD.gn
@@ -29,6 +29,8 @@ sources += [ "media_parser_android.cc", "media_parser_android.h", + "video_thumbnail_parser.cc", + "video_thumbnail_parser.h", ] }
diff --git a/chrome/services/media_gallery_util/media_parser_android.cc b/chrome/services/media_gallery_util/media_parser_android.cc index a6078d6..57c94b6 100644 --- a/chrome/services/media_gallery_util/media_parser_android.cc +++ b/chrome/services/media_gallery_util/media_parser_android.cc
@@ -4,100 +4,30 @@ #include "chrome/services/media_gallery_util/media_parser_android.h" +#include <utility> + #include "base/bind.h" #include "base/optional.h" #include "base/task/post_task.h" -#include "base/task/task_traits.h" #include "chrome/services/media_gallery_util/ipc_data_source.h" -#include "media/base/bind_to_current_loop.h" -#include "media/base/video_codecs.h" -#include "media/base/video_thumbnail_decoder.h" -#include "media/filters/android/video_frame_extractor.h" -#include "media/filters/vpx_video_decoder.h" -#include "media/media_buildflags.h" -#include "media/mojo/common/mojo_shared_buffer_video_frame.h" +#include "chrome/services/media_gallery_util/video_thumbnail_parser.h" namespace { -// Return the video frame back to browser process. A valid |config| is -// needed for deserialization. -void OnSoftwareVideoFrameDecoded( - std::unique_ptr<media::VideoThumbnailDecoder>, - MediaParser::ExtractVideoFrameCallback video_frame_callback, - const media::VideoDecoderConfig& config, - scoped_refptr<media::VideoFrame> frame) { - DCHECK(video_frame_callback); - - if (!frame) { - std::move(video_frame_callback) - .Run(false, chrome::mojom::VideoFrameData::New(), base::nullopt); - return; - } - - std::move(video_frame_callback) - .Run(true, - chrome::mojom::VideoFrameData::NewDecodedFrame( - media::MojoSharedBufferVideoFrame::CreateFromYUVFrame(*frame)), - config); -} - -void OnEncodedVideoFrameExtracted( - std::unique_ptr<media::VideoFrameExtractor> video_frame_extractor, +void OnVideoFrameExtracted( + std::unique_ptr<VideoThumbnailParser>, MediaParser::ExtractVideoFrameCallback video_frame_callback, bool success, - std::vector<uint8_t> data, - const media::VideoDecoderConfig& config) { - if (!success || data.empty()) { - std::move(video_frame_callback) - .Run(false, chrome::mojom::VideoFrameData::New(), base::nullopt); - return; - } - -#if BUILDFLAG(USE_PROPRIETARY_CODECS) && \ - !BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) - // H264 currently needs to be decoded in GPU process when no software decoder - // is provided. - if (config.codec() == media::VideoCodec::kCodecH264) { - std::move(video_frame_callback) - .Run(success, - chrome::mojom::VideoFrameData::NewEncodedData(std::move(data)), - config); - return; - } -#endif - - if (config.codec() != media::VideoCodec::kCodecVP8 && - config.codec() != media::VideoCodec::kCodecVP9) { - std::move(video_frame_callback) - .Run(false, chrome::mojom::VideoFrameData::New(), base::nullopt); - return; - } - - // Decode with libvpx for vp8, vp9. - auto thumbnail_decoder = std::make_unique<media::VideoThumbnailDecoder>( - std::make_unique<media::VpxVideoDecoder>(), config, std::move(data)); - - thumbnail_decoder->Start( - base::BindOnce(&OnSoftwareVideoFrameDecoded, std::move(thumbnail_decoder), - std::move(video_frame_callback), config)); -} - -void ExtractVideoFrameOnMediaThread( - media::DataSource* data_source, - MediaParser::ExtractVideoFrameCallback video_frame_callback) { - auto extractor = std::make_unique<media::VideoFrameExtractor>(data_source); - extractor->Start(base::BindOnce(&OnEncodedVideoFrameExtracted, - std::move(extractor), - std::move(video_frame_callback))); + chrome::mojom::VideoFrameDataPtr frame_data, + const base::Optional<media::VideoDecoderConfig>& config) { + std::move(video_frame_callback).Run(success, std::move(frame_data), config); } } // namespace MediaParserAndroid::MediaParserAndroid( std::unique_ptr<service_manager::ServiceContextRef> service_ref) - : MediaParser(std::move(service_ref)), - media_task_runner_( - base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()})) {} + : MediaParser(std::move(service_ref)) {} MediaParserAndroid::~MediaParserAndroid() = default; @@ -106,12 +36,14 @@ uint32_t total_size, chrome::mojom::MediaDataSourcePtr media_data_source, MediaParser::ExtractVideoFrameCallback video_frame_callback) { - data_source_ = std::make_unique<IPCDataSource>( + auto data_source = std::make_unique<IPCDataSource>( std::move(media_data_source), static_cast<int64_t>(total_size)); - media_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &ExtractVideoFrameOnMediaThread, data_source_.get(), - media::BindToCurrentLoop(std::move(video_frame_callback)))); + // Leak |parser| on utility main thread, because |data_source| lives on main + // thread and is used on another thread as raw pointer. Leaked |parser| will + // be deleted when utility process dies or |OnVideoFrameExtracted| callback + // is called. + auto parser = std::make_unique<VideoThumbnailParser>(std::move(data_source)); + parser->Start(base::BindOnce(&OnVideoFrameExtracted, std::move(parser), + std::move(video_frame_callback))); }
diff --git a/chrome/services/media_gallery_util/media_parser_android.h b/chrome/services/media_gallery_util/media_parser_android.h index 2eb33d4..369f16f8 100644 --- a/chrome/services/media_gallery_util/media_parser_android.h +++ b/chrome/services/media_gallery_util/media_parser_android.h
@@ -10,10 +10,6 @@ #include "base/macros.h" #include "chrome/services/media_gallery_util/media_parser.h" -namespace media { -class DataSource; -} // namespace media - // The media parser on Android that provides video thumbnail generation utility. class MediaParserAndroid : public MediaParser { public: @@ -29,11 +25,6 @@ ExtractVideoFrameCallback video_frame_callback) override; private: - // The task runner to do blocking IO. The utility thread cannot be blocked. - scoped_refptr<base::SequencedTaskRunner> media_task_runner_; - - std::unique_ptr<media::DataSource> data_source_; - DISALLOW_COPY_AND_ASSIGN(MediaParserAndroid); };
diff --git a/chrome/services/media_gallery_util/video_thumbnail_parser.cc b/chrome/services/media_gallery_util/video_thumbnail_parser.cc new file mode 100644 index 0000000..83d57c2 --- /dev/null +++ b/chrome/services/media_gallery_util/video_thumbnail_parser.cc
@@ -0,0 +1,114 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/services/media_gallery_util/video_thumbnail_parser.h" + +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/optional.h" +#include "base/task/post_task.h" +#include "base/task/task_traits.h" +#include "chrome/services/media_gallery_util/ipc_data_source.h" +#include "media/base/bind_to_current_loop.h" +#include "media/base/video_codecs.h" +#include "media/base/video_thumbnail_decoder.h" +#include "media/filters/android/video_frame_extractor.h" +#include "media/filters/vpx_video_decoder.h" +#include "media/media_buildflags.h" +#include "media/mojo/common/mojo_shared_buffer_video_frame.h" + +namespace { + +// Return the video frame back to browser process. A valid |config| is +// needed for deserialization. +void OnSoftwareVideoFrameDecoded( + std::unique_ptr<media::VideoThumbnailDecoder>, + MediaParser::ExtractVideoFrameCallback video_frame_callback, + const media::VideoDecoderConfig& config, + scoped_refptr<media::VideoFrame> frame) { + DCHECK(video_frame_callback); + + if (!frame) { + std::move(video_frame_callback) + .Run(false, chrome::mojom::VideoFrameData::New(), base::nullopt); + return; + } + + std::move(video_frame_callback) + .Run(true, + chrome::mojom::VideoFrameData::NewDecodedFrame( + media::MojoSharedBufferVideoFrame::CreateFromYUVFrame(*frame)), + config); +} + +void OnEncodedVideoFrameExtracted( + std::unique_ptr<media::VideoFrameExtractor> video_frame_extractor, + MediaParser::ExtractVideoFrameCallback video_frame_callback, + bool success, + std::vector<uint8_t> data, + const media::VideoDecoderConfig& config) { + if (!success || data.empty()) { + std::move(video_frame_callback) + .Run(false, chrome::mojom::VideoFrameData::New(), base::nullopt); + return; + } + +#if BUILDFLAG(USE_PROPRIETARY_CODECS) && \ + !BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) + // H264 currently needs to be decoded in GPU process when no software decoder + // is provided. + if (config.codec() == media::VideoCodec::kCodecH264) { + std::move(video_frame_callback) + .Run(success, + chrome::mojom::VideoFrameData::NewEncodedData(std::move(data)), + config); + return; + } +#endif + + if (config.codec() != media::VideoCodec::kCodecVP8 && + config.codec() != media::VideoCodec::kCodecVP9) { + std::move(video_frame_callback) + .Run(false, chrome::mojom::VideoFrameData::New(), base::nullopt); + return; + } + + // Decode with libvpx for vp8, vp9. + auto thumbnail_decoder = std::make_unique<media::VideoThumbnailDecoder>( + std::make_unique<media::VpxVideoDecoder>(), config, std::move(data)); + + thumbnail_decoder->Start( + base::BindOnce(&OnSoftwareVideoFrameDecoded, std::move(thumbnail_decoder), + std::move(video_frame_callback), config)); +} + +void ExtractVideoFrameOnMediaThread( + media::DataSource* data_source, + MediaParser::ExtractVideoFrameCallback video_frame_callback) { + auto extractor = std::make_unique<media::VideoFrameExtractor>(data_source); + extractor->Start(base::BindOnce(&OnEncodedVideoFrameExtracted, + std::move(extractor), + std::move(video_frame_callback))); +} + +} // namespace + +VideoThumbnailParser::VideoThumbnailParser( + std::unique_ptr<media::DataSource> source) + : data_source_(std::move(source)), + media_task_runner_( + base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()})) {} + +VideoThumbnailParser::~VideoThumbnailParser() = default; + +void VideoThumbnailParser::Start( + MediaParser::ExtractVideoFrameCallback video_frame_callback) { + media_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &ExtractVideoFrameOnMediaThread, data_source_.get(), + media::BindToCurrentLoop(std::move(video_frame_callback)))); +}
diff --git a/chrome/services/media_gallery_util/video_thumbnail_parser.h b/chrome/services/media_gallery_util/video_thumbnail_parser.h new file mode 100644 index 0000000..7b2d857 --- /dev/null +++ b/chrome/services/media_gallery_util/video_thumbnail_parser.h
@@ -0,0 +1,40 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_SERVICES_MEDIA_GALLERY_UTIL_VIDEO_THUMBNAIL_PARSER_H_ +#define CHROME_SERVICES_MEDIA_GALLERY_UTIL_VIDEO_THUMBNAIL_PARSER_H_ + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "base/sequenced_task_runner.h" +#include "chrome/services/media_gallery_util/media_parser.h" + +namespace media { +class DataSource; +} // namespace media + +// Parses a video frame. This object is created on utility process main thread, +// and will perform actual parsing on a media thread. +class VideoThumbnailParser { + public: + explicit VideoThumbnailParser(std::unique_ptr<media::DataSource> source); + ~VideoThumbnailParser(); + + void Start(MediaParser::ExtractVideoFrameCallback video_frame_callback); + + private: + // The data source that provides video data. Created and destroyed on utility + // main thread because it's binded to mojo object. Must be used on + // |media_task_runner_|. + std::unique_ptr<media::DataSource> data_source_; + + scoped_refptr<base::SequencedTaskRunner> media_task_runner_; + + DISALLOW_COPY_AND_ASSIGN(VideoThumbnailParser); +}; + +#endif // CHROME_SERVICES_MEDIA_GALLERY_UTIL_VIDEO_THUMBNAIL_PARSER_H_
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 69babd6..d7369ec 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -481,6 +481,7 @@ "//chrome/browser/chromeos/login/test/https_forwarder.py", "//chrome/browser/resources/chromeos/wallpaper_manager/", "//chrome/browser/resources/chromeos/zip_archiver/", + "//google_apis/test/", "//chrome/browser/resources/chromeos/zip_archiver/test/", "//chromeos/test/data/", "//ui/file_manager/base/", @@ -502,16 +503,55 @@ "//ash:ash_service_resources", "//chrome", "//ui/keyboard:resources", + "//ui/file_manager:unit_test_data", ] + if (use_dbus) { + deps += [ "//dbus:test_support" ] + } + if (enable_nacl) { data_deps += [ "//components/nacl/loader:nacl_helper", "//ppapi/native_client:irt", ] + + if (enable_nacl_nonsfi) { + data_deps += [ "//components/nacl/loader:helper_nonsfi" ] + } } - deps += [ "//chrome/browser/chromeos:test_support" ] + deps += [ + "//ash:interactive_ui_test_support", + "//ash:test_support", + "//ash/public/interfaces:test_interfaces", + "//chrome/browser/chromeos:arc_test_support", + "//chrome/browser/chromeos:test_support", + "//chrome/browser/media/router:test_support", + "//chrome/browser/resources/chromeos/chromevox:browser_tests", + "//chrome/browser/resources/chromeos/select_to_speak:browser_tests", + "//chrome/browser/resources/chromeos/switch_access:browser_tests", + "//chrome/services/file_util/public/cpp:browser_tests", + "//chromeos:test_support", + "//chromeos/components/drivefs:test_support", + "//chromeos/dbus:test_support", + "//components/arc:arc_test_support", + "//components/exo:test_support", + "//components/prefs", + "//components/user_manager:test_support", + "//content/public/common:feature_h264_with_openh264_ffmpeg", + "//mojo/core/embedder", + "//services/audio/public/cpp:test_support", + "//services/identity/public/cpp", + "//services/network/public/mojom", + "//services/preferences/public/cpp", + "//services/preferences/public/mojom", + "//services/service_manager/public/cpp", + "//services/ws/public/cpp/input_devices:test_support", + "//ui/keyboard:test_support", + "//ui/login:resources", + "//url", + ] } # TODO(jbudorick): In progress. See crbug.com/611756 @@ -1496,6 +1536,7 @@ "../browser/accessibility/accessibility_extension_api_browsertest.cc", "../browser/apps/platform_apps/api/arc_apps_private/arc_apps_private_apitest.cc", "../browser/extensions/api/system_display/system_display_chromeos_apitest.cc", + "../browser/extensions/clipboard_extension_apitest_chromeos.cc", ] } @@ -1650,10 +1691,18 @@ if (is_chromeos) { assert(enable_app_list) sources += [ + "../browser/apps/platform_apps/app_window_interactive_uitest.cc", + "../browser/apps/platform_apps/app_window_interactive_uitest.h", "../browser/chromeos/accessibility/accessibility_manager_browsertest.cc", + "../browser/chromeos/accessibility/dictation_chromeos_browsertest.cc", + "../browser/chromeos/accessibility/magnification_controller_browsertest.cc", "../browser/chromeos/accessibility/magnification_manager_browsertest.cc", + "../browser/chromeos/accessibility/select_to_speak_browsertest.cc", "../browser/chromeos/accessibility/speech_monitor.cc", "../browser/chromeos/accessibility/speech_monitor.h", + "../browser/chromeos/accessibility/spoken_feedback_browsertest.cc", + "../browser/chromeos/accessibility/sticky_keys_browsertest.cc", + "../browser/chromeos/accessibility/switch_access_browsertest.cc", "../browser/chromeos/accessibility/touch_exploration_controller_browsertest.cc", "../browser/chromeos/app_mode/arc/arc_kiosk_app_manager_browsertest.cc", "../browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc", @@ -1717,9 +1766,12 @@ "../browser/chromeos/first_run/drive_first_run_browsertest.cc", "../browser/chromeos/first_run/goodies_displayer_browsertest.cc", "../browser/chromeos/input_method/input_method_engine_browsertests.cc", + "../browser/chromeos/input_method/textinput_browsertest.cc", + "../browser/chromeos/input_method/textinput_surroundingtext_browsertest.cc", "../browser/chromeos/input_method/textinput_test_helper.cc", "../browser/chromeos/input_method/textinput_test_helper.h", "../browser/chromeos/lock_screen_apps/note_taking_browsertest.cc", + "../browser/chromeos/login/active_directory_login_browsertest.cc", "../browser/chromeos/login/active_directory_test_helper.cc", "../browser/chromeos/login/active_directory_test_helper.h", "../browser/chromeos/login/auto_launched_kiosk_browsertest.cc", @@ -1742,13 +1794,19 @@ "../browser/chromeos/login/lock/screen_locker_browsertest.cc", "../browser/chromeos/login/lock/screen_locker_tester.cc", "../browser/chromeos/login/lock/screen_locker_tester.h", + "../browser/chromeos/login/login_auth_recorder_browsertest.cc", + "../browser/chromeos/login/login_browsertest.cc", "../browser/chromeos/login/login_manager_test.cc", "../browser/chromeos/login/login_manager_test.h", "../browser/chromeos/login/login_screen_policy_browsertest.cc", + "../browser/chromeos/login/login_ui_browsertest.cc", + "../browser/chromeos/login/login_ui_hide_supervised_users_browsertest.cc", "../browser/chromeos/login/login_ui_keyboard_browsertest.cc", "../browser/chromeos/login/login_utils_browsertest.cc", "../browser/chromeos/login/mixin_based_in_process_browser_test.cc", "../browser/chromeos/login/mixin_based_in_process_browser_test.h", + "../browser/chromeos/login/oobe_browsertest.cc", + "../browser/chromeos/login/oobe_interactive_ui_test.cc", "../browser/chromeos/login/oobe_localization_browsertest.cc", "../browser/chromeos/login/proxy_auth_dialog_browsertest.cc", "../browser/chromeos/login/quick_unlock/pin_migration_browsertest.cc", @@ -1771,6 +1829,18 @@ "../browser/chromeos/login/screens/network_screen_browsertest.cc", "../browser/chromeos/login/screens/update_screen_browsertest.cc", "../browser/chromeos/login/screens/user_selection_screen_browsertest.cc", + "../browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric.h", + "../browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric_cpu.cpp", + "../browser/chromeos/login/screenshot_testing/SkImageDiffer.cpp", + "../browser/chromeos/login/screenshot_testing/SkImageDiffer.h", + "../browser/chromeos/login/screenshot_testing/SkPMetric.cpp", + "../browser/chromeos/login/screenshot_testing/SkPMetric.h", + "../browser/chromeos/login/screenshot_testing/SkPMetricUtil_gen.h", + "../browser/chromeos/login/screenshot_testing/login_screen_areas.h", + "../browser/chromeos/login/screenshot_testing/screenshot_tester.cc", + "../browser/chromeos/login/screenshot_testing/screenshot_tester.h", + "../browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.cc", + "../browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.h", "../browser/chromeos/login/session/chrome_session_manager_browsertest.cc", "../browser/chromeos/login/session_login_browsertest.cc", "../browser/chromeos/login/signin/device_id_browsertest.cc", @@ -1832,6 +1902,7 @@ "../browser/chromeos/shutdown_policy_browsertest.cc", "../browser/chromeos/system/device_disabling_browsertest.cc", "../browser/chromeos/system/tray_accessibility_browsertest.cc", + "../browser/download/notification/download_notification_interactive_uitest.cc", "../browser/drive/drive_notification_manager_factory_browsertest.cc", "../browser/extensions/api/certificate_provider/certificate_provider_apitest.cc", "../browser/extensions/api/networking_private/networking_private_apitest.cc", @@ -1859,10 +1930,12 @@ "../browser/ui/ash/shelf_browsertest.cc", "../browser/ui/ash/system_tray_client_browsertest.cc", "../browser/ui/ash/system_tray_tray_cast_browsertest_media_router_chromeos.cc", + "../browser/ui/ash/tab_scrubber_browsertest.cc", "../browser/ui/ash/tablet_mode_page_behavior_browsertest.cc", "../browser/ui/ash/time_to_first_present_recorder_browsertest.cc", "../browser/ui/ash/volume_controller_browsertest.cc", "../browser/ui/views/apps/chrome_native_app_window_views_aura_ash_browsertest.cc", + "../browser/ui/views/apps/chrome_native_app_window_views_aura_ash_interactive_uitest.cc", "../browser/ui/views/arc_app_dialog_view_browsertest.cc", "../browser/ui/views/crostini/crostini_browser_test_util.cc", "../browser/ui/views/crostini/crostini_browser_test_util.h", @@ -1873,6 +1946,7 @@ "../browser/ui/views/extensions/extension_dialog_bounds_browsertest.cc", "../browser/ui/views/frame/browser_frame_ash_browsertest.cc", "../browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc", + "../browser/ui/views/frame/hosted_app_ash_interactive_ui_test.cc", "../browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc", "../browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc", "../browser/ui/views/plugin_vm/plugin_vm_launcher_view_browsertest.cc", @@ -1884,13 +1958,32 @@ "../browser/ui/webui/chromeos/login/discover/modules/discover_module_sync_files_test.cc", "../browser/ui/webui/chromeos/login/discover/wait_for_did_start_navigate.cc", "../browser/ui/webui/chromeos/login/discover/wait_for_did_start_navigate.h", + "../browser/ui/webui/chromeos/login/oobe_display_chooser_browsertest.cc", "../browser/ui/webui/chromeos/system_web_dialog_browsertest.cc", "../browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc", + "../browser/ui/window_sizer/window_sizer_ash_uitest.cc", + "//ash/accelerators/accelerator_interactive_uitest_chromeos.cc", + "//ash/app_list/app_list_interactive_uitest.cc", + "//ash/drag_drop/drag_drop_interactive_uitest.cc", + "//ash/wm/native_cursor_manager_ash_interactive_uitest.cc", + "base/interactive_test_utils.cc", + "base/interactive_test_utils.h", + "base/interactive_test_utils_aura.cc", + "base/interactive_test_utils_aura.h", + "base/interactive_test_utils_common_views.cc", + "base/interactive_test_utils_views.cc", + "data/chromeos/service_login.html", ] if (enable_cros_assistant) { sources += [ "../browser/ui/ash/assistant/assistant_context_browsertest.cc" ] } + if (is_chrome_branded) { + sources += [ + # The screen this test is checking exists in official build only. + "../browser/chromeos/login/sync_consent_interactive_ui_test.cc", + ] + } sources -= [ "../../apps/load_and_launch_browsertest.cc", "../browser/policy/policy_startup_browsertest.cc", @@ -1913,36 +2006,6 @@ # chromeos does not support machine level user cloud policies "../browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc", ] - deps += [ - "//ash:test_support", - "//ash/public/interfaces:test_interfaces", - "//chrome/browser/chromeos:arc_test_support", - "//chrome/browser/chromeos:test_support", - "//chrome/browser/resources/chromeos/chromevox:browser_tests", - "//chrome/browser/resources/chromeos/select_to_speak:browser_tests", - "//chrome/browser/resources/chromeos/switch_access:browser_tests", - "//chrome/services/file_util/public/cpp:browser_tests", - "//chromeos/components/drivefs:test_support", - "//components/arc:arc_test_support", - "//components/exo:test_support", - "//components/prefs", - "//components/user_manager:test_support", - "//content/public/common:feature_h264_with_openh264_ffmpeg", - "//services/audio/public/cpp:test_support", - "//services/identity/public/cpp", - "//services/network/public/mojom", - "//services/preferences/public/cpp", - "//services/preferences/public/mojom", - "//services/service_manager/public/cpp", - "//services/ws/public/cpp/input_devices:test_support", - "//ui/keyboard:test_support", - "//ui/login:resources", - "//url", - ] - data_deps += [ "//ui/file_manager:unit_test_data" ] - if (use_dbus) { - deps += [ "//dbus:test_support" ] - } } else { # !is_chromeos sources -= [ "../browser/invalidation/deprecated_profile_invalidation_provider_factory_browsertest.cc", @@ -2268,8 +2331,8 @@ "//testing/xvfb.py", "//testing/scripts/run_telemetry_as_googletest.py", - # For smoke testing run_telemetry_benchmark_as_googletest - "//testing/scripts/run_telemetry_benchmark_as_googletest.py", + # For smoke testing run_performance_tests.py + "//testing/scripts/run_performance_tests.py", # For tests in tools/perf/process_perf_results_unittest.py "//build/android/pylib/", @@ -2294,7 +2357,6 @@ # Needed for isolate script to execute. "//testing/scripts/common.py", "//testing/xvfb.py", - "//testing/scripts/run_telemetry_benchmark_as_googletest.py", ] } @@ -4778,7 +4840,6 @@ "../browser/extensions/api/tabs/tabs_interactive_test.cc", "../browser/extensions/chrome_extension_test_notification_observer.cc", "../browser/extensions/chrome_extension_test_notification_observer.h", - "../browser/extensions/clipboard_extension_apitest_chromeos.cc", "../browser/extensions/extension_apitest.cc", "../browser/extensions/extension_browsertest.cc", "../browser/extensions/extension_commands_global_registry_apitest.cc", @@ -5034,97 +5095,13 @@ } if (is_chromeos) { - sources += [ - "../browser/chromeos/accessibility/dictation_chromeos_browsertest.cc", - "../browser/chromeos/accessibility/magnification_controller_browsertest.cc", - "../browser/chromeos/accessibility/select_to_speak_browsertest.cc", - "../browser/chromeos/accessibility/spoken_feedback_browsertest.cc", - "../browser/chromeos/accessibility/sticky_keys_browsertest.cc", - "../browser/chromeos/accessibility/switch_access_browsertest.cc", - "../browser/chromeos/input_method/textinput_browsertest.cc", - "../browser/chromeos/input_method/textinput_surroundingtext_browsertest.cc", - "../browser/chromeos/input_method/textinput_test_helper.cc", - "../browser/chromeos/input_method/textinput_test_helper.h", - "../browser/chromeos/login/active_directory_login_browsertest.cc", - "../browser/chromeos/login/active_directory_test_helper.cc", - "../browser/chromeos/login/active_directory_test_helper.h", - "../browser/chromeos/login/login_auth_recorder_browsertest.cc", - "../browser/chromeos/login/login_browsertest.cc", - "../browser/chromeos/login/login_manager_test.cc", - "../browser/chromeos/login/login_manager_test.h", - "../browser/chromeos/login/login_ui_browsertest.cc", - "../browser/chromeos/login/login_ui_hide_supervised_users_browsertest.cc", - "../browser/chromeos/login/mixin_based_in_process_browser_test.cc", - "../browser/chromeos/login/mixin_based_in_process_browser_test.h", - "../browser/chromeos/login/oobe_browsertest.cc", - "../browser/chromeos/login/oobe_interactive_ui_test.cc", - "../browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric.h", - "../browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric_cpu.cpp", - "../browser/chromeos/login/screenshot_testing/SkImageDiffer.cpp", - "../browser/chromeos/login/screenshot_testing/SkImageDiffer.h", - "../browser/chromeos/login/screenshot_testing/SkPMetric.cpp", - "../browser/chromeos/login/screenshot_testing/SkPMetric.h", - "../browser/chromeos/login/screenshot_testing/SkPMetricUtil_gen.h", - "../browser/chromeos/login/screenshot_testing/login_screen_areas.h", - "../browser/chromeos/login/screenshot_testing/screenshot_tester.cc", - "../browser/chromeos/login/screenshot_testing/screenshot_tester.h", - "../browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.cc", - "../browser/chromeos/login/screenshot_testing/screenshot_testing_mixin.h", - "../browser/chromeos/login/test/https_forwarder.cc", - "../browser/chromeos/login/test/https_forwarder.h", - "../browser/chromeos/login/test/oobe_base_test.cc", - "../browser/chromeos/login/test/oobe_base_test.h", - "../browser/download/notification/download_notification_interactive_uitest.cc", - "../browser/ui/ash/tab_scrubber_browsertest.cc", - "../browser/ui/views/apps/chrome_native_app_window_views_aura_ash_interactive_uitest.cc", - "../browser/ui/views/frame/hosted_app_ash_interactive_ui_test.cc", - "../browser/ui/webui/chromeos/login/oobe_display_chooser_browsertest.cc", - "../browser/ui/window_sizer/window_sizer_ash_uitest.cc", - "//ash/accelerators/accelerator_interactive_uitest_chromeos.cc", - "//ash/app_list/app_list_interactive_uitest.cc", - "//ash/drag_drop/drag_drop_interactive_uitest.cc", - "//ash/wm/native_cursor_manager_ash_interactive_uitest.cc", - "data/chromeos/service_login.html", - ] - if (is_chrome_branded) { - sources += [ - # The screen this test is checking exists in official build only. - "../browser/chromeos/login/sync_consent_interactive_ui_test.cc", - ] - } + deps += [ "//chrome/browser/media/router:test_support" ] sources -= [ "../browser/ui/signin_view_controller_interactive_uitest.cc", # Use only the _chromeos version on Ash / Chrome OS. "base/view_event_test_platform_part_default.cc", ] - deps += [ - "//ash:interactive_ui_test_support", - "//ash/public/interfaces:test_interfaces", - "//chrome/browser/chromeos:test_support", - "//chrome/browser/media/router:test_support", - "//chromeos/dbus:test_support", - "//mojo/core/embedder", - ] - - data += [ - "//chrome/browser/chromeos/login/test/https_forwarder.py", - "//google_apis/test/", - "$root_out_dir/resources/chromeos/", - ] - - data_deps += [ "//ui/keyboard:resources" ] - - if (enable_nacl) { - data_deps += [ - "//components/nacl/loader:nacl_helper", - "//ppapi/native_client:irt", - ] - - if (enable_nacl_nonsfi) { - data_deps += [ "//components/nacl/loader:helper_nonsfi" ] - } - } } else { # ! is_chromeos # Non-ChromeOS notifications tests. sources += [ @@ -5396,6 +5373,8 @@ "../browser/sync/test/integration/search_engines_helper.h", "../browser/sync/test/integration/secondary_account_helper.cc", "../browser/sync/test/integration/secondary_account_helper.h", + "../browser/sync/test/integration/send_tab_to_self_helper.cc", + "../browser/sync/test/integration/send_tab_to_self_helper.h", "../browser/sync/test/integration/session_hierarchy_match_checker.cc", "../browser/sync/test/integration/session_hierarchy_match_checker.h", "../browser/sync/test/integration/sessions_helper.cc", @@ -5501,6 +5480,7 @@ "../browser/sync/test/integration/single_client_preferences_sync_test.cc", "../browser/sync/test/integration/single_client_search_engines_sync_test.cc", "../browser/sync/test/integration/single_client_secondary_account_sync_test.cc", + "../browser/sync/test/integration/single_client_send_tab_to_self_sync_test.cc", "../browser/sync/test/integration/single_client_sessions_sync_test.cc", "../browser/sync/test/integration/single_client_standalone_transport_sync_test.cc", "../browser/sync/test/integration/single_client_themes_sync_test.cc", @@ -5524,6 +5504,7 @@ "../browser/sync/test/integration/two_client_polling_sync_test.cc", "../browser/sync/test/integration/two_client_preferences_sync_test.cc", "../browser/sync/test/integration/two_client_search_engines_sync_test.cc", + "../browser/sync/test/integration/two_client_send_tab_to_self_sync_test.cc", "../browser/sync/test/integration/two_client_sessions_sync_test.cc", "../browser/sync/test/integration/two_client_themes_sync_test.cc", "../browser/sync/test/integration/two_client_typed_urls_sync_test.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java index 379e898f..eb94e7a 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/suggestions/FakeSuggestionsSource.java
@@ -11,7 +11,7 @@ import org.chromium.base.Callback; import org.chromium.base.ObserverList; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.base.test.util.UrlUtils; import org.chromium.chrome.browser.ntp.cards.SuggestionsCategoryInfo; import org.chromium.chrome.browser.ntp.snippets.CategoryInt; @@ -19,6 +19,7 @@ import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.ArrayList; import java.util.Collections; @@ -244,7 +245,7 @@ public void fetchSuggestionImage( final SnippetArticle suggestion, final Callback<Bitmap> callback) { if (mThumbnails.containsKey(suggestion.mIdWithinCategory)) { - ThreadUtils.postOnUiThread( + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> callback.onResult(mThumbnails.get(suggestion.mIdWithinCategory))); } } @@ -253,7 +254,8 @@ public void fetchSuggestionFavicon(final SnippetArticle suggestion, int minimumSizePx, int desiredSizePx, final Callback<Bitmap> callback) { final Bitmap favicon = getFaviconForId(suggestion.mIdWithinCategory); - if (favicon != null) ThreadUtils.postOnUiThread(() -> callback.onResult(favicon)); + if (favicon != null) + PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> callback.onResult(favicon)); } private Bitmap getFaviconForId(String id) {
diff --git a/chrome/test/base/interactive_ui_tests_main.cc b/chrome/test/base/interactive_ui_tests_main.cc index 5e296bb..6774007 100644 --- a/chrome/test/base/interactive_ui_tests_main.cc +++ b/chrome/test/base/interactive_ui_tests_main.cc
@@ -38,29 +38,19 @@ ChromeTestSuite::Initialize(); - // Only allow ui_controls to be used in interactive_ui_tests, since they - // depend on focus and can't be sharded. - ui_controls::EnableUIControls(); - #if defined(OS_CHROMEOS) // Do not InstallUIControlsAura in ChromeOS, it will be installed in // InProcessBrowserTest::PreRunTestOnMainThread(). -#elif defined(USE_AURA) -#if defined(OS_WIN) +#elif defined(OS_WIN) com_initializer_.reset(new base::win::ScopedCOMInitializer()); -#endif - -#if defined(OS_LINUX) -#if defined(USE_OZONE) - NOTIMPLEMENTED(); -#else + ui_controls::InstallUIControlsAura( + aura::test::CreateUIControlsAura(nullptr)); +#elif defined(OS_LINUX) && !defined(USE_OZONE) ui_controls::InstallUIControlsAura( views::test::CreateUIControlsDesktopAura()); -#endif // defined(USE_OZONE) #else - ui_controls::InstallUIControlsAura(aura::test::CreateUIControlsAura(NULL)); -#endif // defined(OS_LINUX) -#endif // defined(USE_AURA) + ui_controls::EnableUIControls(); +#endif } void Shutdown() override {
diff --git a/chrome/test/chromedriver/chrome/chrome_impl.cc b/chrome/test/chromedriver/chrome/chrome_impl.cc index 657f2f2..9fa588f 100644 --- a/chrome/test/chromedriver/chrome/chrome_impl.cc +++ b/chrome/test/chromedriver/chrome/chrome_impl.cc
@@ -319,7 +319,7 @@ if (status.IsError()) return status; - base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1000)); + base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); std::string state; if (!bounds->GetString("windowState", &state)) return Status(kOk);
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index 2ab5348..41d864ab 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -40,6 +40,8 @@ _OS_NEGATIVE_FILTER['linux'] = [ ] _OS_NEGATIVE_FILTER['mac'] = [ + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2663 + 'WindowTest.testSetsThePositionOfTheCurrentWindow', ] _SPECIFIC_OS_REVISION_NEGATIVE_FILTER = {}
diff --git a/chrome/test/data/webui/print_preview/destination_select_test.js b/chrome/test/data/webui/print_preview/destination_select_test.js index c5f7cdd..3048e10 100644 --- a/chrome/test/data/webui/print_preview/destination_select_test.js +++ b/chrome/test/data/webui/print_preview/destination_select_test.js
@@ -14,6 +14,7 @@ KioskModeSelectsFirstPrinter: 'kiosk mode selects first printer', NoPrintersShowsError: 'no printers shows error', UnreachableRecentCloudPrinter: 'unreachable recent cloud printer', + RecentSaveAsPdf: 'recent save as pdf', }; const suiteName = 'DestinationSelectTests'; @@ -59,6 +60,7 @@ print_preview.NativeLayer.setInstance(nativeLayer); const cloudPrintInterface = new print_preview.CloudPrintInterfaceStub(); cloudprint.setCloudPrintInterfaceForTesting(cloudPrintInterface); + print_preview.DestinationStore.AUTO_SELECT_TIMEOUT_ = 0; PolymerTest.clearBody(); page = document.createElement('print-preview-app'); document.body.appendChild(page); @@ -80,9 +82,10 @@ * Checks that a printer is displayed to the user with the name given * by |printerName|. * @param {string} printerName The printer name that should be displayed. + * @param {boolean} disabled Whether the dropdown should be disabled. * @return {!Promise} Promise that resolves when checks are complete. */ - function assertPrinterDisplay(printerName) { + function assertPrinterDisplay(printerName, disabled) { const destinationSettings = page.$$('print-preview-destination-settings'); const destinationSelect = destinationSettings.$.destinationSelect; @@ -91,7 +94,7 @@ // Check that the throbber is hidden and the dropdown is shown. assertTrue(destinationSettings.$$('.throbber-container').hidden); assertFalse(destinationSelect.hidden); - assertFalse(destinationSelect.disabled); + assertEquals(disabled, destinationSelect.disabled); const options = destinationSelect.shadowRoot.querySelectorAll('option'); const selectedOption = @@ -117,7 +120,7 @@ assertEquals('ID1', args.destinationId); assertEquals(print_preview.PrinterType.LOCAL, args.type); assertEquals('ID1', page.destination_.id); - return assertPrinterDisplay('One'); + return assertPrinterDisplay('One', false); }); }); @@ -142,7 +145,7 @@ assertEquals('ID1', args.destinationId); assertEquals(print_preview.PrinterType.LOCAL, args.type); assertEquals('ID1', page.destination_.id); - return assertPrinterDisplay('One'); + return assertPrinterDisplay('One', false); }) .then(function() { // Verify the correct printers are marked as recent in the store. @@ -213,7 +216,7 @@ assertEquals('ID4', args.destinationId); assertEquals(print_preview.PrinterType.LOCAL, args.type); assertEquals('ID4', page.destination_.id); - return assertPrinterDisplay('Four'); + return assertPrinterDisplay('Four', false); }); }); @@ -247,7 +250,7 @@ // Need to load FooDevice as the printer, since it is the system // default. assertEquals('FooDevice', page.destination_.id); - assertPrinterDisplay('FooName'); + assertPrinterDisplay('FooName', false); }); }); @@ -268,7 +271,7 @@ assertEquals(destinations[0].id, args.destinationId); assertEquals(print_preview.PrinterType.LOCAL, args.type); assertEquals(destinations[0].id, page.destination_.id); - return assertPrinterDisplay(destinations[0].displayName); + return assertPrinterDisplay(destinations[0].displayName, false); }); }); @@ -324,9 +327,38 @@ assertEquals('FooDevice', args.destinationId); assertEquals(print_preview.PrinterType.LOCAL, args.type); assertEquals('FooDevice', page.destination_.id); - return assertPrinterDisplay('FooName'); + return assertPrinterDisplay('FooName', false); }); }); + + /** + * Tests that if the user has a recent destination that is already in the + * store (PDF printer), the DestinationStore does not try to select a + * printer again later. Regression test for https://crbug.com/927162. + */ + test(assert(TestNames.RecentSaveAsPdf), function() { + const pdfPrinter = print_preview_test_utils.getSaveAsPdfDestination(); + const recentDestination = print_preview.makeRecentDestination(pdfPrinter); + initialSettings.serializedAppStateStr = JSON.stringify({ + version: 2, + recentDestinations: [recentDestination], + }); + + return setInitialSettings() + .then(function() { + assertEquals(print_preview_new.State.READY, page.state); + assertPrinterDisplay('Save as PDF', false); + // Simulate setting a bad ticket value. + page.$.state.transitTo(print_preview_new.State.INVALID_TICKET); + return new Promise(resolve => setTimeout(resolve)); + }) + .then(function() { + // Should still have Save as PDF. Dropdown is disabled due to + // invalid ticket. + assertPrinterDisplay('Save as PDF', true); + assertEquals(print_preview_new.State.INVALID_TICKET, page.state); + }); + }); }); return {
diff --git a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js index ef78621..3605c28 100644 --- a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js +++ b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js
@@ -662,6 +662,10 @@ destination_select_test.TestNames.UnreachableRecentCloudPrinter); }); +TEST_F('PrintPreviewDestinationSelectTest', 'RecentSaveAsPdf', function() { + this.runMochaTest(destination_select_test.TestNames.RecentSaveAsPdf); +}); + PrintPreviewDestinationDialogTest = class extends NewPrintPreviewTest { /** @override */ get browsePreload() {
diff --git a/chrome/test/data/webui/settings/bluetooth_page_tests.js b/chrome/test/data/webui/settings/bluetooth_page_tests.js index a6fcd05..2672009 100644 --- a/chrome/test/data/webui/settings/bluetooth_page_tests.js +++ b/chrome/test/data/webui/settings/bluetooth_page_tests.js
@@ -27,30 +27,37 @@ /** @type {BluetoothPrivate} */ let bluetoothPrivateApi_; - /** @type {!Array<!chrome.bluetooth.Device>} */ const fakeDevices_ = [ - { - address: '10:00:00:00:00:01', - name: 'FakePairedDevice1', - paired: true, - connected: true, - }, - { - address: '10:00:00:00:00:02', - name: 'FakePairedDevice2', - paired: true, - connected: false, - }, - { - address: '00:00:00:00:00:01', - name: 'FakeUnpairedDevice1', - paired: false, - }, - { - address: '00:00:00:00:00:02', - name: 'FakeUnpairedDevice2', - paired: false, - }, - ]; + /** @type {!chrome.bluetooth.Device} */ + let fakeUnpairedDevice1 = { + address: '00:00:00:00:00:01', + name: 'FakeUnpairedDevice1', + paired: false, + connected: false, + }; + + /** @type {!chrome.bluetooth.Device} */ + let fakeUnpairedDevice2 = { + address: '00:00:00:00:00:02', + name: 'FakeUnpairedDevice2', + paired: false, + connected: false, + }; + + /** @type {!chrome.bluetooth.Device} */ + let fakePairedDevice1 = { + address: '10:00:00:00:00:01', + name: 'FakePairedDevice1', + paired: true, + connected: true, + }; + + /** @type {!chrome.bluetooth.Device} */ + let fakePairedDevice2 = { + address: '10:00:00:00:00:02', + name: 'FakePairedDevice2', + paired: true, + connected: false, + }; suiteSetup(function() { loadTimeData.overrideValues({ @@ -148,57 +155,11 @@ }); } - test('paired device list', async function() { - const pairedContainer = subpage.$.pairedContainer; - assertTrue(!!pairedContainer); - assertTrue(pairedContainer.hidden); - assertFalse(subpage.$.noPairedDevices.hidden); - - bluetoothApi_.setDevicesForTest(fakeDevices_); - - await waitForListUpdateTimeout(); - - Polymer.dom.flush(); - assertEquals(4, subpage.deviceList_.length); - assertEquals(2, subpage.pairedDeviceList_.length); - assertTrue(subpage.$.noPairedDevices.hidden); - - const ironList = subpage.$.pairedDevices; - assertTrue(!!ironList); - ironList.notifyResize(); - Polymer.dom.flush(); - const devices = ironList.querySelectorAll('bluetooth-device-list-item'); - assertEquals(2, devices.length); - assertTrue(devices[0].device.connected); - assertFalse(devices[1].device.connected); - }); - - test('unpaired device list', async function() { - const unpairedContainer = subpage.$.unpairedContainer; - assertTrue(!!unpairedContainer); - assertTrue(unpairedContainer.hidden); - assertFalse(subpage.$.noUnpairedDevices.hidden); - - bluetoothApi_.setDevicesForTest(fakeDevices_); - await waitForListUpdateTimeout(); - - Polymer.dom.flush(); - assertEquals(4, subpage.deviceList_.length); - assertEquals(2, subpage.unpairedDeviceList_.length); - assertTrue(subpage.$.noUnpairedDevices.hidden); - - const ironList = subpage.$.unpairedDevices; - assertTrue(!!ironList); - ironList.notifyResize(); - Polymer.dom.flush(); - const devices = ironList.querySelectorAll('bluetooth-device-list-item'); - assertEquals(2, devices.length); - assertFalse(devices[0].device.paired); - assertFalse(devices[1].device.paired); - }); - test('pair device', async function() { - bluetoothApi_.setDevicesForTest(fakeDevices_); + bluetoothApi_.setDevicesForTest([ + fakeUnpairedDevice1, fakeUnpairedDevice2, fakePairedDevice1, + fakePairedDevice2 + ]); await waitForListUpdateTimeout(); Polymer.dom.flush(); @@ -216,7 +177,10 @@ }); test('pair dialog', async function() { - bluetoothApi_.setDevicesForTest(fakeDevices_); + bluetoothApi_.setDevicesForTest([ + fakeUnpairedDevice1, fakeUnpairedDevice2, fakePairedDevice1, + fakePairedDevice2 + ]); await waitForListUpdateTimeout(); Polymer.dom.flush(); @@ -230,5 +194,117 @@ assertTrue(dialog.$.dialog.open); }); + suite('Device List', function() { + function deviceList() { + return subpage.deviceList_; + } + + function unpairedDeviceList() { + return subpage.unpairedDeviceList_; + } + + function pairedDeviceList() { + return subpage.pairedDeviceList_; + } + + let unpairedContainer; + let unpairedDeviceIronList; + + let pairedContainer; + let pairedDeviceIronList; + + setup(function() { + unpairedContainer = subpage.$.unpairedContainer; + assertTrue(!!unpairedContainer); + assertTrue(unpairedContainer.hidden); + unpairedDeviceIronList = subpage.$.unpairedDevices; + assertTrue(!!unpairedDeviceIronList); + + pairedContainer = subpage.$.pairedContainer; + assertTrue(!!pairedContainer); + assertTrue(pairedContainer.hidden); + pairedDeviceIronList = subpage.$.pairedDevices; + assertTrue(!!pairedDeviceIronList); + }); + + test('Unpaired devices: devices added', async function() { + bluetoothApi_.setDevicesForTest( + [fakeUnpairedDevice1, fakeUnpairedDevice2]); + await waitForListUpdateTimeout(); + Polymer.dom.flush(); + + assertEquals(2, deviceList().length); + assertEquals(2, unpairedDeviceList().length); + assertEquals(0, pairedDeviceList().length); + assertTrue(subpage.$.noUnpairedDevices.hidden); + assertFalse(subpage.$.noPairedDevices.hidden); + + unpairedDeviceIronList.notifyResize(); + Polymer.dom.flush(); + + const devices = unpairedDeviceIronList.querySelectorAll( + 'bluetooth-device-list-item'); + assertEquals(2, devices.length); + assertFalse(devices[0].device.paired); + assertFalse(devices[1].device.paired); + }); + + test('Paired devices: devices added', async function() { + bluetoothApi_.setDevicesForTest([fakePairedDevice1, fakePairedDevice2]); + await waitForListUpdateTimeout(); + Polymer.dom.flush(); + + assertEquals(2, deviceList().length); + assertEquals(0, unpairedDeviceList().length); + assertEquals(2, pairedDeviceList().length); + assertFalse(subpage.$.noUnpairedDevices.hidden); + assertTrue(subpage.$.noPairedDevices.hidden); + + pairedDeviceIronList.notifyResize(); + Polymer.dom.flush(); + + const devices = + pairedDeviceIronList.querySelectorAll('bluetooth-device-list-item'); + assertEquals(2, devices.length); + assertTrue(devices[0].device.paired); + assertTrue(devices[0].device.connected); + assertTrue(devices[1].device.paired); + assertFalse(devices[1].device.connected); + }); + + test('Unpaired and paired devices: devices added', async function() { + bluetoothApi_.setDevicesForTest([ + fakeUnpairedDevice1, fakeUnpairedDevice2, fakePairedDevice1, + fakePairedDevice2 + ]); + + await waitForListUpdateTimeout(); + Polymer.dom.flush(); + + assertEquals(4, deviceList().length); + assertEquals(2, unpairedDeviceList().length); + assertEquals(2, pairedDeviceList().length); + assertTrue(subpage.$.noUnpairedDevices.hidden); + assertTrue(subpage.$.noPairedDevices.hidden); + + pairedDeviceIronList.notifyResize(); + unpairedDeviceIronList.notifyResize(); + Polymer.dom.flush(); + + const unpairedDevices = unpairedDeviceIronList.querySelectorAll( + 'bluetooth-device-list-item'); + assertEquals(2, unpairedDevices.length); + assertFalse(unpairedDevices[0].device.paired); + assertFalse(unpairedDevices[1].device.paired); + + const pairedDevices = + pairedDeviceIronList.querySelectorAll('bluetooth-device-list-item'); + assertEquals(2, pairedDevices.length); + assertTrue(pairedDevices[0].device.paired); + assertTrue(pairedDevices[0].device.connected); + assertTrue(pairedDevices[1].device.paired); + assertFalse(pairedDevices[1].device.connected); + }); + }); }); });
diff --git a/components/arc/metrics/arc_metrics_service.cc b/components/arc/metrics/arc_metrics_service.cc index 68eae7da..f89c196 100644 --- a/components/arc/metrics/arc_metrics_service.cc +++ b/components/arc/metrics/arc_metrics_service.cc
@@ -279,7 +279,18 @@ return; } - // Retrieve ARC start time from session manager. + if (IsArcVmEnabled()) { + // For VM builds, do not call into session_manager since we don't use it + // for the builds. Using base::TimeTicks() is fine for now because 1) the + // clocks in host and guest are not synchronized, and 2) the guest does not + // support mini container. + // TODO(yusukes): Once the guest supports mini container (details TBD), we + // should have the guest itself report the timing of the upgrade. + OnArcStartTimeRetrieved(std::move(events), boot_type, base::TimeTicks()); + return; + } + + // Retrieve ARC full container's start time from session manager. chromeos::SessionManagerClient* session_manager_client = chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); session_manager_client->GetArcStartTime(base::BindOnce(
diff --git a/components/browser_sync/DEPS b/components/browser_sync/DEPS index 6dcdc6d..83aedd9 100644 --- a/components/browser_sync/DEPS +++ b/components/browser_sync/DEPS
@@ -10,6 +10,7 @@ "+components/pref_registry", "+components/prefs", "+components/reading_list/features", + "+components/send_tab_to_self", "+components/signin/core/browser", # Use identity_manager.h instead of the below files; # see https://groups.google.com/a/chromium.org/d/msg/chromium-dev/dgFLuxqZt1o/iEqkyoQQBwAJ for help and info.
diff --git a/components/cdm/browser/media_drm_storage_impl.cc b/components/cdm/browser/media_drm_storage_impl.cc index 366614b..3c5ffe3 100644 --- a/components/cdm/browser/media_drm_storage_impl.cc +++ b/components/cdm/browser/media_drm_storage_impl.cc
@@ -4,16 +4,22 @@ #include "components/cdm/browser/media_drm_storage_impl.h" +#include <map> #include <memory> +#include <tuple> #include "base/bind.h" #include "base/logging.h" +#include "base/no_destructor.h" +#include "base/strings/string_util.h" #include "base/value_conversions.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" #include "content/public/browser/navigation_handle.h" #include "media/base/android/media_drm_key_type.h" +#include "url/origin.h" +#include "url/url_constants.h" // The storage will be managed by PrefService. All data will be stored in a // dictionary under the key "media.media_drm_storage". The dictionary is @@ -428,6 +434,116 @@ return origin_data->origin_id(); } +// Map shared by all MediaDrmStorageImpl objects to prevent multiple Origin IDs +// being allocated for the same origin. Initialize() can be called multiple +// times for the same web origin (and profile). This class groups together +// requests for the same web origin (and profile), calling |get_origin_id_cb| +// only on the first request. This avoids a race condition where simultaneous +// requests could result in different Origin IDs allocated for the same origin +// (and only the last one saved in the preference). +class InitializationSerializer { + public: + // Origin IDs are unique per preference service and origin. + struct PreferenceAndOriginKey { + // Allow use as a key in std::map. + bool operator<(const PreferenceAndOriginKey& other) const { + return std::tie(pref_service, origin) < + std::tie(other.pref_service, other.origin); + } + + PrefService* pref_service; + const url::Origin origin; + }; + + // The InitializationSerializer is a global map shared by all + // MediaDrmStorageImpl instances. + static InitializationSerializer& GetInstance() { + static base::NoDestructor<InitializationSerializer> + s_origin_id_request_impl; + return *s_origin_id_request_impl; + } + + InitializationSerializer() = default; + ~InitializationSerializer() = default; + + void FetchOriginId( + PrefService* pref_service, + const url::Origin& origin, + MediaDrmStorageImpl::GetOriginIdCB get_origin_id_cb, + MediaDrmStorageImpl::OriginIdObtainedCB origin_id_obtained_cb) { + DVLOG(3) << __func__ << " origin: " << origin; + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // Check if the preference has an existing origin ID. + const base::DictionaryValue* storage_dict = + pref_service->GetDictionary(kMediaDrmStorage); + base::UnguessableToken origin_id = + GetOriginIdForOrigin(storage_dict, origin); + if (origin_id) { + std::move(origin_id_obtained_cb).Run(origin_id); + return; + } + + // No origin ID found, so check if another Initialize() call is in progress. + PreferenceAndOriginKey key{pref_service, origin}; + auto entry = pending_requests_.find(key); + if (entry != pending_requests_.end()) { + // Entry already exists, so simply add |origin_id_obtained_cb| to be + // called once the Origin ID is obtained. + entry->second.emplace_back(std::move(origin_id_obtained_cb)); + return; + } + + // Entry does not exist, so create a new one. + std::vector<MediaDrmStorageImpl::OriginIdObtainedCB> + origin_id_obtained_cb_list; + origin_id_obtained_cb_list.emplace_back(std::move(origin_id_obtained_cb)); + pending_requests_.emplace(key, std::move(origin_id_obtained_cb_list)); + + // Now call |get_origin_id_cb|. It will call OnOriginIdObtained() when done, + // which will call all the callbacks saved for this preference and origin + // pair. Use of base::Unretained() is valid as |this| is a singleton stored + // in a static variable. + get_origin_id_cb.Run( + base::BindOnce(&InitializationSerializer::OnOriginIdObtained, + base::Unretained(this), pref_service, origin)); + } + + private: + void OnOriginIdObtained(PrefService* pref_service, + const url::Origin& origin, + const base::UnguessableToken& origin_id) { + DVLOG(3) << __func__ << " origin: " << origin; + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // Save the origin ID in the preference as long as it is not null. + if (origin_id) { + DictionaryPrefUpdate update(pref_service, kMediaDrmStorage); + CreateOriginDictAndReturnSessionsDict(update.Get(), origin, origin_id); + } + + // Now call any callbacks waiting for this origin ID to be allocated. + auto entry = pending_requests_.find({pref_service, origin}); + DCHECK(entry != pending_requests_.end()); + + std::vector<MediaDrmStorageImpl::OriginIdObtainedCB> callbacks; + callbacks.swap(entry->second); + pending_requests_.erase(entry); + + for (auto& callback : callbacks) + std::move(callback).Run(origin_id); + } + + // Note that this map is never deleted. As entries are removed when an origin + // ID is allocated, so it should never get too large. + std::map<PreferenceAndOriginKey, + std::vector<MediaDrmStorageImpl::OriginIdObtainedCB>> + pending_requests_; + + THREAD_CHECKER(thread_checker_); + DISALLOW_COPY_AND_ASSIGN(InitializationSerializer); +}; + } // namespace // static @@ -548,55 +664,28 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(!init_cb_); - if (IsInitialized()) { + if (is_initialized_) { std::move(callback).Run(origin_id_); return; } DCHECK(!origin_id_); - // Check if the preference has an existing origin ID. - const base::DictionaryValue* storage_dict = - pref_service_->GetDictionary(kMediaDrmStorage); - origin_id_ = GetOriginIdForOrigin(storage_dict, origin()); - if (origin_id_) { - std::move(callback).Run(origin_id_); - return; - } - - // No origin ID, so fetch one asynchronously. OnOriginIdObtained() is called - // to finish initialization. + // Call using SerializeInitializeRequests() to handle the case where + // Initialize() is called concurrently for the same origin (and preference + // service). Note that if there is already an existing origin ID for this web + // origin saved in the preference, OnOriginIdObtained() will be called + // immediately. init_cb_ = std::move(callback); - get_origin_id_cb_.Run(base::BindOnce(&MediaDrmStorageImpl::OnOriginIdObtained, - weak_factory_.GetWeakPtr())); + InitializationSerializer::GetInstance().FetchOriginId( + pref_service_, origin(), get_origin_id_cb_, + base::BindOnce(&MediaDrmStorageImpl::OnOriginIdObtained, + weak_factory_.GetWeakPtr())); } void MediaDrmStorageImpl::OnOriginIdObtained( const base::UnguessableToken& origin_id) { - // If multiple MediaDrmStorage instances from the same web origin call - // Initialize concurrently, then a previous instance may have successfully - // obtained an origin ID and stored it for this origin. So check again to see - // if an origin ID has been saved, and use it instead of |origin_id|. This - // does mean that |origin_id| will be lost. - // TODO(crbug.com/919228): Once pre-provisioned origins are used, |origin_id| - // needs to be unprovisioned rather than dropped. - DictionaryPrefUpdate update(pref_service_, kMediaDrmStorage); - auto stored_origin_id = GetOriginIdForOrigin(update.Get(), origin()); - if (stored_origin_id) { - origin_id_ = stored_origin_id; - std::move(init_cb_).Run(origin_id_); - return; - } - - // As there is no current value, persist the origin ID into storage now. - // TODO(crbug.com/917527): When pre-provisioned origins are supported, there - // may not be any available, so an empty origin ID can be used temporarily. - // The empty origin ID should not be saved in the preference, but should be - // returned. Note that having |origin_id_| set is used to determine if this - // object is initialized or not, so temporarily using an empty origin ID will - // affect that, and that needs to be fixed too. - DCHECK(origin_id) << "Empty origin ID not handled."; + is_initialized_ = true; origin_id_ = origin_id; - CreateOriginDictAndReturnSessionsDict(update.Get(), origin(), origin_id_); std::move(init_cb_).Run(origin_id_); } @@ -604,12 +693,19 @@ DVLOG(1) << __func__; DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!IsInitialized()) { + if (!is_initialized_) { DVLOG(1) << __func__ << ": Not initialized."; std::move(callback).Run(false); return; } + // If this is using an empty origin ID, it should not be provisioned. + if (!origin_id_) { + DVLOG(1) << __func__ << ": Empty origin ID."; + std::move(callback).Run(false); + return; + } + DictionaryPrefUpdate update(pref_service_, kMediaDrmStorage); base::DictionaryValue* storage_dict = update.Get(); DCHECK(storage_dict); @@ -628,12 +724,19 @@ DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!IsInitialized()) { + if (!is_initialized_) { DVLOG(1) << __func__ << ": Not initialized."; std::move(callback).Run(false); return; } + // If this is using an empty origin ID, it cannot save persistent data. + if (!origin_id_) { + DVLOG(1) << __func__ << ": Empty origin ID."; + std::move(callback).Run(false); + return; + } + DictionaryPrefUpdate update(pref_service_, kMediaDrmStorage); base::DictionaryValue* storage_dict = update.Get(); DCHECK(storage_dict); @@ -674,12 +777,19 @@ DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!IsInitialized()) { + if (!is_initialized_) { DVLOG(1) << __func__ << ": Not initialized."; std::move(callback).Run(nullptr); return; } + // If this is using an empty origin ID, it cannot save persistent data. + if (!origin_id_) { + DVLOG(1) << __func__ << ": Empty origin ID."; + std::move(callback).Run(nullptr); + return; + } + const base::Value* sessions_dict = GetSessionsDictFromStorageDict<const base::Value>( pref_service_->GetDictionary(kMediaDrmStorage), origin().Serialize()); @@ -714,12 +824,19 @@ DVLOG(2) << __func__; DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!IsInitialized()) { + if (!is_initialized_) { DVLOG(1) << __func__ << ": Not initialized."; std::move(callback).Run(false); return; } + // If this is using an empty origin ID, it cannot save persistent data. + if (!origin_id_) { + DVLOG(1) << __func__ << ": Empty origin ID."; + std::move(callback).Run(false); + return; + } + DictionaryPrefUpdate update(pref_service_, kMediaDrmStorage); base::Value* sessions_dict = GetSessionsDictFromStorageDict<base::Value>(
diff --git a/components/cdm/browser/media_drm_storage_impl.h b/components/cdm/browser/media_drm_storage_impl.h index 4ca4ae1..e4a97f7e 100644 --- a/components/cdm/browser/media_drm_storage_impl.h +++ b/components/cdm/browser/media_drm_storage_impl.h
@@ -6,6 +6,7 @@ #define COMPONENTS_CDM_BROWSER_MEDIA_DRM_STORAGE_IMPL_H_ #include <set> +#include <string> #include <vector> #include "base/callback.h" @@ -36,8 +37,9 @@ class MediaDrmStorageImpl final : public content::FrameServiceBase<media::mojom::MediaDrmStorage> { public: - using GetOriginIdCB = base::RepeatingCallback<void( - base::OnceCallback<void(const base::UnguessableToken&)>)>; + using OriginIdObtainedCB = + base::OnceCallback<void(const base::UnguessableToken&)>; + using GetOriginIdCB = base::RepeatingCallback<void(OriginIdObtainedCB)>; static void RegisterProfilePrefs(PrefRegistrySimple* registry); @@ -79,8 +81,6 @@ void RemovePersistentSession(const std::string& session_id, RemovePersistentSessionCallback callback) final; - bool IsInitialized() const { return !!origin_id_; } - private: // |this| can only be destructed as a FrameServiceBase. ~MediaDrmStorageImpl() final; @@ -89,7 +89,7 @@ // of Initialize(); void OnOriginIdObtained(const base::UnguessableToken& origin_id); - PrefService* const pref_service_ = nullptr; + PrefService* const pref_service_; GetOriginIdCB get_origin_id_cb_; // ID for the current origin. Per EME spec on individualization, @@ -100,6 +100,9 @@ // necessary. InitializeCallback init_cb_; + // Set when initialized. + bool is_initialized_ = false; + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory<MediaDrmStorageImpl> weak_factory_; };
diff --git a/components/gwp_asan/BUILD.gn b/components/gwp_asan/BUILD.gn index 48db66c..5176c8c 100644 --- a/components/gwp_asan/BUILD.gn +++ b/components/gwp_asan/BUILD.gn
@@ -7,7 +7,7 @@ deps = [ "//components/gwp_asan/common:unit_tests", ] - if (is_win) { + if (is_win || is_mac) { deps += [ "//components/gwp_asan/client:unit_tests", "//components/gwp_asan/crash_handler:unit_tests",
diff --git a/components/gwp_asan/client/guarded_page_allocator.cc b/components/gwp_asan/client/guarded_page_allocator.cc index 798583809..a50d076 100644 --- a/components/gwp_asan/client/guarded_page_allocator.cc +++ b/components/gwp_asan/client/guarded_page_allocator.cc
@@ -17,6 +17,7 @@ #include "components/crash/core/common/crash_key.h" #include "components/gwp_asan/common/allocator_state.h" #include "components/gwp_asan/common/crash_key_name.h" +#include "components/gwp_asan/common/pack_stack_trace.h" namespace gwp_asan { namespace internal { @@ -174,10 +175,13 @@ slots_[slot].alloc_size = size; slots_[slot].alloc_ptr = reinterpret_cast<uintptr_t>(ptr); + void* trace[AllocatorState::kMaxStackFrames]; + size_t len = + base::debug::CollectStackTrace(trace, AllocatorState::kMaxStackFrames); + slots_[slot].alloc.trace_len = Pack(reinterpret_cast<uintptr_t*>(trace), len, + slots_[slot].alloc.packed_trace, + sizeof(slots_[slot].alloc.packed_trace)); slots_[slot].alloc.tid = base::PlatformThread::CurrentId(); - slots_[slot].alloc.trace_len = base::debug::CollectStackTrace( - reinterpret_cast<void**>(&slots_[slot].alloc.trace), - AllocatorState::kMaxStackFrames); slots_[slot].alloc.trace_collected = true; slots_[slot].dealloc.tid = base::kInvalidThreadId; @@ -187,10 +191,14 @@ } void GuardedPageAllocator::RecordDeallocationInSlot(size_t slot) { + void* trace[AllocatorState::kMaxStackFrames]; + size_t len = + base::debug::CollectStackTrace(trace, AllocatorState::kMaxStackFrames); + slots_[slot].dealloc.trace_len = + Pack(reinterpret_cast<uintptr_t*>(trace), len, + slots_[slot].dealloc.packed_trace, + sizeof(slots_[slot].dealloc.packed_trace)); slots_[slot].dealloc.tid = base::PlatformThread::CurrentId(); - slots_[slot].dealloc.trace_len = base::debug::CollectStackTrace( - reinterpret_cast<void**>(&slots_[slot].dealloc.trace), - AllocatorState::kMaxStackFrames); slots_[slot].dealloc.trace_collected = true; }
diff --git a/components/gwp_asan/client/sampling_allocator_shims.cc b/components/gwp_asan/client/sampling_allocator_shims.cc index 07c59be..c02bab6b 100644 --- a/components/gwp_asan/client/sampling_allocator_shims.cc +++ b/components/gwp_asan/client/sampling_allocator_shims.cc
@@ -18,10 +18,7 @@ #include "components/gwp_asan/client/guarded_page_allocator.h" #if defined(OS_MACOSX) -// TODO(https://crbug.com/829078): thread_local is not currently supported on -// macOS; however, it works correctly on other platforms and is noticeably -// faster. -#error "macOS does not support thread_local" +#include <pthread.h> #endif namespace gwp_asan { @@ -40,6 +37,10 @@ void Init(size_t sampling_frequency) { DCHECK_GT(sampling_frequency, 0U); sampling_frequency_ = sampling_frequency; + +#if defined(OS_MACOSX) + pthread_key_create(&tls_key_, nullptr); +#endif } // Return true if this allocation should be sampled. @@ -50,12 +51,11 @@ // // Instead, use zero to mean 'get a new counter value' and one to mean // that this allocation should be sampled. - static thread_local size_t tls_counter = 0; - size_t samples_left = tls_counter; + size_t samples_left = GetCounter(); if (UNLIKELY(!samples_left)) samples_left = NextSample(); - tls_counter = samples_left - 1; + SetCounter(samples_left - 1); return (samples_left == 1); } @@ -72,6 +72,26 @@ return next_sample; } +#if !defined(OS_MACOSX) + ALWAYS_INLINE size_t GetCounter() { return tls_counter_; } + ALWAYS_INLINE void SetCounter(size_t value) { tls_counter_ = value; } + + static thread_local size_t tls_counter_; +#else + // On macOS, the first use of a thread_local variable on a new thread will + // cause a malloc(), causing infinite recursion. Instead, use pthread TLS to + // store the counter. + ALWAYS_INLINE size_t GetCounter() { + return reinterpret_cast<size_t>(pthread_getspecific(tls_key_)); + } + + ALWAYS_INLINE void SetCounter(size_t value) { + pthread_setspecific(tls_key_, reinterpret_cast<void*>(value)); + } + + pthread_key_t tls_key_ = 0; +#endif + size_t sampling_frequency_ = 0; // Stores the number of allocations we need to skip to reach the end of the @@ -79,6 +99,10 @@ size_t increment_ = 0; }; +#if !defined(OS_MACOSX) +thread_local size_t SamplingState::tls_counter_ = 0; +#endif + // By being implemented as a global with inline method definitions, method calls // and member acceses are inlined and as efficient as possible in the // performance-sensitive allocation hot-path.
diff --git a/components/gwp_asan/common/allocator_state.cc b/components/gwp_asan/common/allocator_state.cc index ccd2a7d..8aa839f 100644 --- a/components/gwp_asan/common/allocator_state.cc +++ b/components/gwp_asan/common/allocator_state.cc
@@ -15,6 +15,7 @@ // TODO: Delete out-of-line constexpr defininitons once C++17 is in use. constexpr size_t AllocatorState::kGpaMaxPages; constexpr size_t AllocatorState::kMaxStackFrames; +constexpr size_t AllocatorState::kMaxPackedTraceLength; AllocatorState::AllocatorState() {}
diff --git a/components/gwp_asan/common/allocator_state.h b/components/gwp_asan/common/allocator_state.h index a7ff46ed..2f1f88b 100644 --- a/components/gwp_asan/common/allocator_state.h +++ b/components/gwp_asan/common/allocator_state.h
@@ -37,9 +37,12 @@ class AllocatorState { public: // Maximum number of pages this class can allocate. - static constexpr size_t kGpaMaxPages = 128; + static constexpr size_t kGpaMaxPages = 256; // Maximum number of stack trace frames to collect. static constexpr size_t kMaxStackFrames = 60; + // Number of bytes to allocate for packed stack traces. This can hold + // approximately kMaxStackFrames under normal conditions. + static constexpr size_t kMaxPackedTraceLength = 200; enum class ErrorType { kUseAfterFree = 0, @@ -65,9 +68,9 @@ // (De)allocation thread id or base::kInvalidThreadId if no (de)allocation // occurred. base::PlatformThreadId tid = base::kInvalidThreadId; - // Stack trace contents. - uintptr_t trace[kMaxStackFrames]; - // Stack trace length. + // Packed stack trace. + uint8_t packed_trace[kMaxPackedTraceLength]; + // Length used to encode the packed stack trace. size_t trace_len = 0; // Whether a stack trace has been collected for this (de)allocation. bool trace_collected = false;
diff --git a/components/gwp_asan/crash_handler/crash_analyzer.cc b/components/gwp_asan/crash_handler/crash_analyzer.cc index 04e70d1..95f1223 100644 --- a/components/gwp_asan/crash_handler/crash_analyzer.cc +++ b/components/gwp_asan/crash_handler/crash_analyzer.cc
@@ -14,6 +14,7 @@ #include "build/build_config.h" #include "components/gwp_asan/common/allocator_state.h" #include "components/gwp_asan/common/crash_key_name.h" +#include "components/gwp_asan/common/pack_stack_trace.h" #include "components/gwp_asan/crash_handler/crash.pb.h" #include "third_party/crashpad/crashpad/client/annotation.h" #include "third_party/crashpad/crashpad/snapshot/cpu_context.h" @@ -158,12 +159,21 @@ return; } - // On 32-bit platforms we can't copy directly to + uintptr_t unpacked_stack_trace[AllocatorState::kMaxPackedTraceLength]; + size_t unpacked_len = + Unpack(slot_info.packed_trace, slot_info.trace_len, unpacked_stack_trace, + AllocatorState::kMaxPackedTraceLength); + if (!unpacked_len) { + DLOG(ERROR) << "Failed to unpack stack trace."; + return; + } + + // On 32-bit platforms we can't copy directly into // proto_info->mutable_stack_trace()->mutable_data(). - proto_info->mutable_stack_trace()->Resize(slot_info.trace_len, 0); + proto_info->mutable_stack_trace()->Resize(unpacked_len, 0); uint64_t* output = proto_info->mutable_stack_trace()->mutable_data(); - for (size_t i = 0; i < slot_info.trace_len; i++) - output[i] = slot_info.trace[i]; + for (size_t i = 0; i < unpacked_len; i++) + output[i] = unpacked_stack_trace[i]; } } // namespace internal
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc index 3714ba5..9da0bd7 100644 --- a/components/omnibox/browser/autocomplete_match.cc +++ b/components/omnibox/browser/autocomplete_match.cc
@@ -643,6 +643,10 @@ // TODO(orinj): It may make more sense to start from a clean slate and // apply only the bits of state relevant to the Pedal, rather than // eliminating parts of an existing match that are no longer useful. + // But while Pedal suggestions are derived from triggering suggestions by + // copy, it is necessary to be careful that we don't inherit fields that + // might cause issues. + allowed_to_be_default_match = false; type = Type::PEDAL; destination_url = pedal->GetNavigationUrl();
diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc index 1eb96847..1da1333 100644 --- a/components/omnibox/browser/autocomplete_result.cc +++ b/components/omnibox/browser/autocomplete_result.cc
@@ -236,18 +236,48 @@ void AutocompleteResult::AppendDedicatedPedalMatches( AutocompleteProviderClient* client, const AutocompleteInput& input) { - ACMatches pedal_suggestions; const OmniboxPedalProvider* provider = client->GetPedalProvider(); + ACMatches pedal_suggestions; + // Map from Pedal to a vector and index so that we can update instead of + // adding a duplicate. Existing Pedals are fully indexed before the next + // loop that adds|updates because, e.g. the first match may trigger a Pedal + // which is already applied on the last. We should update it, but without the + // fully built index the below logic would add new, resulting in a duplicate. + std::unordered_map<OmniboxPedal*, std::pair<ACMatches&, size_t>> pedals_found; + for (size_t match_index = 0; match_index < matches_.size(); ++match_index) { + OmniboxPedal* const pedal = matches_[match_index].pedal; + if (pedal) { + const auto insertion = + pedals_found.insert({pedal, {matches_, match_index}}); + DCHECK(insertion.second) << "Found existing duplicate Pedal suggestion."; + } + } for (const auto& match : matches_) { if (match.pedal) continue; - OmniboxPedal* pedal = provider->FindPedalMatch(match.contents); + OmniboxPedal* const pedal = provider->FindPedalMatch(match.contents); if (pedal) { - AutocompleteMatch suggestion = match; - suggestion.relevance--; - suggestion.pedal = pedal; - suggestion.ApplyPedal(); - pedal_suggestions.push_back(suggestion); + auto derive_pedal_suggestion = [&match, pedal]() { + AutocompleteMatch suggestion = match; + suggestion.relevance--; + suggestion.pedal = pedal; + suggestion.ApplyPedal(); + return suggestion; + }; + const auto insertion = pedals_found.insert( + {pedal, {pedal_suggestions, pedal_suggestions.size()}}); + if (insertion.second) { + // This is the first use of the found pedal; add new suggestion. + pedal_suggestions.push_back(derive_pedal_suggestion()); + } else { + // This is a subsequent use of the found pedal; update its suggestion to + // ensure that it is derived from the most relevant matching suggestion. + const auto& map_value_pair = insertion.first->second; + auto& suggestion = map_value_pair.first[map_value_pair.second]; + if (suggestion.relevance < match.relevance - 1) { + suggestion = derive_pedal_suggestion(); + } + } } } if (!pedal_suggestions.empty()) {
diff --git a/components/omnibox/browser/autocomplete_result.h b/components/omnibox/browser/autocomplete_result.h index 746cbee7..747b278 100644 --- a/components/omnibox/browser/autocomplete_result.h +++ b/components/omnibox/browser/autocomplete_result.h
@@ -55,7 +55,9 @@ void SortAndCull(const AutocompleteInput& input, TemplateURLService* template_url_service); - // Creates and adds any dedicated Pedal matches triggered by existing match. + // Creates and adds any dedicated Pedal matches triggered by existing matches. + // This should be the only place where new Pedal suggestions are introduced + // because it doesn't dedupe; it just carefully avoids adding duplicates. void AppendDedicatedPedalMatches(AutocompleteProviderClient* client, const AutocompleteInput& input);
diff --git a/components/omnibox/browser/autocomplete_result_unittest.cc b/components/omnibox/browser/autocomplete_result_unittest.cc index 734366aa..2c73f6c 100644 --- a/components/omnibox/browser/autocomplete_result_unittest.cc +++ b/components/omnibox/browser/autocomplete_result_unittest.cc
@@ -85,7 +85,7 @@ public: struct TestData { // Used to build a url for the AutocompleteMatch. The URL becomes - // "http://" + ('a' + |url_id|) (e.g. an ID of 2 yields "http://b"). + // "http://" + ('a' + |url_id|) (e.g. an ID of 2 yields "http://c"). int url_id; // ID of the provider. @@ -1161,3 +1161,79 @@ OmniboxEventProto::HOME_PAGE)); CheckRelevanceExpectations(first, second, 1000, 600, "", ""); } + +TEST_F(AutocompleteResultTest, PedalSuggestionsCantBeDefaultMatch) { + TestData data[] = { + {1, 1, 500, true}, + {0, 1, 1100, true}, + }; + + ACMatches matches; + PopulateAutocompleteMatches(data, base::size(data), &matches); + matches[0].contents = base::UTF8ToUTF16("clear chrome history"); + matches[1].contents = base::UTF8ToUTF16("open incognito tab"); + + AutocompleteInput input(base::ASCIIToUTF16("a"), + metrics::OmniboxEventProto::OTHER, + TestSchemeClassifier()); + AutocompleteResult result; + result.AppendMatches(input, matches); + + FakeAutocompleteProviderClient client; + result.AppendDedicatedPedalMatches(&client, input); + + // Two distinct Pedals should be appended. + EXPECT_EQ(result.size(), 4u); + EXPECT_NE(result.match_at(2)->pedal, nullptr); + EXPECT_NE(result.match_at(3)->pedal, nullptr); + + // Neither should be allowed to be default match, even though they were both + // derived from suggestions where the field is set true. + EXPECT_TRUE(result.match_at(0)->allowed_to_be_default_match); + EXPECT_TRUE(result.match_at(1)->allowed_to_be_default_match); + EXPECT_FALSE(result.match_at(2)->allowed_to_be_default_match); + EXPECT_FALSE(result.match_at(3)->allowed_to_be_default_match); +} + +TEST_F(AutocompleteResultTest, PedalSuggestionsRemainUnique) { + TestData data[] = { + {1, 1, 500, true}, + {0, 1, 1100, true}, + {2, 1, 1000, true}, + {0, 1, 1200, true}, + }; + + ACMatches matches; + PopulateAutocompleteMatches(data, base::size(data), &matches); + matches[0].contents = base::UTF8ToUTF16("clear chrome history"); + matches[1].contents = base::UTF8ToUTF16("open incognito tab"); + matches[2].contents = base::UTF8ToUTF16("clear chrome history"); + + AutocompleteInput input(base::ASCIIToUTF16("a"), + metrics::OmniboxEventProto::OTHER, + TestSchemeClassifier()); + AutocompleteResult result; + result.AppendMatches(input, matches); + + FakeAutocompleteProviderClient client; + result.AppendDedicatedPedalMatches(&client, input); + + // Exactly 2 (not 3) unique Pedals should be added with relevance close to max + // of the triggering suggestions. + EXPECT_EQ(result.size(), 6u); + EXPECT_NE(result.match_at(4)->pedal, nullptr); + EXPECT_NE(result.match_at(5)->pedal, nullptr); + EXPECT_NE(result.match_at(4)->pedal, result.match_at(5)->pedal); + EXPECT_EQ(result.match_at(4)->relevance, 999); + EXPECT_EQ(result.match_at(5)->relevance, 1099); + + // Now artificially modify existing suggestions and run again to ensure that + // no duplicates are added, but the existing Pedal suggestion is updated. + result.match_at(3)->contents = base::UTF8ToUTF16("open incognito tab"); + result.AppendDedicatedPedalMatches(&client, input); + EXPECT_EQ(result.size(), 6u); + EXPECT_NE(result.match_at(4)->pedal, nullptr); + EXPECT_NE(result.match_at(5)->pedal, nullptr); + EXPECT_NE(result.match_at(4)->pedal, result.match_at(5)->pedal); + EXPECT_EQ(result.match_at(5)->relevance, 1199); +}
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.cc b/components/password_manager/core/browser/password_form_metrics_recorder.cc index e407765..82610742cd 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder.cc +++ b/components/password_manager/core/browser/password_form_metrics_recorder.cc
@@ -254,6 +254,15 @@ FillingAssistance filling_assistance = *filling_assistance_; UMA_HISTOGRAM_ENUMERATION("PasswordManager.FillingAssistance", filling_assistance); + + if (is_main_frame_secure_) { + UMA_HISTOGRAM_ENUMERATION( + "PasswordManager.FillingAssistance.SecureOrigin", filling_assistance); + } else { + UMA_HISTOGRAM_ENUMERATION( + "PasswordManager.FillingAssistance.InsecureOrigin", + filling_assistance); + } } ukm_entry_builder_.Record(ukm::UkmRecorder::Get());
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc index d9fd683..8d31f79 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc +++ b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
@@ -754,36 +754,53 @@ void CheckFillingAssistanceTestCase( const FillingAssistanceTestCase& test_case) { - SCOPED_TRACE(testing::Message("Test description: ") - << test_case.description_for_logging); + for (bool is_main_frame_secure : {false, true}) { + SCOPED_TRACE(testing::Message("Test description: ") + << test_case.description_for_logging + << ", is_main_frame_secure: " << std::boolalpha + << is_main_frame_secure); - base::test::ScopedTaskEnvironment scoped_task_environment_; - base::HistogramTester histogram_tester; + base::test::ScopedTaskEnvironment scoped_task_environment_; + base::HistogramTester histogram_tester; - FormData form_data = ConvertToFormData(test_case.fields); - std::set<base::string16> saved_usernames = - ConvertToString16Set(test_case.saved_usernames); - std::set<base::string16> saved_passwords = - ConvertToString16Set(test_case.saved_passwords); + FormData form_data = ConvertToFormData(test_case.fields); + std::set<base::string16> saved_usernames = + ConvertToString16Set(test_case.saved_usernames); + std::set<base::string16> saved_passwords = + ConvertToString16Set(test_case.saved_passwords); - auto recorder = - CreatePasswordFormMetricsRecorder(true /*is_main_frame_secure*/, nullptr); - if (test_case.submission_detected) { - recorder->CalculateFillingAssistanceMetric(form_data, saved_usernames, - saved_passwords, - test_case.interactions_stats); - } + auto recorder = + CreatePasswordFormMetricsRecorder(is_main_frame_secure, nullptr); + if (test_case.submission_detected) { + recorder->CalculateFillingAssistanceMetric(form_data, saved_usernames, + saved_passwords, + test_case.interactions_stats); + } - if (test_case.submission_is_successful) - recorder->LogSubmitPassed(); - recorder.reset(); + if (test_case.submission_is_successful) + recorder->LogSubmitPassed(); + recorder.reset(); - int expected_count = test_case.expectation ? 1 : 0; - histogram_tester.ExpectTotalCount("PasswordManager.FillingAssistance", - expected_count); - if (test_case.expectation) { - histogram_tester.ExpectUniqueSample("PasswordManager.FillingAssistance", - test_case.expectation.value(), 1); + int expected_count = test_case.expectation ? 1 : 0; + int expected_insecure_count = !is_main_frame_secure ? expected_count : 0; + int expected_secure_count = is_main_frame_secure ? expected_count : 0; + histogram_tester.ExpectTotalCount("PasswordManager.FillingAssistance", + expected_count); + histogram_tester.ExpectTotalCount( + "PasswordManager.FillingAssistance.InsecureOrigin", + expected_insecure_count); + histogram_tester.ExpectTotalCount( + "PasswordManager.FillingAssistance.SecureOrigin", + expected_secure_count); + if (test_case.expectation) { + histogram_tester.ExpectUniqueSample("PasswordManager.FillingAssistance", + *test_case.expectation, 1); + histogram_tester.ExpectUniqueSample( + is_main_frame_secure + ? "PasswordManager.FillingAssistance.SecureOrigin" + : "PasswordManager.FillingAssistance.InsecureOrigin", + *test_case.expectation, 1); + } } }
diff --git a/components/safe_browsing/password_protection/visual_utils.cc b/components/safe_browsing/password_protection/visual_utils.cc index e24d3ad..e395851 100644 --- a/components/safe_browsing/password_protection/visual_utils.cc +++ b/components/safe_browsing/password_protection/visual_utils.cc
@@ -3,13 +3,73 @@ // found in the LICENSE file. #include <unordered_map> +#include <vector> #include "base/numerics/checked_math.h" #include "components/safe_browsing/password_protection/visual_utils.h" +#include "base/logging.h" +#include "base/numerics/checked_math.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkPixmap.h" + namespace safe_browsing { namespace visual_utils { +namespace { + +// Constants used in getting the luminance of a Rec 2020 RGB value. +// Drawn from: +// https://en.wikipedia.org/wiki/Rec._2020#RGB_and_luma-chroma_formats +const uint32_t kWeightRed = 263; +const uint32_t kWeightGreen = 678; +const uint32_t kWeightBlue = 59; + +// WARNING: The following parameters are highly privacy and performance +// sensitive. These should not be changed without thorough review. +const int kPHashDownsampleWidth = 288; +const int kPHashDownsampleHeight = 288; +const int kPHashBlockSize = 6; + +// Returns the median value of the list. +uint8_t GetMedian(const std::vector<uint8_t>& samples) { + std::vector<uint8_t> samples_copy = samples; + std::vector<uint8_t>::iterator middle = + samples_copy.begin() + (samples_copy.size() / 2); + std::nth_element(samples_copy.begin(), middle, samples_copy.end()); + return *middle; +} + +// Encode the luminances as a bitstring, with a "1" bit if the luminance is +// above the cutoff, and a "0" if it's below. +void EncodeHash(const std::vector<uint8_t>& luminances, + uint8_t cutoff_luminance, + std::string* output) { + int current_bits = 0; + uint8_t current_byte = 0; + *output = ""; + + for (uint8_t luminance : luminances) { + current_bits++; + current_byte <<= 1; + if (luminance >= cutoff_luminance) + current_byte |= 1; + + if (current_bits == 8) { + *output += static_cast<char>(current_byte); + current_bits = 0; + current_byte = 0; + } + } + + if (current_bits != 0) { + current_byte <<= (8 - current_bits); + *output += static_cast<char>(current_byte); + } +} + +} // namespace + // A QuantizedColor takes the highest 3 bits of R, G, and B, and concatenates // them. QuantizedColor SkColorToQuantizedColor(SkColor color) { @@ -67,5 +127,93 @@ return true; } +bool GetBlurredImage(const SkBitmap& image, + VisualFeatures::BlurredImage* blurred_image) { + if (image.drawsNothing()) + return false; + + // Use the Rec. 2020 color space, in case the user input is wide-gamut. + sk_sp<SkColorSpace> rec2020 = SkColorSpace::MakeRGB( + {2.22222f, 0.909672f, 0.0903276f, 0.222222f, 0.0812429f, 0, 0}, + SkNamedGamut::kRec2020); + + // We scale down twice, once with medium quality, once with none quality to be + // consistent with the backend. + // TODO(drubery): Investigate whether this is necessary for performance or + // not. + SkImageInfo downsampled_info = + SkImageInfo::Make(kPHashDownsampleWidth, kPHashDownsampleHeight, + SkColorType::kRGBA_8888_SkColorType, + SkAlphaType::kUnpremul_SkAlphaType, rec2020); + SkBitmap downsampled; + if (!downsampled.tryAllocPixels(downsampled_info)) + return false; + image.pixmap().scalePixels(downsampled.pixmap(), + SkFilterQuality::kMedium_SkFilterQuality); + + SkImageInfo blurred_info = + SkImageInfo::Make(kPHashDownsampleWidth / kPHashBlockSize, + kPHashDownsampleHeight / kPHashBlockSize, + SkColorType::kRGBA_8888_SkColorType, + SkAlphaType::kUnpremul_SkAlphaType, rec2020); + SkBitmap blurred; + if (!blurred.tryAllocPixels(blurred_info)) + return false; + downsampled.pixmap().scalePixels(blurred.pixmap(), + SkFilterQuality::kNone_SkFilterQuality); + + blurred_image->set_width(blurred.width()); + blurred_image->set_height(blurred.height()); + blurred_image->clear_data(); + + const uint32_t* rgba = blurred.getAddr32(0, 0); + for (int i = 0; i < blurred.width() * blurred.height(); i++) { + *blurred_image->mutable_data() += static_cast<char>((rgba[i] >> 0) & 0xff); + *blurred_image->mutable_data() += static_cast<char>((rgba[i] >> 8) & 0xff); + *blurred_image->mutable_data() += static_cast<char>((rgba[i] >> 16) & 0xff); + } + + return true; +} + +// Computes the final PHash value for the BlurredImage. For each pixel in the +// blurred image, we compute its luminance. Then we create a bitstring, where +// each pixel gives a "1" if the luminance is at least the median, and a "0" +// otherwise. +bool GetPHash(const VisualFeatures::BlurredImage& blurred_image, + std::string* phash) { + DCHECK_LE(blurred_image.width(), kPHashDownsampleWidth); + DCHECK_LE(blurred_image.height(), kPHashDownsampleHeight); + + int width = blurred_image.width(); + int height = blurred_image.height(); + + base::CheckedNumeric<int> expected_size = + base::CheckMul(3u, base::CheckMul(width, height)); + if (!expected_size.IsValid()) + return false; + if (blurred_image.data().size() != expected_size.ValueOrDie()) + return false; + + std::vector<uint8_t> luminances; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + int current_offset = 3 * width * y + 3 * x; + uint8_t r = blurred_image.data()[current_offset]; + uint8_t g = blurred_image.data()[current_offset + 1]; + uint8_t b = blurred_image.data()[current_offset + 2]; + + uint8_t luminance = + (kWeightRed * r + kWeightGreen * g + kWeightBlue * b) / + (kWeightRed + kWeightGreen + kWeightBlue); + luminances.push_back(luminance); + } + } + + uint8_t cutoff_luminance = GetMedian(luminances); + EncodeHash(luminances, cutoff_luminance, phash); + return true; +} + } // namespace visual_utils } // namespace safe_browsing
diff --git a/components/safe_browsing/password_protection/visual_utils.h b/components/safe_browsing/password_protection/visual_utils.h index 269fefe..70a037f 100644 --- a/components/safe_browsing/password_protection/visual_utils.h +++ b/components/safe_browsing/password_protection/visual_utils.h
@@ -5,6 +5,8 @@ #ifndef COMPONENTS_SAFE_BROWSING_PASSWORD_PROTECTION_VISUAL_UTILS_H_ #define COMPONENTS_SAFE_BROWSING_PASSWORD_PROTECTION_VISUAL_UTILS_H_ +#include <string> + #include "components/safe_browsing/proto/csd.pb.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -24,6 +26,18 @@ bool GetHistogramForImage(const SkBitmap& image, VisualFeatures::ColorHistogram* histogram); +// Computes the BlurredImage for the given input image. This involves +// downsampling the image to a certain fixed resolution, then blurring +// by taking an average over fixed-size blocks of pixels. +bool GetBlurredImage(const SkBitmap& image, + VisualFeatures::BlurredImage* blurred_image); + +// Computes the pHash from the Blurred image. This involves computing the +// luminance for each pixel, then outputs a bitstring, where each pixel +// contributes a "1" if the luminance is above the median, and a "0" otherwise. +bool GetPHash(const VisualFeatures::BlurredImage& blurred_image, + std::string* phash); + } // namespace visual_utils } // namespace safe_browsing
diff --git a/components/safe_browsing/password_protection/visual_utils_unittest.cc b/components/safe_browsing/password_protection/visual_utils_unittest.cc index 049bfa7..5cc0994 100644 --- a/components/safe_browsing/password_protection/visual_utils_unittest.cc +++ b/components/safe_browsing/password_protection/visual_utils_unittest.cc
@@ -4,6 +4,7 @@ #include "components/safe_browsing/password_protection/visual_utils.h" +#include "base/test/test_discardable_memory_allocator.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -12,7 +13,35 @@ using ::testing::FloatEq; -TEST(VisualUtilsTest, TestSkColorToQuantizedColor) { +class VisualUtilsTest : public testing::Test { + protected: + void SetUp() override { + base::DiscardableMemoryAllocator::SetInstance(&test_allocator_); + + sk_sp<SkColorSpace> rec2020 = SkColorSpace::MakeRGB( + {2.22222f, 0.909672f, 0.0903276f, 0.222222f, 0.0812429f, 0, 0}, + SkNamedGamut::kRec2020); + SkImageInfo bitmap_info = + SkImageInfo::Make(1000, 1000, SkColorType::kBGRA_8888_SkColorType, + SkAlphaType::kUnpremul_SkAlphaType, rec2020); + + ASSERT_TRUE(bitmap_.tryAllocPixels(bitmap_info)); + } + + void TearDown() override { + base::DiscardableMemoryAllocator::SetInstance(nullptr); + } + + // A test bitmap to work with. Initialized to be 1000x1000 in the Rec 2020 + // color space. + SkBitmap bitmap_; + + private: + // A DiscardableMemoryAllocator is needed for certain Skia operations. + base::TestDiscardableMemoryAllocator test_allocator_; +}; + +TEST_F(VisualUtilsTest, TestSkColorToQuantizedColor) { // Test quantization EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(0, 0, 31)), 0u); EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(0, 0, 32)), 1u); @@ -28,76 +57,191 @@ EXPECT_EQ(SkColorToQuantizedColor(SkColorSetRGB(255, 255, 255)), 511u); } -TEST(VisualUtilsTest, GetQuantizedR) { +TEST_F(VisualUtilsTest, GetQuantizedR) { EXPECT_EQ(GetQuantizedR(0), 0); EXPECT_EQ(GetQuantizedR(64), 1); EXPECT_EQ(GetQuantizedR(448), 7); } -TEST(VisualUtilsTest, GetQuantizedG) { +TEST_F(VisualUtilsTest, GetQuantizedG) { EXPECT_EQ(GetQuantizedG(0), 0); EXPECT_EQ(GetQuantizedG(8), 1); EXPECT_EQ(GetQuantizedG(56), 7); } -TEST(VisualUtilsTest, GetQuantizedB) { +TEST_F(VisualUtilsTest, GetQuantizedB) { EXPECT_EQ(GetQuantizedB(0), 0); EXPECT_EQ(GetQuantizedB(1), 1); EXPECT_EQ(GetQuantizedB(7), 7); } -TEST(VisualUtilsTest, GetHistogramForImageWhite) { +TEST_F(VisualUtilsTest, GetHistogramForImageWhite) { VisualFeatures::ColorHistogram histogram; SkBitmap bitmap; - bitmap.allocN32Pixels(200, 200); - for (int x = 0; x < 200; x++) - for (int y = 0; y < 200; y++) - *bitmap.getAddr32(x, y) = SkColorSetRGB(255, 255, 255); + // Draw white over half the image + for (int x = 0; x < 1000; x++) + for (int y = 0; y < 1000; y++) + *bitmap_.getAddr32(x, y) = SkColorSetRGB(255, 255, 255); - ASSERT_TRUE(GetHistogramForImage(bitmap, &histogram)); + ASSERT_TRUE(GetHistogramForImage(bitmap_, &histogram)); ASSERT_EQ(histogram.bins_size(), 1); EXPECT_THAT(histogram.bins(0).centroid_x(), - FloatEq(0.4975)); // All pixels are the same color, so centroid_x - // is (0+1+...+199)/200/200 = 0.4975 - EXPECT_THAT(histogram.bins(0).centroid_y(), FloatEq(0.4975)); + FloatEq(0.4995)); // All pixels are the same color, so centroid_x + // is (0+1+...+999)/1000/1000 = 0.4995 + EXPECT_THAT(histogram.bins(0).centroid_y(), FloatEq(0.4995)); EXPECT_EQ(histogram.bins(0).quantized_r(), 7); EXPECT_EQ(histogram.bins(0).quantized_g(), 7); EXPECT_EQ(histogram.bins(0).quantized_b(), 7); EXPECT_THAT(histogram.bins(0).weight(), FloatEq(1.0)); } -TEST(VisualUtilsTest, GetHistogramForImageHalfWhiteHalfBlack) { +TEST_F(VisualUtilsTest, GetHistogramForImageHalfWhiteHalfBlack) { VisualFeatures::ColorHistogram histogram; - SkBitmap bitmap; - bitmap.allocN32Pixels(200, 200); + + // Draw white over half the image + for (int x = 0; x < 1000; x++) + for (int y = 0; y < 500; y++) + *bitmap_.getAddr32(x, y) = SkColorSetRGB(255, 255, 255); // Draw black over half the image. - for (int x = 0; x < 200; x++) - for (int y = 0; y < 100; y++) - *bitmap.getAddr32(x, y) = SkColorSetRGB(0, 0, 0); + for (int x = 0; x < 1000; x++) + for (int y = 500; y < 1000; y++) + *bitmap_.getAddr32(x, y) = SkColorSetRGB(0, 0, 0); - for (int x = 0; x < 200; x++) - for (int y = 100; y < 200; y++) - *bitmap.getAddr32(x, y) = SkColorSetRGB(255, 255, 255); - - ASSERT_TRUE(GetHistogramForImage(bitmap, &histogram)); + ASSERT_TRUE(GetHistogramForImage(bitmap_, &histogram)); ASSERT_EQ(histogram.bins_size(), 2); - EXPECT_THAT(histogram.bins(0).centroid_x(), FloatEq(0.4975)); - EXPECT_THAT(histogram.bins(0).centroid_y(), FloatEq(0.7475)); - EXPECT_EQ(histogram.bins(0).quantized_r(), 7); - EXPECT_EQ(histogram.bins(0).quantized_g(), 7); - EXPECT_EQ(histogram.bins(0).quantized_b(), 7); + EXPECT_THAT(histogram.bins(0).centroid_x(), FloatEq(0.4995)); + EXPECT_THAT(histogram.bins(0).centroid_y(), FloatEq(0.7495)); + EXPECT_EQ(histogram.bins(0).quantized_r(), 0); + EXPECT_EQ(histogram.bins(0).quantized_g(), 0); + EXPECT_EQ(histogram.bins(0).quantized_b(), 0); EXPECT_THAT(histogram.bins(0).weight(), FloatEq(0.5)); - EXPECT_THAT(histogram.bins(1).centroid_x(), FloatEq(0.4975)); - EXPECT_THAT(histogram.bins(1).centroid_y(), FloatEq(0.2475)); - EXPECT_EQ(histogram.bins(1).quantized_r(), 0); - EXPECT_EQ(histogram.bins(1).quantized_g(), 0); - EXPECT_EQ(histogram.bins(1).quantized_b(), 0); + EXPECT_THAT(histogram.bins(1).centroid_x(), FloatEq(0.4995)); + EXPECT_THAT(histogram.bins(1).centroid_y(), FloatEq(0.2495)); + EXPECT_EQ(histogram.bins(1).quantized_r(), 7); + EXPECT_EQ(histogram.bins(1).quantized_g(), 7); + EXPECT_EQ(histogram.bins(1).quantized_b(), 7); EXPECT_THAT(histogram.bins(1).weight(), FloatEq(0.5)); } +TEST_F(VisualUtilsTest, BlurImageWhite) { + VisualFeatures::BlurredImage blurred; + + // Draw white over the image + for (int x = 0; x < 1000; x++) + for (int y = 0; y < 1000; y++) + *bitmap_.getAddr32(x, y) = SkColorSetRGB(255, 255, 255); + + ASSERT_TRUE(GetBlurredImage(bitmap_, &blurred)); + ASSERT_EQ(48, blurred.width()); + ASSERT_EQ(48, blurred.height()); + ASSERT_EQ(3u * 48u * 48u, blurred.data().size()); + for (size_t i = 0; i < 48u * 48u; i++) { + EXPECT_EQ('\xff', blurred.data()[3 * i]); + EXPECT_EQ('\xff', blurred.data()[3 * i + 1]); + EXPECT_EQ('\xff', blurred.data()[3 * i + 2]); + } +} + +TEST_F(VisualUtilsTest, BlurImageRed) { + VisualFeatures::BlurredImage blurred; + + // Draw red over the image. + for (int x = 0; x < 1000; x++) + for (int y = 0; y < 1000; y++) + *bitmap_.getAddr32(x, y) = SkColorSetRGB(255, 0, 0); + + ASSERT_TRUE(GetBlurredImage(bitmap_, &blurred)); + ASSERT_EQ(48, blurred.width()); + ASSERT_EQ(48, blurred.height()); + ASSERT_EQ(3u * 48u * 48u, blurred.data().size()); + for (size_t i = 0; i < 48u * 48u; i++) { + EXPECT_EQ('\xff', blurred.data()[3 * i]); + EXPECT_EQ('\x00', blurred.data()[3 * i + 1]); + EXPECT_EQ('\x00', blurred.data()[3 * i + 2]); + } +} + +TEST_F(VisualUtilsTest, BlurImageHalfWhiteHalfBlack) { + VisualFeatures::BlurredImage blurred; + + // Draw black over half the image. + for (int x = 0; x < 1000; x++) + for (int y = 0; y < 500; y++) + *bitmap_.getAddr32(x, y) = SkColorSetRGB(0, 0, 0); + + // Draw white over half the image + for (int x = 0; x < 1000; x++) + for (int y = 500; y < 1000; y++) + *bitmap_.getAddr32(x, y) = SkColorSetRGB(255, 255, 255); + + ASSERT_TRUE(GetBlurredImage(bitmap_, &blurred)); + ASSERT_EQ(48, blurred.width()); + ASSERT_EQ(48, blurred.height()); + ASSERT_EQ(3u * 48u * 48u, blurred.data().size()); + // The middle blocks may have been blurred to something between white and + // black, so only verify the first 22 and last 22 rows. + for (size_t i = 0; i < 22u * 48u; i++) { + EXPECT_EQ('\x00', blurred.data()[3 * i]); + EXPECT_EQ('\x00', blurred.data()[3 * i + 1]); + EXPECT_EQ('\x00', blurred.data()[3 * i + 2]); + } + + for (size_t i = 26u * 48u; i < 48u * 48u; i++) { + EXPECT_EQ('\xff', blurred.data()[3 * i]); + EXPECT_EQ('\xff', blurred.data()[3 * i + 1]); + EXPECT_EQ('\xff', blurred.data()[3 * i + 2]); + } +} + +TEST_F(VisualUtilsTest, PHashUniformImage) { + // Create 8x1 image. + VisualFeatures::BlurredImage blurred; + blurred.set_width(1); + blurred.set_height(8); + for (int i = 0; i < 8; i++) { + *blurred.mutable_data() += "\x30\x30\x30"; + } + + std::string phash; + ASSERT_TRUE(GetPHash(blurred, &phash)); + EXPECT_EQ("\xff", phash); +} + +TEST_F(VisualUtilsTest, PHashPadsExtraBits) { + // Create 9x1 image. + VisualFeatures::BlurredImage blurred; + blurred.set_width(1); + blurred.set_height(9); + for (int i = 0; i < 9; i++) { + *blurred.mutable_data() += "\x30\x30\x30"; + } + + std::string phash; + ASSERT_TRUE(GetPHash(blurred, &phash)); + EXPECT_EQ("\xff\x80", phash); +} + +TEST_F(VisualUtilsTest, PHashDistinctLuminances) { + // Create 9x1 image, with all pixels distinct + VisualFeatures::BlurredImage blurred; + blurred.set_width(1); + blurred.set_height(9); + for (int i = 0; i < 9; i++) { + *blurred.mutable_data() += "\x30\x30"; + // Using 10*i to ensure that the luminances are distinct. + *blurred.mutable_data() += static_cast<char>(10 * i); + } + + // With 9 distinct pixels, the first 4 will be below the median, and the last + // 5 will be at least the median. + std::string phash; + ASSERT_TRUE(GetPHash(blurred, &phash)); + EXPECT_EQ("\x0f\x80", phash); +} + } // namespace visual_utils } // namespace safe_browsing
diff --git a/components/send_tab_to_self/send_tab_to_self_bridge.cc b/components/send_tab_to_self/send_tab_to_self_bridge.cc index 549d513..c11495f8 100644 --- a/components/send_tab_to_self/send_tab_to_self_bridge.cc +++ b/components/send_tab_to_self/send_tab_to_self_bridge.cc
@@ -24,12 +24,12 @@ SendTabToSelfBridge::SendTabToSelfBridge( std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor, - syncer::LocalDeviceInfoProvider* local_device_info_provider, + const syncer::LocalDeviceInfoProvider* device_info_provider, base::Clock* clock) : ModelTypeSyncBridge(std::move(change_processor)), - local_device_info_provider_(local_device_info_provider), + local_device_info_provider_(device_info_provider), clock_(clock) { - DCHECK(local_device_info_provider_); + DCHECK(device_info_provider); DCHECK(clock_); auto batch = std::make_unique<syncer::MetadataBatch>(); this->change_processor()->ModelReadyToSync(std::move(batch)); @@ -173,7 +173,11 @@ change_processor()->Put(guid, std::move(entity_data), &metadata_change_list); - return entries_.emplace(guid, std::move(entry)).first->second.get(); + const SendTabToSelfEntry* result = + entries_.emplace(guid, std::move(entry)).first->second.get(); + NotifySendTabToSelfModelChanged(); + + return result; } void SendTabToSelfBridge::NotifySendTabToSelfModelChanged() {
diff --git a/components/send_tab_to_self/send_tab_to_self_bridge.h b/components/send_tab_to_self/send_tab_to_self_bridge.h index 9cfc7e23..6e96ab3 100644 --- a/components/send_tab_to_self/send_tab_to_self_bridge.h +++ b/components/send_tab_to_self/send_tab_to_self_bridge.h
@@ -37,7 +37,7 @@ // |clock| must not be null and must outlive this object. SendTabToSelfBridge( std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor, - syncer::LocalDeviceInfoProvider* local_device_info_provider, + const syncer::LocalDeviceInfoProvider* local_device_info_provider, base::Clock* clock); ~SendTabToSelfBridge() override;
diff --git a/components/send_tab_to_self/send_tab_to_self_service.cc b/components/send_tab_to_self/send_tab_to_self_service.cc index 49916b6..1acd8fc 100644 --- a/components/send_tab_to_self/send_tab_to_self_service.cc +++ b/components/send_tab_to_self/send_tab_to_self_service.cc
@@ -16,7 +16,7 @@ SendTabToSelfService::SendTabToSelfService( version_info::Channel channel, - syncer::LocalDeviceInfoProvider* local_device_info_provider) { + const syncer::LocalDeviceInfoProvider* local_device_info_provider) { bridge_ = std::make_unique<send_tab_to_self::SendTabToSelfBridge>( std::make_unique<syncer::ClientTagBasedModelTypeProcessor>( syncer::SEND_TAB_TO_SELF,
diff --git a/components/send_tab_to_self/send_tab_to_self_service.h b/components/send_tab_to_self/send_tab_to_self_service.h index 44941a2..123334d 100644 --- a/components/send_tab_to_self/send_tab_to_self_service.h +++ b/components/send_tab_to_self/send_tab_to_self_service.h
@@ -26,7 +26,7 @@ public: SendTabToSelfService( version_info::Channel channel, - syncer::LocalDeviceInfoProvider* local_device_info_provider); + const syncer::LocalDeviceInfoProvider* local_device_info_provider); ~SendTabToSelfService() override; SendTabToSelfModel* GetSendTabToSelfModel();
diff --git a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc index ffcb7a93..9d5a874 100644 --- a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc +++ b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle.cc
@@ -11,6 +11,7 @@ #include "base/debug/dump_without_crashing.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" +#include "base/strings/stringprintf.h" #include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h" #include "components/subresource_filter/core/browser/subresource_filter_constants.h" #include "components/subresource_filter/core/common/time_measurements.h"
diff --git a/components/sync/engine_impl/syncer_proto_util.cc b/components/sync/engine_impl/syncer_proto_util.cc index cac498d..80b80a30 100644 --- a/components/sync/engine_impl/syncer_proto_util.cc +++ b/components/sync/engine_impl/syncer_proto_util.cc
@@ -358,15 +358,22 @@ ClientToServerMessage::Contents_MAX + 1); std::map<int, std::string> progress_marker_token_per_data_type; - for (const sync_pb::DataTypeProgressMarker& progress_marker : - msg.get_updates().from_progress_marker()) { - progress_marker_token_per_data_type[progress_marker.data_type_id()] = - progress_marker.token(); - UMA_HISTOGRAM_ENUMERATION( - "Sync.PostedDataTypeGetUpdatesRequest", - ModelTypeToHistogramInt(GetModelTypeFromSpecificsFieldNumber( - progress_marker.data_type_id())), - static_cast<int>(MODEL_TYPE_COUNT)); + + if (msg.has_get_updates()) { + UMA_HISTOGRAM_ENUMERATION("Sync.PostedGetUpdatesOrigin", + msg.get_updates().get_updates_origin(), + sync_pb::SyncEnums::GetUpdatesOrigin_ARRAYSIZE); + + for (const sync_pb::DataTypeProgressMarker& progress_marker : + msg.get_updates().from_progress_marker()) { + progress_marker_token_per_data_type[progress_marker.data_type_id()] = + progress_marker.token(); + UMA_HISTOGRAM_ENUMERATION( + "Sync.PostedDataTypeGetUpdatesRequest", + ModelTypeToHistogramInt(GetModelTypeFromSpecificsFieldNumber( + progress_marker.data_type_id())), + static_cast<int>(MODEL_TYPE_COUNT)); + } } const base::Time start_time = base::Time::Now();
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.cc b/components/sync/model_impl/client_tag_based_model_type_processor.cc index c76a24ef..abd575e 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor.cc
@@ -16,6 +16,7 @@ #include "base/trace_event/memory_usage_estimator.h" #include "components/sync/base/data_type_histogram.h" #include "components/sync/base/hash_util.h" +#include "components/sync/base/model_type.h" #include "components/sync/base/time.h" #include "components/sync/engine/commit_queue.h" #include "components/sync/engine/data_type_activation_response.h" @@ -59,6 +60,19 @@ return count; } +void LogNonReflectionUpdateFreshnessToUma(ModelType type, + base::Time remote_modification_time) { + const base::TimeDelta latency = base::Time::Now() - remote_modification_time; + + UMA_HISTOGRAM_LONG_TIMES("Sync.NonReflectionUpdateFreshnessPossiblySkewed", + latency); + + base::UmaHistogramLongTimes( + std::string("Sync.NonReflectionUpdateFreshnessPossiblySkewed.") + + ModelTypeToHistogramSuffix(type), + latency); +} + } // namespace ClientTagBasedModelTypeProcessor::ClientTagBasedModelTypeProcessor( @@ -1058,6 +1072,12 @@ // have server tags instead). continue; } + + LogNonReflectionUpdateFreshnessToUma( + type_, + /*remote_modification_time=*/ + ProtoTimeToTime(entity->metadata().modification_time())); + if (entity->storage_key().empty()) { // Storage key of this entity is not known yet. Don't update metadata, it // will be done from UpdateStorageKey.
diff --git a/components/sync/syncable/model_type.cc b/components/sync/syncable/model_type.cc index bb45a57..2b50bc1 100644 --- a/components/sync/syncable/model_type.cc +++ b/components/sync/syncable/model_type.cc
@@ -21,6 +21,7 @@ #include "components/sync/protocol/preference_specifics.pb.h" #include "components/sync/protocol/reading_list_specifics.pb.h" #include "components/sync/protocol/search_engine_specifics.pb.h" +#include "components/sync/protocol/send_tab_to_self_specifics.pb.h" #include "components/sync/protocol/session_specifics.pb.h" #include "components/sync/protocol/sync.pb.h" #include "components/sync/protocol/theme_specifics.pb.h"
diff --git a/components/variations/service/variations_service.cc b/components/variations/service/variations_service.cc index 13d1bca..0583214 100644 --- a/components/variations/service/variations_service.cc +++ b/components/variations/service/variations_service.cc
@@ -503,11 +503,11 @@ safe_seed_manager_.RecordFetchStarted(); - // Normally, there shouldn't be a |pending_request_| when this fires. However - // it's not impossible - for example if Chrome was paused (e.g. in a debugger - // or if the machine was suspended) and OnURLFetchComplete() hasn't had a - // chance to run yet from the previous request. In this case, don't start a - // new request and just let the previous one finish. + // Normally, there shouldn't be a |pending_seed_request_| when this fires. + // However it's not impossible - for example if Chrome was paused (e.g. in a + // debugger or if the machine was suspended) and OnURLFetchComplete() hasn't + // had a chance to run yet from the previous request. In this case, don't + // start a new request and just let the previous one finish. if (pending_seed_request_) return false; @@ -920,6 +920,10 @@ field_trial_creator_.OverrideCachedUIStrings(); } +void VariationsService::CancelCurrentRequestForTesting() { + pending_seed_request_.reset(); +} + std::string VariationsService::GetStoredPermanentCountry() { const base::ListValue* list_value = local_state_->GetList(prefs::kVariationsPermanentConsistencyCountry);
diff --git a/components/variations/service/variations_service.h b/components/variations/service/variations_service.h index 217a7c5..bc5fd826b 100644 --- a/components/variations/service/variations_service.h +++ b/components/variations/service/variations_service.h
@@ -176,6 +176,11 @@ // Exposed for testing. void GetClientFilterableStateForVersionCalledForTesting(); + web_resource::ResourceRequestAllowedNotifier* + GetResourceRequestAllowedNotifierForTesting() { + return resource_request_allowed_notifier_.get(); + } + // Wrapper around VariationsFieldTrialCreator::SetupFieldTrials(). bool SetupFieldTrials(const char* kEnableGpuBenchmarking, const char* kEnableFeatures, @@ -190,6 +195,9 @@ int request_count() const { return request_count_; } + // Cancels the currently pending fetch request. + void CancelCurrentRequestForTesting(); + protected: // Starts the fetching process once, where |OnURLFetchComplete| is called with // the response. This calls DoFetchToURL with the set url.
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index d79cb19..aa67edf7 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -214,15 +214,19 @@ GrGLFramebufferInfo framebuffer_info; framebuffer_info.fFBOID = 0; - framebuffer_info.fFormat = - gl_version_info_->is_es ? GL_BGRA8_EXT : GL_RGBA8; + if (supports_alpha_) { + framebuffer_info.fFormat = + gl_version_info_->is_es ? GL_BGRA8_EXT : GL_RGBA8; + } else { + framebuffer_info.fFormat = GL_RGB8_OES; + } GrBackendRenderTarget render_target(size.width(), size.height(), 0, 8, framebuffer_info); sk_surface_ = SkSurface::MakeFromBackendRenderTarget( gr_context(), render_target, kBottomLeft_GrSurfaceOrigin, - kBGRA_8888_SkColorType, color_space.ToSkColorSpace(), &surface_props); + FramebufferColorType(), color_space.ToSkColorSpace(), &surface_props); DCHECK(sk_surface_); } else { #if BUILDFLAG(ENABLE_VULKAN) @@ -624,32 +628,39 @@ return; auto* context = context_state_->real_context(); + auto* current_gl = context->GetCurrentGL(); + api_ = current_gl->Api; gl_version_info_ = context->GetVersionInfo(); capabilities_.flipped_output_surface = gl_surface_->FlipsVertically(); - // Get stencil bits from the default frame buffer. - auto* current_gl = context->GetCurrentGL(); - const auto* version = current_gl->Version; - auto* api = current_gl->Api; - api->glBindFramebufferEXTFn(GL_FRAMEBUFFER, 0); + // Get alpha and stencil bits from the default frame buffer. + api_->glBindFramebufferEXTFn(GL_FRAMEBUFFER, 0); gr_context()->resetContext(kRenderTarget_GrGLBackendState); + const auto* version = current_gl->Version; GLint stencil_bits = 0; + GLint alpha_bits = 0; if (version->is_desktop_core_profile) { - api->glGetFramebufferAttachmentParameterivEXTFn( + api_->glGetFramebufferAttachmentParameterivEXTFn( GL_FRAMEBUFFER, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits); + api_->glGetFramebufferAttachmentParameterivEXTFn( + GL_FRAMEBUFFER, GL_BACK_LEFT, GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, + &alpha_bits); } else { - api->glGetIntegervFn(GL_STENCIL_BITS, &stencil_bits); + api_->glGetIntegervFn(GL_STENCIL_BITS, &stencil_bits); + api_->glGetIntegervFn(GL_ALPHA_BITS, &alpha_bits); } CHECK_GL_ERROR(); capabilities_.supports_stencil = stencil_bits > 0; + supports_alpha_ = alpha_bits > 0; } void SkiaOutputSurfaceImplOnGpu::InitializeForVulkan( GpuServiceImpl* gpu_service) { context_state_ = gpu_service->GetContextStateForVulkan(); DCHECK(context_state_); + supports_alpha_ = true; } void SkiaOutputSurfaceImplOnGpu::BindOrCopyTextureIfNecessary( @@ -707,7 +718,7 @@ vk_image_info); sk_surface = SkSurface::MakeFromBackendRenderTarget( gr_context(), render_target, kTopLeft_GrSurfaceOrigin, - kBGRA_8888_SkColorType, nullptr, &surface_props); + FramebufferColorType(), nullptr, &surface_props); DCHECK(sk_surface); } else { auto backend = sk_surface->getBackendRenderTarget(
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index d5d4d38..50c9521 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -38,6 +38,7 @@ } namespace gl { +class GLApi; class GLSurface; } @@ -174,6 +175,10 @@ GrContext* gr_context() { return context_state_->gr_context(); } + SkColorType FramebufferColorType() { + return supports_alpha_ ? kBGRA_8888_SkColorType : kRGB_888x_SkColorType; + } + bool is_using_vulkan() const { return !!vulkan_context_provider_; } const gpu::SurfaceHandle surface_handle_; @@ -229,6 +234,9 @@ ui::LatencyTracker latency_tracker_; + gl::GLApi* api_ = nullptr; + bool supports_alpha_ = false; + THREAD_CHECKER(thread_checker_); base::WeakPtr<SkiaOutputSurfaceImplOnGpu> weak_ptr_;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_win.cc b/content/browser/accessibility/accessibility_tree_formatter_win.cc index abf05c8..14c6537 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_win.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_win.cc
@@ -724,7 +724,6 @@ return related_accessibles_string; base::win::ScopedVariant variant_self(CHILDID_SELF); - for (int index = 0; index < num_accessibles; index++) { related_accessibles_string += index > 0 ? L"," : L"<"; Microsoft::WRL::ComPtr<IUnknown> unknown = accessibles[index];
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc index 50985897..90eb615 100644 --- a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc +++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
@@ -13,6 +13,7 @@ #include "content/public/browser/media_session.h" #include "content/public/browser/overlay_window.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/common/content_client.h" #include "media/base/media_switches.h"
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h index 6f302c5..a7832f06 100644 --- a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h +++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h
@@ -8,14 +8,17 @@ #include "base/memory/weak_ptr.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "content/public/browser/picture_in_picture_window_controller.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/media_session/public/cpp/media_metadata.h" #include "services/media_session/public/mojom/media_session.mojom.h" namespace content { + class OverlaySurfaceEmbedder; class WebContents; +class WebContentsImpl; class MediaWebContentsObserver; // TODO(thakis,mlamouri): PictureInPictureWindowControllerImpl isn't
diff --git a/content/browser/portal/portal.cc b/content/browser/portal/portal.cc index 65c34a95..093cfc2 100644 --- a/content/browser/portal/portal.cc +++ b/content/browser/portal/portal.cc
@@ -4,6 +4,8 @@ #include "content/browser/portal/portal.h" +#include <utility> + #include "base/feature_list.h" #include "base/memory/ptr_util.h" #include "content/browser/frame_host/render_frame_host_impl.h" @@ -101,41 +103,24 @@ portal_contents_impl_->GetController().LoadURLWithParams(load_url_params); } -void Portal::Activate( - base::OnceCallback<void(blink::mojom::PortalActivationStatus)> callback) { +void Portal::Activate(base::OnceCallback<void()> callback) { WebContents* outer_contents = WebContents::FromRenderFrameHost(owner_render_frame_host_); WebContentsDelegate* delegate = outer_contents->GetDelegate(); - if (delegate) { - FrameTreeNode* outer_node = FrameTreeNode::GloballyFindByID( - portal_contents_impl_->GetOuterDelegateFrameTreeNodeId()); - bool is_loading = portal_contents_impl_->IsLoading(); - std::unique_ptr<WebContents> portal_contents = - portal_contents_impl_->DetachFromOuterWebContents(); - // TODO(lfg): If there are nested portals, this would replace the entire tab - // upon a nested portal's activation. We should handle that case so that it - // would only replace the nested portal's contents. - std::unique_ptr<WebContents> contents = delegate->SwapWebContents( - outer_contents, std::move(portal_contents), true, is_loading); - - if (contents.get() == outer_contents) { - // TODO(lfg): The old WebContents is currently discarded, but should be - // kept and passed to the new page. - portal_contents_impl_->set_portal(nullptr); - portal_contents_impl_->GetMainFrame()->OnPortalActivated(); - std::move(callback).Run(blink::mojom::PortalActivationStatus::kSuccess); - } else { - DCHECK_EQ(portal_contents_impl_, contents.get()); - portal_contents_impl_->AttachToOuterWebContentsFrame( - std::move(contents), outer_node->current_frame_host()); - std::move(callback).Run( - blink::mojom::PortalActivationStatus::kNotSupported); - } - - return; - } - - std::move(callback).Run(blink::mojom::PortalActivationStatus::kNotSupported); + bool is_loading = portal_contents_impl_->IsLoading(); + std::unique_ptr<WebContents> portal_contents = + portal_contents_impl_->DetachFromOuterWebContents(); + // TODO(lfg): If there are nested portals, this would replace the entire tab + // upon a nested portal's activation. We should handle that case so that it + // would only replace the nested portal's contents. https://crbug.com/919110 + std::unique_ptr<WebContents> contents = delegate->SwapWebContents( + outer_contents, std::move(portal_contents), true, is_loading); + CHECK_EQ(contents.get(), outer_contents); + // TODO(lfg): The old WebContents is currently discarded, but should be + // kept and passed to the new page. https://crbug.com/914122 + portal_contents_impl_->set_portal(nullptr); + portal_contents_impl_->GetMainFrame()->OnPortalActivated(); + std::move(callback).Run(); } void Portal::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
diff --git a/content/browser/portal/portal.h b/content/browser/portal/portal.h index a58818dec..c3bff09 100644 --- a/content/browser/portal/portal.h +++ b/content/browser/portal/portal.h
@@ -49,8 +49,7 @@ // blink::mojom::Portal implementation. void Navigate(const GURL& url) override; - void Activate(base::OnceCallback<void(blink::mojom::PortalActivationStatus)> - callback) override; + void Activate(base::OnceCallback<void()> callback) override; // WebContentsObserver overrides. void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
diff --git a/content/browser/portal/portal_browsertest.cc b/content/browser/portal/portal_browsertest.cc index 7d35f324..db38596 100644 --- a/content/browser/portal/portal_browsertest.cc +++ b/content/browser/portal/portal_browsertest.cc
@@ -41,8 +41,7 @@ blink::mojom::PortalRequest request); static PortalInterceptorForTesting* From(content::Portal* portal); - void Activate(base::OnceCallback<void(blink::mojom::PortalActivationStatus)> - callback) override { + void Activate(base::OnceCallback<void()> callback) override { portal_activated_ = true; if (run_loop_) { @@ -102,25 +101,6 @@ return interceptor; } -class MockPortalWebContentsDelegate : public WebContentsDelegate { - public: - MockPortalWebContentsDelegate() {} - ~MockPortalWebContentsDelegate() override {} - - MOCK_METHOD4( - DoSwapWebContents, - std::unique_ptr<WebContents>(WebContents*, WebContents*, bool, bool)); - std::unique_ptr<WebContents> SwapWebContents( - WebContents* old_contents, - std::unique_ptr<WebContents> new_contents, - bool did_start_load, - bool did_finish_load) override { - DoSwapWebContents(old_contents, new_contents.get(), did_start_load, - did_finish_load); - return new_contents; - } -}; - // The PortalCreatedObserver observes portal creations on // |render_frame_host_impl|. This observer can be used to monitor for multiple // Portal creations on the same RenderFrameHost, by repeatedly calling @@ -275,45 +255,6 @@ } } -// Tests that the WebContentsDelegate will receive a request to swap the -// WebContents when a portal is activated. -// Disabled due to flakiness on Android. See https://crbug.com/892669. -#if defined(OS_ANDROID) -#define MAYBE_ActivatePortal DISABLED_ActivatePortal -#else -#define MAYBE_ActivatePortal ActivatePortal -#endif - -IN_PROC_BROWSER_TEST_F(PortalBrowserTest, MAYBE_ActivatePortal) { - EXPECT_TRUE(NavigateToURL( - shell(), embedded_test_server()->GetURL("portal.test", "/title1.html"))); - WebContentsImpl* web_contents_impl = - static_cast<WebContentsImpl*>(shell()->web_contents()); - RenderFrameHostImpl* main_frame = web_contents_impl->GetMainFrame(); - - PortalCreatedObserver portal_created_observer(main_frame); - GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html")); - EXPECT_TRUE(ExecJs(main_frame, - JsReplace("var portal = document.createElement('portal');" - "portal.src = $1;" - "document.body.appendChild(portal);", - a_url))); - Portal* portal = portal_created_observer.WaitUntilPortalCreated(); - MockPortalWebContentsDelegate mock_delegate; - shell()->web_contents()->SetDelegate(&mock_delegate); - - base::RunLoop run_loop; - EXPECT_CALL(mock_delegate, - DoSwapWebContents(shell()->web_contents(), - portal->GetPortalContents(), _, _)) - .WillOnce(testing::DoAll( - testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit), - testing::ReturnNull())); - EXPECT_TRUE( - ExecJs(main_frame, "document.querySelector('portal').activate();")); - run_loop.Run(); -} - // Tests that a portal can be activated in content_shell. IN_PROC_BROWSER_TEST_F(PortalBrowserTest, ActivatePortalInShell) { EXPECT_TRUE(NavigateToURL(
diff --git a/content/browser/renderer_host/input/fling_browsertest.cc b/content/browser/renderer_host/input/fling_browsertest.cc index 0741032..f172974 100644 --- a/content/browser/renderer_host/input/fling_browsertest.cc +++ b/content/browser/renderer_host/input/fling_browsertest.cc
@@ -501,60 +501,6 @@ EXPECT_TRUE( router->forced_last_fling_start_target_to_stop_flinging_for_test()); } - -// Flaky, see https://crbug.com/850455 -#define MAYBE_ScrollEndGeneratedForFilteredFling \ - DISABLED_ScrollEndGeneratedForFilteredFling -IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, - MAYBE_ScrollEndGeneratedForFilteredFling) { - LoadURL(kTouchActionFilterDataURL); - - // Necessary for checking the ACK source of the sent events. The events are - // filtered when the Browser is the source. - auto scroll_begin_watcher = std::make_unique<InputMsgWatcher>( - GetWidgetHost(), blink::WebInputEvent::kGestureScrollBegin); - auto fling_start_watcher = std::make_unique<InputMsgWatcher>( - GetWidgetHost(), blink::WebInputEvent::kGestureFlingStart); - auto scroll_end_watcher = std::make_unique<InputMsgWatcher>( - GetWidgetHost(), blink::WebInputEvent::kGestureScrollEnd); - - // Do a horizontal touchscreen scroll followed by a fling. The GFS must get - // filtered since the GSB is filtered. - SyntheticSmoothScrollGestureParams params; - params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; - params.anchor = gfx::PointF(10, 10); - params.distances.push_back(gfx::Vector2d(-60, 0)); - params.prevent_fling = false; - - run_loop_ = std::make_unique<base::RunLoop>(); - - std::unique_ptr<SyntheticSmoothScrollGesture> gesture( - new SyntheticSmoothScrollGesture(params)); - GetWidgetHost()->QueueSyntheticGesture( - std::move(gesture), - base::BindOnce(&BrowserSideFlingBrowserTest::OnSyntheticGestureCompleted, - base::Unretained(this))); - - // Runs until we get the OnSyntheticGestureCompleted callback. - run_loop_->Run(); - - scroll_begin_watcher->GetAckStateWaitIfNecessary(); - EXPECT_EQ(InputEventAckSource::BROWSER, - scroll_begin_watcher->last_event_ack_source()); - - fling_start_watcher->GetAckStateWaitIfNecessary(); - EXPECT_EQ(InputEventAckSource::BROWSER, - fling_start_watcher->last_event_ack_source()); - - // Since the GFS is filtered. the input_router_impl will generate and forward - // a GSE to make sure that the scrolling sequence and the touch action filter - // state get reset properly. The generated GSE will also get filtered since - // its equivalent GSB is filtered. The test will timeout if the GSE is not - // generated. - scroll_end_watcher->GetAckStateWaitIfNecessary(); - EXPECT_EQ(InputEventAckSource::BROWSER, - scroll_end_watcher->last_event_ack_source()); -} #endif // !defined(OS_MACOSX) } // namespace content
diff --git a/content/browser/renderer_host/input/touch_action_filter.cc b/content/browser/renderer_host/input/touch_action_filter.cc index 6c13e1a..18bb05e 100644 --- a/content/browser/renderer_host/input/touch_action_filter.cc +++ b/content/browser/renderer_host/input/touch_action_filter.cc
@@ -256,7 +256,9 @@ break; case WebInputEvent::kGestureScrollEnd: - gesture_sequence_.clear(); + if (gesture_sequence_.size() >= 1000) + gesture_sequence_.erase(gesture_sequence_.begin(), + gesture_sequence_.end() - 250); gesture_sequence_in_progress_ = false; // Whenever there is a new touch start, white listed touch action will be // set. So it is fine to reset at GSE. @@ -350,6 +352,17 @@ gesture_sequence_.append("OY"); else gesture_sequence_.append("ON"); + if (compositor_touch_action_enabled_ && + !allowed_touch_action_.has_value() && + !white_listed_touch_action_.has_value()) { + static auto* crash_key = base::debug::AllocateCrashKeyString( + "tapdown-gestures", base::debug::CrashKeySize::Size256); + if (gesture_sequence_.size() >= 256) + gesture_sequence_.erase(gesture_sequence_.begin(), + gesture_sequence_.end() - 256); + base::debug::SetCrashKeyString(crash_key, gesture_sequence_); + gesture_sequence_.clear(); + } // TODO(xidachen): investigate why the touch action has no value. if (compositor_touch_action_enabled_ && !touch_action.has_value()) SetTouchAction(cc::kTouchActionAuto);
diff --git a/content/browser/renderer_host/render_widget_host_delegate.cc b/content/browser/renderer_host/render_widget_host_delegate.cc index 3b51afe5..1c9aa4c 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.cc +++ b/content/browser/renderer_host/render_widget_host_delegate.cc
@@ -12,14 +12,6 @@ namespace content { -bool RenderWidgetHostDelegate::DoBrowserControlsShrinkRendererSize() const { - return false; -} - -int RenderWidgetHostDelegate::GetTopControlsHeight() const { - return 0; -} - KeyboardEventProcessingResult RenderWidgetHostDelegate::PreHandleKeyboardEvent( const NativeWebKeyboardEvent& event) { return KeyboardEventProcessingResult::NOT_HANDLED;
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h index aef0cf02..688a332 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.h +++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -61,8 +61,6 @@ virtual void SetTopControlsShownRatio( RenderWidgetHostImpl* render_widget_host, float ratio) {} - virtual bool DoBrowserControlsShrinkRendererSize() const; - virtual int GetTopControlsHeight() const; virtual void SetTopControlsGestureScrollInProgress(bool in_progress) {} // The RenderWidgetHost has just been created.
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 316e7cf..43baa4c 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -872,23 +872,37 @@ visual_properties->page_scale_factor = page_scale_factor_; if (view_) { + // TODO(danakj): Move this browser controls code out of the if-view block? + if (delegate_) { + RenderViewHostDelegateView* rvh_delegate_view = + delegate_->GetDelegateView(); + DCHECK(rvh_delegate_view); + + visual_properties->browser_controls_shrink_blink_size = + rvh_delegate_view->DoBrowserControlsShrinkRendererSize(); + + float top_controls_height = rvh_delegate_view->GetTopControlsHeight(); + float bottom_controls_height = + rvh_delegate_view->GetBottomControlsHeight(); + float browser_controls_dsf_multiplier = 1.f; + // The top and bottom control sizes are physical pixels but the IPC wants + // DIPs *when not using page zoom for DSF* because blink layout is working + // in DIPs then. + if (!IsUseZoomForDSFEnabled()) { + browser_controls_dsf_multiplier = + visual_properties->screen_info.device_scale_factor; + } + visual_properties->top_controls_height = + top_controls_height / browser_controls_dsf_multiplier; + visual_properties->bottom_controls_height = + bottom_controls_height / browser_controls_dsf_multiplier; + } + visual_properties->new_size = view_->GetRequestedRendererSize(); visual_properties->capture_sequence_number = view_->GetCaptureSequenceNumber(); visual_properties->compositor_viewport_pixel_size = view_->GetCompositorViewportPixelSize(); - visual_properties->top_controls_height = view_->GetTopControlsHeight(); - visual_properties->bottom_controls_height = - view_->GetBottomControlsHeight(); - if (!IsUseZoomForDSFEnabled()) { - float device_scale = visual_properties->screen_info.device_scale_factor; - if (device_scale != 0.f) { - visual_properties->top_controls_height /= device_scale; - visual_properties->bottom_controls_height /= device_scale; - } - } - visual_properties->browser_controls_shrink_blink_size = - view_->DoBrowserControlsShrinkRendererSize(); visual_properties->visible_viewport_size = view_->GetVisibleViewportSize(); // TODO(ccameron): GetLocalSurfaceId is not synchronized with the device // scale factor of the surface. Fix this.
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index 453a9d24..1492a21 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -334,9 +334,7 @@ acked_event_count_(0), gesture_event_type_(-1), use_fake_compositor_viewport_pixel_size_(false), - ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN), - top_controls_height_(0.f), - bottom_controls_height_(0.f) { + ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN) { local_surface_id_allocator_.GenerateId(); } @@ -361,14 +359,6 @@ *screen_info = screen_info_; } - void set_top_controls_height(float top_controls_height) { - top_controls_height_ = top_controls_height; - } - - void set_bottom_controls_height(float bottom_controls_height) { - bottom_controls_height_ = bottom_controls_height; - } - const WebTouchEvent& acked_event() const { return acked_event_; } int acked_event_count() const { return acked_event_count_; } void ClearAckedEvent() { @@ -409,10 +399,6 @@ // RenderWidgetHostView override. gfx::Rect GetViewBounds() const override { return bounds_; } - float GetTopControlsHeight() const override { return top_controls_height_; } - float GetBottomControlsHeight() const override { - return bottom_controls_height_; - } const viz::LocalSurfaceIdAllocation& GetLocalSurfaceIdAllocation() const override { return local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation(); @@ -454,8 +440,6 @@ bool use_fake_compositor_viewport_pixel_size_; gfx::Size mock_compositor_viewport_pixel_size_; InputEventAckState ack_result_; - float top_controls_height_; - float bottom_controls_height_; viz::BeginFrameAck last_did_not_produce_frame_ack_; viz::ParentLocalSurfaceIdAllocator local_surface_id_allocator_; ScreenInfo screen_info_;
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 575ff95..93a418bcb 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -504,22 +504,6 @@ return view_.GetPhysicalBackingSize(); } -bool RenderWidgetHostViewAndroid::DoBrowserControlsShrinkRendererSize() const { - auto* delegate_view = GetRenderViewHostDelegateView(); - return delegate_view ? delegate_view->DoBrowserControlsShrinkRendererSize() - : false; -} - -float RenderWidgetHostViewAndroid::GetTopControlsHeight() const { - auto* delegate_view = GetRenderViewHostDelegateView(); - return delegate_view ? delegate_view->GetTopControlsHeight() : 0.f; -} - -float RenderWidgetHostViewAndroid::GetBottomControlsHeight() const { - auto* delegate_view = GetRenderViewHostDelegateView(); - return delegate_view ? delegate_view->GetBottomControlsHeight() : 0.f; -} - int RenderWidgetHostViewAndroid::GetMouseWheelMinimumGranularity() const { auto* window = view_.GetWindowAndroid(); if (!window) @@ -1553,8 +1537,12 @@ void RenderWidgetHostViewAndroid::TransformPointToRootSurface( gfx::PointF* point) { - *point += gfx::Vector2d( - 0, DoBrowserControlsShrinkRendererSize() ? GetTopControlsHeight() : 0); + if (!host()->delegate()) + return; + RenderViewHostDelegateView* rvh_delegate_view = + host()->delegate()->GetDelegateView(); + if (rvh_delegate_view->DoBrowserControlsShrinkRendererSize()) + *point += gfx::Vector2d(0, rvh_delegate_view->GetTopControlsHeight()); } // TODO(jrg): Find out the implications and answer correctly here, @@ -1597,12 +1585,6 @@ gesture_listener_manager_->GestureEventAck(event, ack_result); } -RenderViewHostDelegateView* -RenderWidgetHostViewAndroid::GetRenderViewHostDelegateView() const { - RenderWidgetHostDelegate* delegate = host()->delegate(); - return delegate ? delegate->GetDelegateView() : nullptr; -} - InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent( const blink::WebInputEvent& input_event) { if (overscroll_controller_ &&
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index a70fe2f9..de49eae 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -119,9 +119,6 @@ base::OnceCallback<void(const SkBitmap&)> callback) override; void EnsureSurfaceSynchronizedForWebTest() override; uint32_t GetCaptureSequenceNumber() const override; - bool DoBrowserControlsShrinkRendererSize() const override; - float GetTopControlsHeight() const override; - float GetBottomControlsHeight() const override; int GetMouseWheelMinimumGranularity() const override; void UpdateCursor(const WebCursor& cursor) override; void SetIsLoading(bool is_loading) override; @@ -405,7 +402,6 @@ float mouse_down_y); WebContentsAccessibilityAndroid* GetWebContentsAccessibilityAndroid() const; - RenderViewHostDelegateView* GetRenderViewHostDelegateView() const; void OnFocusInternal(); void LostFocusInternal();
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index cffe395..c037ef3 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -844,15 +844,6 @@ return latest_capture_sequence_number_; } -bool RenderWidgetHostViewAura::DoBrowserControlsShrinkRendererSize() const { - return host()->delegate() && - host()->delegate()->DoBrowserControlsShrinkRendererSize(); -} - -float RenderWidgetHostViewAura::GetTopControlsHeight() const { - return host()->delegate() ? host()->delegate()->GetTopControlsHeight() : 0; -} - void RenderWidgetHostViewAura::CopyFromSurface( const gfx::Rect& src_subrect, const gfx::Size& dst_size,
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 44e7879..fb40b669 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -137,8 +137,6 @@ void SetTooltipText(const base::string16& tooltip_text) override; void DisplayTooltipText(const base::string16& tooltip_text) override; uint32_t GetCaptureSequenceNumber() const override; - bool DoBrowserControlsShrinkRendererSize() const override; - float GetTopControlsHeight() const override; bool IsSurfaceAvailableForCopy() const override; void CopyFromSurface( const gfx::Rect& src_rect,
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index 7e2761a..318a27b 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -145,14 +145,6 @@ GetDeviceScaleFactor()); } -bool RenderWidgetHostViewBase::DoBrowserControlsShrinkRendererSize() const { - return false; -} - -float RenderWidgetHostViewBase::GetTopControlsHeight() const { - return 0.f; -} - void RenderWidgetHostViewBase::SelectionBoundsChanged( const WidgetHostMsg_SelectionBounds_Params& params) { #if !defined(OS_ANDROID) @@ -163,10 +155,6 @@ #endif } -float RenderWidgetHostViewBase::GetBottomControlsHeight() const { - return 0.f; -} - int RenderWidgetHostViewBase::GetMouseWheelMinimumGranularity() const { // Most platforms can specify the floating-point delta in the wheel event so // they don't have a minimum granularity. Android is currently the only
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index b7febba..e36a58a2 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -224,16 +224,6 @@ // The size of the view's backing surface in non-DPI-adjusted pixels. virtual gfx::Size GetCompositorViewportPixelSize() const; - // Whether or not the renderer's viewport size should be shrunk by the height - // of the URL-bar. - virtual bool DoBrowserControlsShrinkRendererSize() const; - - // The height of the URL-bar browser controls. - virtual float GetTopControlsHeight() const; - - // The height of the bottom bar. - virtual float GetBottomControlsHeight() const; - // If mouse wheels can only specify the number of ticks of some static // multiplier constant, this method returns that constant (in DIPs). If mouse // wheels can specify an arbitrary delta this returns 0.
diff --git a/content/browser/renderer_host/render_widget_host_view_cocoa.mm b/content/browser/renderer_host/render_widget_host_view_cocoa.mm index b72f2d8fc..24e931f 100644 --- a/content/browser/renderer_host/render_widget_host_view_cocoa.mm +++ b/content/browser/renderer_host/render_widget_host_view_cocoa.mm
@@ -302,6 +302,8 @@ replacementRange.location += textSelectionOffset_; [self insertText:selectedResult.replacementString replacementRange:replacementRange]; + + ui::LogTouchBarUMA(ui::TouchBarAction::TEXT_SUGGESTION); } - (void)candidateListTouchBarItem:(NSCandidateListTouchBarItem*)anItem
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index ee4c0da9..4c43834 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2201,14 +2201,6 @@ delegate_->SetTopControlsShownRatio(this, ratio); } -bool WebContentsImpl::DoBrowserControlsShrinkRendererSize() const { - return delegate_ && delegate_->DoBrowserControlsShrinkRendererSize(this); -} - -int WebContentsImpl::GetTopControlsHeight() const { - return delegate_ ? delegate_->GetTopControlsHeight() : 0; -} - void WebContentsImpl::SetTopControlsGestureScrollInProgress(bool in_progress) { if (delegate_) delegate_->SetTopControlsGestureScrollInProgress(in_progress); @@ -3254,9 +3246,8 @@ } bool WebContentsImpl::OnUpdateDragCursor() { - if (browser_plugin_embedder_) - return browser_plugin_embedder_->OnUpdateDragCursor(); - return false; + return browser_plugin_embedder_ && + browser_plugin_embedder_->OnUpdateDragCursor(); } bool WebContentsImpl::IsWidgetForMainFrame( @@ -3906,9 +3897,10 @@ float screen_y, blink::WebDragOperation operation, RenderWidgetHost* source_rwh) { - if (browser_plugin_embedder_.get()) + if (browser_plugin_embedder_) { browser_plugin_embedder_->DragSourceEndedAt( client_x, client_y, screen_x, screen_y, operation); + } if (source_rwh) { source_rwh->DragSourceEndedAt(gfx::PointF(client_x, client_y), gfx::PointF(screen_x, screen_y), operation); @@ -3968,7 +3960,7 @@ void WebContentsImpl::SystemDragEnded(RenderWidgetHost* source_rwh) { if (source_rwh) source_rwh->DragSourceSystemDragEnded(); - if (browser_plugin_embedder_.get()) + if (browser_plugin_embedder_) browser_plugin_embedder_->SystemDragEnded(); } @@ -4908,7 +4900,7 @@ void WebContentsImpl::OnBrowserPluginMessage(RenderFrameHost* render_frame_host, const IPC::Message& message) { - CHECK(!browser_plugin_embedder_.get()); + CHECK(!browser_plugin_embedder_); CreateBrowserPluginEmbedderIfNecessary(); browser_plugin_embedder_->OnMessageReceived(message, render_frame_host); } @@ -5487,8 +5479,7 @@ } void WebContentsImpl::RemoveBrowserPluginEmbedder() { - if (browser_plugin_embedder_) - browser_plugin_embedder_.reset(); + browser_plugin_embedder_.reset(); } RenderFrameHostImpl* WebContentsImpl::GetOuterWebContentsFrame() { @@ -6260,7 +6251,7 @@ // because this is a cross-process navigation, which means that it's a new // site that should not have to pay for the sins of its predecessor. // - // Note that we don't bother telling browser_plugin_embedder_ because the + // Note that we don't bother telling |browser_plugin_embedder_| because the // cross-process navigation will either destroy the browser plugins or not // require their dialogs to close. if (dialog_manager_) { @@ -6789,9 +6780,9 @@ base::Optional<gfx::Size> WebContentsImpl::GetFullscreenVideoSize() { base::Optional<WebContentsObserver::MediaPlayerId> id = media_web_contents_observer_->GetFullscreenVideoMediaPlayerId(); - if (id && cached_video_sizes_.count(id.value())) + if (id && base::ContainsKey(cached_video_sizes_, id.value())) return base::Optional<gfx::Size>(cached_video_sizes_[id.value()]); - return base::Optional<gfx::Size>(); + return base::nullopt; } int WebContentsImpl::GetCurrentlyPlayingVideoCount() {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 5afa1aa..91546771 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -16,6 +16,7 @@ #include <vector> #include "base/compiler_specific.h" +#include "base/containers/flat_map.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/observer_list.h" @@ -709,8 +710,6 @@ ukm::SourceId GetUkmSourceIdForLastCommittedSource() const override; void SetTopControlsShownRatio(RenderWidgetHostImpl* render_widget_host, float ratio) override; - bool DoBrowserControlsShrinkRendererSize() const override; - int GetTopControlsHeight() const override; void SetTopControlsGestureScrollInProgress(bool in_progress) override; void RenderWidgetCreated(RenderWidgetHostImpl* render_widget_host) override; void RenderWidgetDeleted(RenderWidgetHostImpl* render_widget_host) override; @@ -1815,7 +1814,8 @@ bool showing_context_menu_; int currently_playing_video_count_ = 0; - VideoSizeMap cached_video_sizes_; + base::flat_map<WebContentsObserver::MediaPlayerId, gfx::Size> + cached_video_sizes_; bool has_persistent_video_ = false;
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index 68fb77a4..3ae2cd8 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -1299,6 +1299,27 @@ return ConvertFromWeb(current_drag_op_); } +int WebContentsViewAura::GetTopControlsHeight() const { + WebContentsDelegate* delegate = web_contents_->GetDelegate(); + if (!delegate) + return 0; + return delegate->GetTopControlsHeight(); +} + +int WebContentsViewAura::GetBottomControlsHeight() const { + WebContentsDelegate* delegate = web_contents_->GetDelegate(); + if (!delegate) + return 0; + return delegate->GetBottomControlsHeight(); +} + +bool WebContentsViewAura::DoBrowserControlsShrinkRendererSize() const { + WebContentsDelegate* delegate = web_contents_->GetDelegate(); + if (!delegate) + return false; + return delegate->DoBrowserControlsShrinkRendererSize(web_contents_); +} + #if BUILDFLAG(USE_EXTERNAL_POPUP_MENU) void WebContentsViewAura::ShowPopupMenu(RenderFrameHost* render_frame_host, const gfx::Rect& bounds,
diff --git a/content/browser/web_contents/web_contents_view_aura.h b/content/browser/web_contents/web_contents_view_aura.h index 5fdd862..c917d91 100644 --- a/content/browser/web_contents/web_contents_view_aura.h +++ b/content/browser/web_contents/web_contents_view_aura.h
@@ -133,6 +133,9 @@ void GotFocus(RenderWidgetHostImpl* render_widget_host) override; void LostFocus(RenderWidgetHostImpl* render_widget_host) override; void TakeFocus(bool reverse) override; + int GetTopControlsHeight() const override; + int GetBottomControlsHeight() const override; + bool DoBrowserControlsShrinkRendererSize() const override; #if BUILDFLAG(USE_EXTERNAL_POPUP_MENU) void ShowPopupMenu(RenderFrameHost* render_frame_host, const gfx::Rect& bounds,
diff --git a/content/public/android/java/src/org/chromium/content/app/ContentChildProcessServiceDelegate.java b/content/public/android/java/src/org/chromium/content/app/ContentChildProcessServiceDelegate.java index e58907e..511b0596 100644 --- a/content/public/android/java/src/org/chromium/content/app/ContentChildProcessServiceDelegate.java +++ b/content/public/android/java/src/org/chromium/content/app/ContentChildProcessServiceDelegate.java
@@ -15,7 +15,6 @@ import org.chromium.base.CommandLine; import org.chromium.base.JNIUtils; import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; import org.chromium.base.UnguessableToken; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; @@ -25,10 +24,12 @@ import org.chromium.base.library_loader.ProcessInitException; import org.chromium.base.memory.MemoryPressureUma; import org.chromium.base.process_launcher.ChildProcessServiceDelegate; +import org.chromium.base.task.PostTask; import org.chromium.content.browser.ChildProcessCreationParamsImpl; import org.chromium.content.browser.ContentChildProcessConstants; import org.chromium.content.common.IGpuProcessCallback; import org.chromium.content.common.SurfaceWrapper; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.common.ContentProcessInfo; import org.chromium.content_public.common.ContentSwitches; @@ -172,7 +173,8 @@ @Override public void onBeforeMain() { nativeInitChildProcess(mCpuCount, mCpuFeatures); - ThreadUtils.postOnUiThread(() -> MemoryPressureUma.initializeForChildService()); + PostTask.postTask( + UiThreadTaskTraits.DEFAULT, () -> MemoryPressureUma.initializeForChildService()); } @Override
diff --git a/content/public/android/java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java index 164c0186..2c9ed9df 100644 --- a/content/public/android/java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java
@@ -20,8 +20,10 @@ import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.LoaderErrors; import org.chromium.base.library_loader.ProcessInitException; +import org.chromium.base.task.PostTask; import org.chromium.content.app.ContentMain; import org.chromium.content_public.browser.BrowserStartupController; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.ui.resources.ResourceExtractor; import java.lang.annotation.Retention; @@ -130,7 +132,7 @@ if (BuildInfo.isDebugAndroid()) { // Only set up the tracing broadcast receiver on debug builds of the OS. Normal tracing // should use the DevTools API. - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { addStartupCompletedObserver(new StartupCallback() {
diff --git a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java index c019cf6..bf644f0b 100644 --- a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java
@@ -13,6 +13,8 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.gfx.mojom.Rect; import org.chromium.media.mojom.AndroidOverlay; import org.chromium.media.mojom.AndroidOverlayClient; @@ -91,7 +93,7 @@ public void run() { dialogCore.initialize(context, config, mHoppingHost, asPanel); // Now that |mDialogCore| has been initialized, we are ready for token callbacks. - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { if (mNativeHandle != 0) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnection.java b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnection.java index 3f2f81f..89109d7 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnection.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnection.java
@@ -22,6 +22,8 @@ import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -215,7 +217,7 @@ return mCachedTextInputState; } assertOnImeThread(); - ThreadUtils.postOnUiThread(mRequestTextInputStateUpdate); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, mRequestTextInputStateUpdate); return blockAndGetStateUpdate(); } @@ -279,7 +281,7 @@ } private void notifyUserAction() { - ThreadUtils.postOnUiThread(mNotifyUserActionRunnable); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, mNotifyUserActionRunnable); } /** @@ -298,7 +300,7 @@ @VisibleForTesting public boolean updateComposingText( final CharSequence text, final int newCursorPosition, final boolean isPendingAccent) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { updateComposingTextOnUiThread(text, newCursorPosition, isPendingAccent); @@ -329,7 +331,7 @@ beginBatchEdit(); // Clear the current composition range (the keypress alone wouldn't do this). commitText("", 1); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { mImeAdapter.sendSyntheticKeyPress(KeyEvent.KEYCODE_ENTER, @@ -340,7 +342,7 @@ return true; } - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { commitTextOnUiThread(text, newCursorPosition); @@ -361,7 +363,7 @@ @Override public boolean performEditorAction(final int actionCode) { if (DEBUG_LOGS) Log.i(TAG, "performEditorAction [%d]", actionCode); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { mImeAdapter.performEditorAction(actionCode); @@ -376,7 +378,7 @@ @Override public boolean performContextMenuAction(final int id) { if (DEBUG_LOGS) Log.i(TAG, "performContextMenuAction [%d]", id); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { mImeAdapter.performContextMenuAction(id); @@ -447,7 +449,7 @@ @Override public boolean deleteSurroundingText(final int beforeLength, final int afterLength) { if (DEBUG_LOGS) Log.i(TAG, "deleteSurroundingText [%d %d]", beforeLength, afterLength); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { if (mPendingAccent != 0) { @@ -468,7 +470,7 @@ if (DEBUG_LOGS) { Log.i(TAG, "deleteSurroundingTextInCodePoints [%d %d]", beforeLength, afterLength); } - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { if (mPendingAccent != 0) { @@ -486,7 +488,7 @@ @Override public boolean sendKeyEvent(final KeyEvent event) { if (DEBUG_LOGS) Log.i(TAG, "sendKeyEvent [%d %d]", event.getAction(), event.getKeyCode()); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { if (handleCombiningAccentOnUiThread(event)) return; @@ -568,7 +570,7 @@ if (DEBUG_LOGS) Log.i(TAG, "finishComposingText"); // This is the only function that may be called on UI thread because // of direct calls from InputMethodManager. - ThreadUtils.postOnUiThread(mFinishComposingTextRunnable); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, mFinishComposingTextRunnable); return true; } @@ -582,7 +584,7 @@ @Override public boolean setSelection(final int start, final int end) { if (DEBUG_LOGS) Log.i(TAG, "setSelection [%d %d]", start, end); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { mImeAdapter.setEditableSelectionOffsets(start, end); @@ -597,7 +599,7 @@ @Override public boolean setComposingRegion(final int start, final int end) { if (DEBUG_LOGS) Log.i(TAG, "setComposingRegion [%d %d]", start, end); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { mImeAdapter.setComposingRegion(start, end); @@ -711,7 +713,7 @@ @Override public boolean requestCursorUpdates(final int cursorUpdateMode) { if (DEBUG_LOGS) Log.i(TAG, "requestCursorUpdates [%x]", cursorUpdateMode); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { mImeAdapter.onRequestCursorUpdates(cursorUpdateMode);
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/LGEmailActionModeWorkaroundImpl.java b/content/public/android/java/src/org/chromium/content/browser/selection/LGEmailActionModeWorkaroundImpl.java index 4901fa0..9d299a2 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/LGEmailActionModeWorkaroundImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/LGEmailActionModeWorkaroundImpl.java
@@ -20,7 +20,8 @@ import org.chromium.base.Log; import org.chromium.base.PackageUtils; -import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -103,7 +104,7 @@ @Override public void onDestroyActionMode(final ActionMode mode) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { c.onDestroyActionMode(mode); @@ -124,7 +125,7 @@ null, contentContainer, 150, new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { popupWindow.dismiss();
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/BrowserTaskExecutor.java b/content/public/android/java/src/org/chromium/content_public/browser/BrowserTaskExecutor.java index 2bca7dc..2857aa3e 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/BrowserTaskExecutor.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/BrowserTaskExecutor.java
@@ -47,6 +47,7 @@ // TODO(alexclarke): ThreadUtils.getUiThreadHandler shouldn't be in base. taskRunner = new SingleThreadTaskRunnerImpl(ThreadUtils.getUiThreadHandler(), taskTraits); + taskRunner.disableLifetimeCheck(); mTaskRunners.put(taskTraits, taskRunner); return taskRunner; }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java index b1a48db..b2e782bb 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/BrowserStartupControllerTest.java
@@ -18,8 +18,10 @@ import org.chromium.base.library_loader.LoaderErrors; import org.chromium.base.library_loader.ProcessInitException; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.task.PostTask; import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.content_public.browser.BrowserStartupController.StartupCallback; +import org.chromium.content_public.browser.UiThreadTaskTraits; /** * Test of BrowserStartupController @@ -71,7 +73,7 @@ private int kickOffStartup(boolean startServiceManagerOnly) { // Post to the UI thread to emulate what would happen in a real scenario. - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { if (!mServiceManagerStarted) {
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentTextSelectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentTextSelectionTest.java index 6039657..1e4f382 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentTextSelectionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentTextSelectionTest.java
@@ -20,6 +20,7 @@ import org.junit.runner.RunWith; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; @@ -28,6 +29,7 @@ import org.chromium.content.browser.input.ImeTestUtils; import org.chromium.content.browser.selection.SelectionPopupControllerImpl; import org.chromium.content_public.browser.SelectionClient; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner; import org.chromium.content_public.browser.test.util.Criteria; @@ -84,7 +86,8 @@ result = new SelectionClient.Result(); } - ThreadUtils.postOnUiThread(() -> mResultCallback.onClassified(result)); + PostTask.postTask( + UiThreadTaskTraits.DEFAULT, () -> mResultCallback.onClassified(result)); return true; }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/scheduler/NativePostTaskTest.java b/content/public/android/javatests/src/org/chromium/content/browser/scheduler/NativePostTaskTest.java index fcfc254..d4081fa 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/scheduler/NativePostTaskTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/scheduler/NativePostTaskTest.java
@@ -77,13 +77,10 @@ public void testNativePostDelayedTask() throws Exception { final Object lock = new Object(); final AtomicBoolean taskExecuted = new AtomicBoolean(); - PostTask.postDelayedTask(new TaskTraits(), new Runnable() { - @Override - public void run() { - synchronized (lock) { - taskExecuted.set(true); - lock.notify(); - } + PostTask.postDelayedTask(new TaskTraits(), () -> { + synchronized (lock) { + taskExecuted.set(true); + lock.notify(); } }, 1);
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/scheduler/UiThreadSchedulerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/scheduler/UiThreadSchedulerTest.java index c7eb954..b117056b 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/scheduler/UiThreadSchedulerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/scheduler/UiThreadSchedulerTest.java
@@ -113,7 +113,6 @@ Assert.assertTrue(ThreadUtils.runningOnUiThread()); } }); - SchedulerTestHelpers.postTaskAndBlockUntilRun(uiThreadTaskRunner); } finally { uiThreadTaskRunner.destroy();
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java index 8fee992..7cad67b 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java
@@ -17,11 +17,13 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.process_launcher.ChildProcessConnection; +import org.chromium.base.task.PostTask; import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.UrlUtils; import org.chromium.content.browser.ChildProcessLauncherHelperImpl; import org.chromium.content_public.browser.ChildProcessImportance; import org.chromium.content_public.browser.RenderFrameHost; +import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsStatics; import org.chromium.content_shell.Shell; @@ -350,7 +352,7 @@ mActivityTestRule.waitForActiveShellToBeDoneLoading(); final WebContents webContents = activity.getActiveWebContents(); - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { RenderFrameHost frameHost = webContents.getMainFrame();
diff --git a/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java b/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java index 23c8fb2c..27437bd 100644 --- a/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java +++ b/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java
@@ -36,8 +36,10 @@ import org.robolectric.annotation.Config; import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.Feature; +import org.chromium.content_public.browser.UiThreadTaskTraits; import java.util.concurrent.Callable; @@ -186,7 +188,7 @@ public void testRendererCannotUpdateState() { when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(true); // We found that renderer cannot update state, e.g., due to a crash. - ThreadUtils.postOnUiThread(new Runnable() { + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { @Override public void run() { try {
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index 33c67fd..2230284 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -27,7 +27,6 @@ #include "content/public/browser/screen_orientation_delegate.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/visibility.h" -#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_ui.h" #include "content/public/common/stop_find_action.h" #include "third_party/blink/public/common/frame/sandbox_flags.h" @@ -879,9 +878,6 @@ virtual int GetCurrentlyPlayingVideoCount() = 0; - // Returns a map containing the sizes of all currently playing videos. - using VideoSizeMap = - base::flat_map<WebContentsObserver::MediaPlayerId, gfx::Size>; virtual base::Optional<gfx::Size> GetFullscreenVideoSize() = 0; virtual bool IsFullscreen() = 0;
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index d318223..075425da 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h
@@ -201,12 +201,12 @@ IPC_STRUCT_TRAITS_MEMBER(text_track_text_color) IPC_STRUCT_TRAITS_MEMBER(text_autosizing_enabled) IPC_STRUCT_TRAITS_MEMBER(double_tap_to_zoom_enabled) + IPC_STRUCT_TRAITS_MEMBER(web_app_scope) #if defined(OS_ANDROID) IPC_STRUCT_TRAITS_MEMBER(font_scale_factor) IPC_STRUCT_TRAITS_MEMBER(device_scale_adjustment) IPC_STRUCT_TRAITS_MEMBER(force_enable_zoom) IPC_STRUCT_TRAITS_MEMBER(fullscreen_supported) - IPC_STRUCT_TRAITS_MEMBER(web_app_scope) IPC_STRUCT_TRAITS_MEMBER(default_video_poster_url) IPC_STRUCT_TRAITS_MEMBER(support_deprecated_target_density_dpi) IPC_STRUCT_TRAITS_MEMBER(use_legacy_background_size_shorthand_behavior)
diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h index 579c086..52edd1a 100644 --- a/content/public/common/web_preferences.h +++ b/content/public/common/web_preferences.h
@@ -226,12 +226,14 @@ bool text_autosizing_enabled; + // Representation of the Web App Manifest scope if any. + GURL web_app_scope; + #if defined(OS_ANDROID) float font_scale_factor; float device_scale_adjustment; bool force_enable_zoom; bool fullscreen_supported; - GURL web_app_scope; GURL default_video_poster_url; bool support_deprecated_target_density_dpi; bool use_legacy_background_size_shorthand_behavior;
diff --git a/content/public/test/web_contents_tester.h b/content/public/test/web_contents_tester.h index ca36d6e..c041587 100644 --- a/content/public/test/web_contents_tester.h +++ b/content/public/test/web_contents_tester.h
@@ -12,6 +12,7 @@ #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom.h" +#include "third_party/blink/public/platform/web_input_event.h" #include "ui/base/page_transition_types.h" class GURL;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index ce6ce32..24d1e1d 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -498,8 +498,6 @@ "renderer_webapplicationcachehost_impl.h", "renderer_webcookiejar_impl.cc", "renderer_webcookiejar_impl.h", - "resizing_mode_selector.cc", - "resizing_mode_selector.h", "resource_timing_info_conversions.cc", "resource_timing_info_conversions.h", "sad_plugin.cc",
diff --git a/content/renderer/media/stream/media_stream_center.cc b/content/renderer/media/stream/media_stream_center.cc index c3ab43fd..af27d64 100644 --- a/content/renderer/media/stream/media_stream_center.cc +++ b/content/renderer/media/stream/media_stream_center.cc
@@ -20,8 +20,8 @@ #include "content/renderer/media/webrtc_local_audio_source_provider.h" #include "media/base/sample_format.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h" -#include "third_party/blink/public/platform/modules/mediastream/platform_media_stream_source.h" #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h" +#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h" #include "third_party/blink/public/platform/web_media_constraints.h" #include "third_party/blink/public/platform/web_media_stream.h" #include "third_party/blink/public/platform/web_media_stream_source.h"
diff --git a/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc b/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc index 8a49e26..d7f995e 100644 --- a/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc +++ b/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc
@@ -19,7 +19,7 @@ #include "media/base/audio_parameters.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" -#include "third_party/blink/public/platform/modules/mediastream/platform_media_stream_source.h" +#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h" #include "third_party/blink/public/platform/web_media_constraints.h" #include "third_party/blink/public/platform/web_string.h"
diff --git a/content/renderer/media/stream/media_stream_constraints_util_video_content_unittest.cc b/content/renderer/media/stream/media_stream_constraints_util_video_content_unittest.cc index 6116220..1c21c971 100644 --- a/content/renderer/media/stream/media_stream_constraints_util_video_content_unittest.cc +++ b/content/renderer/media/stream/media_stream_constraints_util_video_content_unittest.cc
@@ -11,7 +11,7 @@ #include "content/renderer/media/stream/mock_constraint_factory.h" #include "media/base/limits.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/platform/modules/mediastream/platform_media_stream_source.h" +#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h" #include "third_party/blink/public/platform/web_media_constraints.h" namespace content {
diff --git a/content/renderer/media/stream/media_stream_video_source.h b/content/renderer/media/stream/media_stream_video_source.h index ec92006..4d7a98f 100644 --- a/content/renderer/media/stream/media_stream_video_source.h +++ b/content/renderer/media/stream/media_stream_video_source.h
@@ -19,8 +19,8 @@ #include "media/capture/video_capture_types.h" #include "third_party/blink/public/common/media/video_capture.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_types.h" -#include "third_party/blink/public/platform/modules/mediastream/platform_media_stream_source.h" #include "third_party/blink/public/platform/modules/mediastream/secure_display_link_tracker.h" +#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h" #include "third_party/blink/public/platform/web_media_constraints.h" #include "third_party/blink/public/platform/web_media_stream_source.h" #include "third_party/blink/public/platform/web_media_stream_track.h"
diff --git a/content/renderer/media/stream/user_media_processor.h b/content/renderer/media/stream/user_media_processor.h index d8970c0..cbc0b25 100644 --- a/content/renderer/media/stream/user_media_processor.h +++ b/content/renderer/media/stream/user_media_processor.h
@@ -19,7 +19,7 @@ #include "content/renderer/media/stream/media_stream_dispatcher_eventhandler.h" #include "third_party/blink/public/mojom/mediastream/media_devices.mojom.h" #include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h" -#include "third_party/blink/public/platform/modules/mediastream/platform_media_stream_source.h" +#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h" #include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/public/web/web_user_media_request.h"
diff --git a/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc index c1ee6ff..20d0151 100644 --- a/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc +++ b/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
@@ -39,7 +39,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h" -#include "third_party/blink/public/platform/modules/mediastream/platform_media_stream_source.h" +#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/web_media_constraints.h" #include "third_party/blink/public/platform/web_media_stream.h"
diff --git a/content/renderer/media_recorder/video_track_recorder_unittest.cc b/content/renderer/media_recorder/video_track_recorder_unittest.cc index bbe1552..9cf00d4 100644 --- a/content/renderer/media_recorder/video_track_recorder_unittest.cc +++ b/content/renderer/media_recorder/video_track_recorder_unittest.cc
@@ -72,7 +72,7 @@ blink::WebString::FromASCII("dummy")); blink_source_.Initialize(webkit_track_id, blink::WebMediaStreamSource::kTypeVideo, - webkit_track_id); + webkit_track_id, false /*remote*/); blink_source_.SetPlatformSource(base::WrapUnique(mock_source_)); blink_track_.Initialize(blink_source_);
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index f4ed0b0..318f5078 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -88,7 +88,6 @@ #include "content/renderer/render_widget_fullscreen_pepper.h" #include "content/renderer/renderer_blink_platform_impl.h" #include "content/renderer/renderer_webapplicationcachehost_impl.h" -#include "content/renderer/resizing_mode_selector.h" #include "content/renderer/savable_resources.h" #include "content/renderer/v8_value_converter_impl.h" #include "content/renderer/web_ui_extension_data.h" @@ -822,6 +821,8 @@ static_cast<blink::WebEffectiveConnectionType>( prefs.network_quality_estimator_web_holdback)); + settings->SetWebAppScope(WebString::FromASCII(prefs.web_app_scope.spec())); + #if defined(OS_ANDROID) settings->SetAllowCustomScrollbarInMainFrame(false); settings->SetAccessibilityFontScaleFactor(prefs.font_scale_factor); @@ -829,7 +830,6 @@ settings->SetFullscreenSupported(prefs.fullscreen_supported); web_view->SetIgnoreViewportTagScaleLimits(prefs.force_enable_zoom); settings->SetAutoZoomFocusedNodeToLegibleScale(true); - settings->SetWebAppScope(WebString::FromASCII(prefs.web_app_scope.spec())); settings->SetDefaultVideoPosterURL( WebString::FromASCII(prefs.default_video_poster_url.spec())); settings->SetSupportDeprecatedTargetDensityDPI(
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 3013a52..234f5d0 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -73,7 +73,6 @@ #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_view_impl.h" #include "content/renderer/renderer_blink_platform_impl.h" -#include "content/renderer/resizing_mode_selector.h" #include "gpu/command_buffer/service/gpu_switches.h" #include "ipc/ipc_message_start.h" #include "ipc/ipc_sync_message.h" @@ -421,7 +420,6 @@ monitor_composition_info_(false), popup_origin_scale_for_emulation_(0.f), frame_swap_message_queue_(new FrameSwapMessageQueue(routing_id_)), - resizing_mode_selector_(new ResizingModeSelector()), has_host_context_menu_location_(false), has_focus_(false), for_child_local_root_frame_(false), @@ -777,8 +775,41 @@ bottom_controls_height_ = params.bottom_controls_height; } - if (!resizing_mode_selector_->ShouldAbortOnResize(this, params)) { + bool ignore_resize_ipc = false; + if (synchronous_resize_mode_for_testing_) { + // We can ignore browser-initialized resizing during synchronous + // (renderer-controlled) mode, unless it is switching us to/from + // fullsreen mode or changing the device scale factor. + // TODO(danakj): Does the browser actually change DSF inside a web test?? + // TODO(danakj): Isn't the display mode check redundant with the fullscreen + // one? + if (params.is_fullscreen_granted == is_fullscreen_granted_ && + params.display_mode == display_mode_ && + params.screen_info.device_scale_factor == + screen_info_.device_scale_factor) + ignore_resize_ipc = true; + } + + // When controlling the size in the renderer, we should ignore sizes given by + // the browser IPC here. + // TODO(danakj): There are many things also being ignored that aren't the + // widget's size params. It works because tests that use this mode don't + // change those parameters, I guess. But it's more complicated then because it + // looks like they are related to sync resize mode. Let's move them out of + // this block. + // TODO(danakj): It would be nice if we can still use the emulator to emulate + // things other than the size if we are in sync resize mode - if the emulator + // is even used in sync resize tests. It probably isn't though, so either way + // it'd be good to get the emulator out of this block (maybe by overwriting + // some of |params| in sync resize mode instead of just skipping the emulator. + if (!ignore_resize_ipc) { if (screen_metrics_emulator_) { + // This will call our SynchronizeVisualProperties() method with a + // different set of VisualProperties, holding emulated values. Though not + // all VisualProperties are modified by the metrics emulator, so it's a + // bit unclear to do this with the full structure. Anything it does not + // modify can be consumed directly here instead of in + // SynchronizeVisualProperties(). screen_metrics_emulator_->OnSynchronizeVisualProperties(params); } else { if (!delegate()) { @@ -1935,7 +1966,7 @@ WebRect window_rect = rect_in_screen; EmulatedToScreenRectIfNeeded(&window_rect); - if (resizing_mode_selector_->is_synchronous_mode()) { + if (synchronous_resize_mode_for_testing_) { // This is a web-test-only path. At one point, it was planned to be // removed. See https://crbug.com/309760. SetWindowRectSynchronously(window_rect); @@ -2523,7 +2554,7 @@ size_.height() != new_size_in_window.height) { size_ = gfx::Size(new_size_in_window.width, new_size_in_window.height); - if (resizing_mode_selector_->is_synchronous_mode()) { + if (synchronous_resize_mode_for_testing_) { gfx::Rect new_pos(WindowRect().x, WindowRect().y, size_.width(), size_.height()); widget_screen_rect_ = new_pos; @@ -3324,7 +3355,7 @@ } void RenderWidget::UseSynchronousResizeModeForTesting(bool enable) { - resizing_mode_selector_->set_is_synchronous_mode(enable); + synchronous_resize_mode_for_testing_ = enable; } void RenderWidget::SetDeviceScaleFactorForTesting(float factor) {
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 21145d23d..6db4199f 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -114,7 +114,6 @@ class RenderViewImpl; class RenderWidgetDelegate; class RenderWidgetScreenMetricsEmulator; -class ResizingModeSelector; class TextInputClientObserver; class WidgetInputHandlerManager; struct ContextMenuParams; @@ -889,6 +888,20 @@ // the RenderViewImpl, we freeze it instead. bool is_frozen_; + // In web tests, synchronous resizing mode may be used. Normally each widget's + // size is controlled by IPC from the browser. In synchronous resize mode the + // renderer controls the size directly, and IPCs from the browser must be + // ignored. This was deprecated but then later undeprecated, so it is now + // called unfortunate instead. See https://crbug.com/309760. When this is + // enabled the various size properties will be controlled directly when + // SetWindowRect() is called instead of needing a round trip through the + // browser. + // Note that SetWindowRectSynchronouslyForTesting() provides a secondary way + // to control the size of the RenderWidget independently from the renderer + // process, without the use of this mode, however it would be overridden by + // the browser if they disagree. + bool synchronous_resize_mode_for_testing_ = false; + // Stores information about the current text input. blink::WebTextInputInfo text_input_info_; @@ -949,7 +962,6 @@ float popup_origin_scale_for_emulation_; scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue_; - std::unique_ptr<ResizingModeSelector> resizing_mode_selector_; // Lists of RenderFrameProxy objects that need to be notified of // compositing-related events (e.g. DidCommitCompositorFrame).
diff --git a/content/renderer/resizing_mode_selector.cc b/content/renderer/resizing_mode_selector.cc deleted file mode 100644 index cc16b16..0000000 --- a/content/renderer/resizing_mode_selector.cc +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/resizing_mode_selector.h" - -#include "content/common/view_messages.h" -#include "content/renderer/render_thread_impl.h" -#include "content/renderer/render_widget.h" - -namespace content { - -ResizingModeSelector::ResizingModeSelector() : is_synchronous_mode_(false) {} - -bool ResizingModeSelector::NeverUsesSynchronousResize() const { - return !RenderThreadImpl::current() || // can be NULL when in unit tests - !RenderThreadImpl::current()->web_test_mode(); -} - -bool ResizingModeSelector::ShouldAbortOnResize( - RenderWidget* widget, - const VisualProperties& visual_properties) { - if (!is_synchronous_mode_) - return false; - if (visual_properties.is_fullscreen_granted != - widget->is_fullscreen_granted()) - return false; - if (visual_properties.display_mode != widget->display_mode()) - return false; - return visual_properties.screen_info.device_scale_factor == - widget->screen_info().device_scale_factor; -} - -void ResizingModeSelector::set_is_synchronous_mode(bool mode) { - is_synchronous_mode_ = mode; -} - -bool ResizingModeSelector::is_synchronous_mode() const { - return is_synchronous_mode_; -} - -} // namespace content
diff --git a/content/renderer/resizing_mode_selector.h b/content/renderer/resizing_mode_selector.h deleted file mode 100644 index 1743fba..0000000 --- a/content/renderer/resizing_mode_selector.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_RESIZING_MODE_SELECTOR_H_ -#define CONTENT_RENDERER_RESIZING_MODE_SELECTOR_H_ - -#include "base/macros.h" - -namespace content { - -class RenderWidget; -struct VisualProperties; - -// Enables switching between two modes of resizing: -// 1) The "normal" (asynchronous) resizing, which involves sending messages to -// and receiving them from host; and -// 2) The synchronous mode, which short-circuits the resizing logic to operate -// strictly inside renderer. -// The latter is necessary to support a handful of web tests that were -// written with the expectation of a synchronous resize, and we're going to -// eventually rewrite or remove all of them. See http://crbug.com/309760 for -// details. -class ResizingModeSelector { - public: - ResizingModeSelector(); - bool NeverUsesSynchronousResize() const; - bool ShouldAbortOnResize(RenderWidget* widget, - const VisualProperties& visual_properties); - - void set_is_synchronous_mode(bool mode); - bool is_synchronous_mode() const; - - private: - bool is_synchronous_mode_; - - DISALLOW_COPY_AND_ASSIGN(ResizingModeSelector); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_RESIZING_MODE_SELECTOR_H_
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 0d5edc2..bdf583e 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -259,6 +259,7 @@ "storage_partition_test_utils.h", "stub_layer_tree_view_delegate.cc", "stub_layer_tree_view_delegate.h", + "stub_render_view_host_delegate_view.h", "stub_render_widget_host_owner_delegate.cc", "stub_render_widget_host_owner_delegate.h", "test_background_sync_context.cc",
diff --git a/content/test/data/accessibility/aria/aria-col-attr.html b/content/test/data/accessibility/aria/aria-col-attr.html index a4782a6..39dc90c 100644 --- a/content/test/data/accessibility/aria/aria-col-attr.html +++ b/content/test/data/accessibility/aria/aria-col-attr.html
@@ -6,6 +6,9 @@ @BLINK-ALLOW:ariaColumn* @BLINK-ALLOW:ariaCellColumn* --> +<!-- For compatibility with earlier versions of Jaws, We do not expose + aria-row/colcount and aria-row/colindex information if they match the + physical coordinates of the table. --> <div role="grid" aria-colcount="5"> <div role="row"> <span role="columnheader" aria-colindex="2" aria-colspan="2">cell 2</span>
diff --git a/content/test/data/accessibility/aria/aria-row-attr.html b/content/test/data/accessibility/aria/aria-row-attr.html index 1b5e6299..a906d6b 100644 --- a/content/test/data/accessibility/aria/aria-row-attr.html +++ b/content/test/data/accessibility/aria/aria-row-attr.html
@@ -6,6 +6,9 @@ @BLINK-ALLOW:ariaRow* @BLINK-ALLOW:ariaCellRow* --> +<!-- For compatibility with earlier versions of Jaws, We do not expose + aria-row/colcount and aria-row/colindex information if they match the + physical coordinates of the table. --> <div role="grid" aria-rowcount="5"> <div role="row"> <span role="columnheader" aria-rowindex="3">cell 2</span>
diff --git a/content/test/data/accessibility/aria/table-column-hidden-expected-blink.txt b/content/test/data/accessibility/aria/table-column-hidden-expected-blink.txt index 8c812f5..88f459b 100644 --- a/content/test/data/accessibility/aria/table-column-hidden-expected-blink.txt +++ b/content/test/data/accessibility/aria/table-column-hidden-expected-blink.txt
@@ -1,33 +1,33 @@ rootWebArea -++grid ariaColumnCount=4 ariaRowCount=3 tableRowCount=3 tableColumnCount=3 +++grid ariaColumnCount=5 ariaRowCount=4 tableRowCount=3 tableColumnCount=3 ++++row selected=false -++++++columnHeader name='Month' ariaCellColumnIndex=1 ariaCellRowIndex=1 selected=false +++++++columnHeader name='Month' ariaCellColumnIndex=2 ariaCellRowIndex=2 selected=false ++++++++staticText name='Month' ++++++++++inlineTextBox name='Month' -++++++columnHeader name='Day' ariaCellColumnIndex=2 ariaCellRowIndex=1 selected=false +++++++columnHeader name='Day' ariaCellColumnIndex=3 ariaCellRowIndex=2 selected=false ++++++++staticText name='Day' ++++++++++inlineTextBox name='Day' -++++++columnHeader name='Weather' ariaCellColumnIndex=4 ariaCellRowIndex=1 selected=false +++++++columnHeader name='Weather' ariaCellColumnIndex=5 ariaCellRowIndex=2 selected=false ++++++++staticText name='Weather' ++++++++++inlineTextBox name='Weather' ++++row selected=false -++++++cell name='January' ariaCellColumnIndex=1 ariaCellRowIndex=2 selected=false +++++++cell name='January' ariaCellColumnIndex=2 ariaCellRowIndex=3 selected=false ++++++++staticText name='January' ++++++++++inlineTextBox name='January' -++++++cell name='01' ariaCellColumnIndex=2 ariaCellRowIndex=2 selected=false +++++++cell name='01' ariaCellColumnIndex=3 ariaCellRowIndex=3 selected=false ++++++++staticText name='01' ++++++++++inlineTextBox name='01' -++++++cell name='Sunny' ariaCellColumnIndex=4 ariaCellRowIndex=2 selected=false +++++++cell name='Sunny' ariaCellColumnIndex=5 ariaCellRowIndex=3 selected=false ++++++++staticText name='Sunny' ++++++++++inlineTextBox name='Sunny' ++++row selected=false -++++++cell name='January' ariaCellColumnIndex=1 ariaCellRowIndex=3 selected=false +++++++cell name='January' ariaCellColumnIndex=2 ariaCellRowIndex=4 selected=false ++++++++staticText name='January' ++++++++++inlineTextBox name='January' -++++++cell name='02' ariaCellColumnIndex=2 ariaCellRowIndex=3 selected=false +++++++cell name='02' ariaCellColumnIndex=3 ariaCellRowIndex=4 selected=false ++++++++staticText name='02' ++++++++++inlineTextBox name='02' -++++++cell name='Rainy' ariaCellColumnIndex=4 ariaCellRowIndex=3 selected=false +++++++cell name='Rainy' ariaCellColumnIndex=5 ariaCellRowIndex=4 selected=false ++++++++staticText name='Rainy' ++++++++++inlineTextBox name='Rainy' ++paragraph
diff --git a/content/test/data/accessibility/aria/table-column-hidden-expected-mac.txt b/content/test/data/accessibility/aria/table-column-hidden-expected-mac.txt index bf850ee..fc32f75 100644 --- a/content/test/data/accessibility/aria/table-column-hidden-expected-mac.txt +++ b/content/test/data/accessibility/aria/table-column-hidden-expected-mac.txt
@@ -1,25 +1,25 @@ AXWebArea -++AXTable AXARIAColumnCount='4' AXARIARowCount='3' +++AXTable AXARIAColumnCount='5' AXARIARowCount='4' ++++AXRow -++++++AXCell AXARIAColumnIndex='1' AXARIARowIndex='1' +++++++AXCell AXARIAColumnIndex='2' AXARIARowIndex='2' ++++++++AXStaticText AXValue='Month' -++++++AXCell AXARIAColumnIndex='2' AXARIARowIndex='1' +++++++AXCell AXARIAColumnIndex='3' AXARIARowIndex='2' ++++++++AXStaticText AXValue='Day' -++++++AXCell AXARIAColumnIndex='4' AXARIARowIndex='1' +++++++AXCell AXARIAColumnIndex='5' AXARIARowIndex='2' ++++++++AXStaticText AXValue='Weather' ++++AXRow -++++++AXCell AXARIAColumnIndex='1' AXARIARowIndex='2' +++++++AXCell AXARIAColumnIndex='2' AXARIARowIndex='3' ++++++++AXStaticText AXValue='January' -++++++AXCell AXARIAColumnIndex='2' AXARIARowIndex='2' +++++++AXCell AXARIAColumnIndex='3' AXARIARowIndex='3' ++++++++AXStaticText AXValue='01' -++++++AXCell AXARIAColumnIndex='4' AXARIARowIndex='2' +++++++AXCell AXARIAColumnIndex='5' AXARIARowIndex='3' ++++++++AXStaticText AXValue='Sunny' ++++AXRow -++++++AXCell AXARIAColumnIndex='1' AXARIARowIndex='3' +++++++AXCell AXARIAColumnIndex='2' AXARIARowIndex='4' ++++++++AXStaticText AXValue='January' -++++++AXCell AXARIAColumnIndex='2' AXARIARowIndex='3' +++++++AXCell AXARIAColumnIndex='3' AXARIARowIndex='4' ++++++++AXStaticText AXValue='02' -++++++AXCell AXARIAColumnIndex='4' AXARIARowIndex='3' +++++++AXCell AXARIAColumnIndex='5' AXARIARowIndex='4' ++++++++AXStaticText AXValue='Rainy' ++++AXColumn ++++AXColumn
diff --git a/content/test/data/accessibility/aria/table-column-hidden-expected-win.txt b/content/test/data/accessibility/aria/table-column-hidden-expected-win.txt index 6887c8a6..c7e8573 100644 --- a/content/test/data/accessibility/aria/table-column-hidden-expected-win.txt +++ b/content/test/data/accessibility/aria/table-column-hidden-expected-win.txt
@@ -1,25 +1,25 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE -++ROLE_SYSTEM_TABLE colcount:4 rowcount:3 +++ROLE_SYSTEM_TABLE colcount:5 rowcount:4 ++++ROLE_SYSTEM_ROW -++++++ROLE_SYSTEM_COLUMNHEADER name='Month' colindex:1 rowindex:1 +++++++ROLE_SYSTEM_COLUMNHEADER name='Month' colindex:2 rowindex:2 ++++++++ROLE_SYSTEM_STATICTEXT name='Month' -++++++ROLE_SYSTEM_COLUMNHEADER name='Day' colindex:2 rowindex:1 +++++++ROLE_SYSTEM_COLUMNHEADER name='Day' colindex:3 rowindex:2 ++++++++ROLE_SYSTEM_STATICTEXT name='Day' -++++++ROLE_SYSTEM_COLUMNHEADER name='Weather' colindex:4 rowindex:1 +++++++ROLE_SYSTEM_COLUMNHEADER name='Weather' colindex:5 rowindex:2 ++++++++ROLE_SYSTEM_STATICTEXT name='Weather' ++++ROLE_SYSTEM_ROW -++++++ROLE_SYSTEM_CELL name='January' FOCUSABLE colindex:1 rowindex:2 +++++++ROLE_SYSTEM_CELL name='January' FOCUSABLE colindex:2 rowindex:3 ++++++++ROLE_SYSTEM_STATICTEXT name='January' -++++++ROLE_SYSTEM_CELL name='01' FOCUSABLE colindex:2 rowindex:2 +++++++ROLE_SYSTEM_CELL name='01' FOCUSABLE colindex:3 rowindex:3 ++++++++ROLE_SYSTEM_STATICTEXT name='01' -++++++ROLE_SYSTEM_CELL name='Sunny' FOCUSABLE colindex:4 rowindex:2 +++++++ROLE_SYSTEM_CELL name='Sunny' FOCUSABLE colindex:5 rowindex:3 ++++++++ROLE_SYSTEM_STATICTEXT name='Sunny' ++++ROLE_SYSTEM_ROW -++++++ROLE_SYSTEM_CELL name='January' FOCUSABLE colindex:1 rowindex:3 +++++++ROLE_SYSTEM_CELL name='January' FOCUSABLE colindex:2 rowindex:4 ++++++++ROLE_SYSTEM_STATICTEXT name='January' -++++++ROLE_SYSTEM_CELL name='02' FOCUSABLE colindex:2 rowindex:3 +++++++ROLE_SYSTEM_CELL name='02' FOCUSABLE colindex:3 rowindex:4 ++++++++ROLE_SYSTEM_STATICTEXT name='02' -++++++ROLE_SYSTEM_CELL name='Rainy' FOCUSABLE colindex:4 rowindex:3 +++++++ROLE_SYSTEM_CELL name='Rainy' FOCUSABLE colindex:5 rowindex:4 ++++++++ROLE_SYSTEM_STATICTEXT name='Rainy' ++IA2_ROLE_PARAGRAPH ++++ROLE_SYSTEM_STATICTEXT name='done'
diff --git a/content/test/data/accessibility/aria/table-column-hidden.html b/content/test/data/accessibility/aria/table-column-hidden.html index 09b773d..40640e1d 100644 --- a/content/test/data/accessibility/aria/table-column-hidden.html +++ b/content/test/data/accessibility/aria/table-column-hidden.html
@@ -13,24 +13,27 @@ @BLINK-ALLOW:*RowCount* @BLINK-ALLOW:ariaCellRowIndex* --> -<table role="grid" aria-rowcount="3" aria-colcount="4"> +<!-- For compatibility with earlier versions of Jaws, We do not expose + aria-row/colcount and aria-row/colindex information if they match the + physical coordinates of the table. --> +<table role="grid" aria-rowcount="4" aria-colcount="5"> <tbody><tr> - <th aria-rowindex="1" aria-colindex="1">Month</th> - <th aria-rowindex="1" aria-colindex="2">Day</th> - <th aria-rowindex="1" aria-colindex="3">Year</th> - <th aria-rowindex="1" aria-colindex="4">Weather</th> + <th aria-rowindex="2" aria-colindex="2">Month</th> + <th aria-rowindex="2" aria-colindex="3">Day</th> + <th aria-rowindex="2" aria-colindex="4">Year</th> + <th aria-rowindex="2" aria-colindex="5">Weather</th> </tr> <tr> - <td role="gridcell" tabindex="0" aria-rowindex="2" aria-colindex="1">January</td> - <td role="gridcell" tabindex="-1" aria-rowindex="2" aria-colindex="2">01</td> - <td role="gridcell" tabindex="-1" aria-rowindex="2" aria-colindex="3">2017</td> - <td role="gridcell" tabindex="-1" aria-rowindex="2" aria-colindex="4">Sunny</td> + <td role="gridcell" tabindex="0" aria-rowindex="3" aria-colindex="2">January</td> + <td role="gridcell" tabindex="-1" aria-rowindex="3" aria-colindex="3">01</td> + <td role="gridcell" tabindex="-1" aria-rowindex="3" aria-colindex="4">2017</td> + <td role="gridcell" tabindex="-1" aria-rowindex="3" aria-colindex="5">Sunny</td> </tr> <tr> - <td role="gridcell" tabindex="0" aria-rowindex="3" aria-colindex="1">January</td> - <td role="gridcell" tabindex="-1" aria-rowindex="3" aria-colindex="2">02</td> - <td role="gridcell" tabindex="-1" aria-rowindex="3" aria-colindex="3">2017</td> - <td role="gridcell" tabindex="-1" aria-rowindex="3" aria-colindex="4">Rainy</td> + <td role="gridcell" tabindex="0" aria-rowindex="4" aria-colindex="2">January</td> + <td role="gridcell" tabindex="-1" aria-rowindex="4" aria-colindex="3">02</td> + <td role="gridcell" tabindex="-1" aria-rowindex="4" aria-colindex="4">2017</td> + <td role="gridcell" tabindex="-1" aria-rowindex="4" aria-colindex="5">Rainy</td> </tr> </tbody> </table> @@ -38,7 +41,7 @@ <script> // Hide the year column. - let cells = document.querySelectorAll('[aria-colindex="3"]'); + let cells = document.querySelectorAll('[aria-colindex="4"]'); for (let cell of cells) { cell.style.display = 'none'; }
diff --git a/content/test/data/accessibility/html/table-th-colheader-expected-win.txt b/content/test/data/accessibility/html/table-th-colheader-expected-win.txt index 4f1741c..32d89f1 100644 --- a/content/test/data/accessibility/html/table-th-colheader-expected-win.txt +++ b/content/test/data/accessibility/html/table-th-colheader-expected-win.txt
@@ -1,9 +1,9 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ++ROLE_SYSTEM_TABLE ++++ROLE_SYSTEM_ROW -++++++ROLE_SYSTEM_COLUMNHEADER name='Firstname' +++++++ROLE_SYSTEM_COLUMNHEADER name='Firstname' column_headers='<Firstname>' ++++++++ROLE_SYSTEM_STATICTEXT name='Firstname' -++++++ROLE_SYSTEM_COLUMNHEADER name='Lastname' +++++++ROLE_SYSTEM_COLUMNHEADER name='Lastname' column_headers='<Lastname>' ++++++++ROLE_SYSTEM_STATICTEXT name='Lastname' ++++ROLE_SYSTEM_ROW ++++++ROLE_SYSTEM_CELL name='Jill' column_headers='<Firstname>'
diff --git a/content/test/data/accessibility/html/table-th-rowheader-expected-win.txt b/content/test/data/accessibility/html/table-th-rowheader-expected-win.txt index 9fb75b5..335eb7a6 100644 --- a/content/test/data/accessibility/html/table-th-rowheader-expected-win.txt +++ b/content/test/data/accessibility/html/table-th-rowheader-expected-win.txt
@@ -1,12 +1,12 @@ ROLE_SYSTEM_DOCUMENT name='Table example - th rowheader' READONLY FOCUSABLE ++ROLE_SYSTEM_TABLE ++++ROLE_SYSTEM_ROW -++++++ROLE_SYSTEM_ROWHEADER name='Firstname' +++++++ROLE_SYSTEM_ROWHEADER name='Firstname' row_headers='<Firstname>' ++++++++ROLE_SYSTEM_STATICTEXT name='Firstname' ++++++ROLE_SYSTEM_CELL name='Jill' row_headers='<Firstname>' ++++++++ROLE_SYSTEM_STATICTEXT name='Jill' ++++ROLE_SYSTEM_ROW -++++++ROLE_SYSTEM_ROWHEADER name='Lastname' +++++++ROLE_SYSTEM_ROWHEADER name='Lastname' row_headers='<Lastname>' ++++++++ROLE_SYSTEM_STATICTEXT name='Lastname' ++++++ROLE_SYSTEM_CELL name='Smith' row_headers='<Lastname>' ++++++++ROLE_SYSTEM_STATICTEXT name='Smith'
diff --git a/content/test/data/gpu/pixel_video_context_loss.html b/content/test/data/gpu/pixel_video_context_loss.html index c146e50..6dd9c36 100644 --- a/content/test/data/gpu/pixel_video_context_loss.html +++ b/content/test/data/gpu/pixel_video_context_loss.html
@@ -34,40 +34,45 @@ }(); function CrashGpuProcess() { - // Create a canvas element and webgl context. + // Create a canvas element and webgl context -- without a context, we won't + // get a webglcontextlost event. var canvas = document.createElement('canvas'); var gl = canvas.getContext('webgl'); // Now wait for the context loss before starting video playback. canvas.addEventListener('webglcontextlost', function(e) { - // Now wait for the video to playback to play until the end end, by which - // point a frame should be visible onscreen. + // Now wait for the video to play until the end, by which point a frame + // should be visible on screen. video.addEventListener('ended', function(e) { - domAutomationController.send("SUCCESS"); + domAutomationController.send('SUCCESS'); }, false); video.play(); }, false); - // Essentially invokes chrome://gpucrash. + // Invokes chrome://gpucrash, which triggers a webglcontextlost event above. chrome.gpuBenchmarking.crashGpuProcess(); } function Main() { - video = document.getElementById("video"); + video = document.getElementById('video'); // Wait until we're sure a frame has been displayed before crashing GPU. video.addEventListener('canplaythrough', CrashGpuProcess, false); - // src needs to be set after listener is added. + // Add an error listener to avoid timeouts if playback fails. + video.addEventListener('error', function(e) { + console.log('Video playback failed: ' + e.code + ', "' + e.message + '"'); + domAutomationController.send('ERROR'); + }, false); + + // src needs to be set after listeners are added. video.src = QueryString.src; } </script> </head> <body onload="Main()"> <div id="container" style="position:absolute; top:0px; left:0px"> -<video class="nomargin" id="video" width="240" height="135"> -<source type="video/mp4"> -</video> +<video class="nomargin" id="video" width="240" height="135"></video> </div> </body> </html>
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index ca9744d7..86b15d96 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -421,6 +421,8 @@ ['linux', 'passthrough', 'opengl', 'nvidia'], bug=766918) self.Fail('deqp/functional/gles3/shaderoperator/common_functions_*.html', ['linux', 'passthrough', 'opengl', 'nvidia'], bug=793055) + self.Flaky('conformance/extensions/webgl-compressed-texture-s3tc.html', + ['linux', 'passthrough', 'opengl', 'nvidia'], bug=927407) # Passthrough command decoder / Linux / OpenGL / Intel self.Flaky('conformance/extensions/webgl-compressed-texture-s3tc.html',
diff --git a/content/test/mock_render_widget_host_delegate.cc b/content/test/mock_render_widget_host_delegate.cc index d45a5daa..8e7922a 100644 --- a/content/test/mock_render_widget_host_delegate.cc +++ b/content/test/mock_render_widget_host_delegate.cc
@@ -67,4 +67,8 @@ return is_fullscreen_; } +RenderViewHostDelegateView* MockRenderWidgetHostDelegate::GetDelegateView() { + return &rvh_delegate_view_; +} + } // namespace content
diff --git a/content/test/mock_render_widget_host_delegate.h b/content/test/mock_render_widget_host_delegate.h index 739770c..5cdc010 100644 --- a/content/test/mock_render_widget_host_delegate.h +++ b/content/test/mock_render_widget_host_delegate.h
@@ -12,6 +12,7 @@ #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/text_input_manager.h" #include "content/public/browser/keyboard_event_processing_result.h" +#include "content/test/stub_render_view_host_delegate_view.h" namespace content { @@ -51,6 +52,7 @@ void SendScreenRects() override; TextInputManager* GetTextInputManager() override; bool IsFullscreenForCurrentTab() override; + RenderViewHostDelegateView* GetDelegateView() override; private: std::unique_ptr<NativeWebKeyboardEvent> last_event_; @@ -61,6 +63,7 @@ RenderWidgetHostImpl* focused_widget_ = nullptr; KeyboardEventProcessingResult pre_handle_keyboard_event_result_ = KeyboardEventProcessingResult::NOT_HANDLED; + StubRenderViewHostDelegateView rvh_delegate_view_; DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHostDelegate); };
diff --git a/content/test/stub_render_view_host_delegate_view.h b/content/test/stub_render_view_host_delegate_view.h new file mode 100644 index 0000000..1fc64970 --- /dev/null +++ b/content/test/stub_render_view_host_delegate_view.h
@@ -0,0 +1,19 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_TEST_STUB_RENDER_VIEW_HOST_DELEGATE_VIEW_H_ +#define CONTENT_TEST_STUB_RENDER_VIEW_HOST_DELEGATE_VIEW_H_ + +#include "content/browser/renderer_host/render_view_host_delegate_view.h" + +namespace content { + +class StubRenderViewHostDelegateView : public RenderViewHostDelegateView { + // The class already implements every method as a stub, but can't be created + // and destroyed without a subclass. +}; + +} // namespace content + +#endif // CONTENT_TEST_STUB_RENDER_VIEW_HOST_DELEGATE_VIEW_H_
diff --git a/extensions/browser/extension_pref_value_map.cc b/extensions/browser/extension_pref_value_map.cc index 93fe044..4b4ff07 100644 --- a/extensions/browser/extension_pref_value_map.cc +++ b/extensions/browser/extension_pref_value_map.cc
@@ -50,8 +50,9 @@ ExtensionPrefsScope scope, base::Value* value) { PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope); - - if (prefs->SetValue(key, base::WrapUnique(value))) + std::unique_ptr<base::Value> owned_value = base::WrapUnique(value); + if (prefs->SetValue(key, + base::Value::FromUniquePtrValue(std::move(owned_value)))) NotifyPrefValueChanged(key); }
diff --git a/fuchsia/BUILD.gn b/fuchsia/BUILD.gn index 43194bc..f682394 100644 --- a/fuchsia/BUILD.gn +++ b/fuchsia/BUILD.gn
@@ -63,6 +63,7 @@ ] public_deps = [ ":web_fidl", + "//skia/public/interfaces", ] } @@ -385,3 +386,18 @@ ":restaged_packages", ] } + +# Used by the top-level "gn_all" target to discover Fuchsia build targets. +group("gn_all") { + testonly = true + deps = [ + ":service_exe", + ":webrunner_browsertests", + ":webrunner_unittests", + "http:http_service_tests", + "runners:cast_runner", + "runners:cast_runner_browsertests", + "runners:cast_runner_integration_tests", + "runners:web_runner", + ] +}
diff --git a/fuchsia/fidl/cast/cast_channel.fidl b/fuchsia/fidl/cast/cast_channel.fidl index 77a88d0..b73fcbb 100644 --- a/fuchsia/fidl/cast/cast_channel.fidl +++ b/fuchsia/fidl/cast/cast_channel.fidl
@@ -8,10 +8,9 @@ [Discoverable] interface CastChannel { - /// Handles Cast Channel open calls from the webpage. - /// The new Cast Channel's message port is returned asynchronously once - /// opened by the webpage. The port is disconnected when the peer's Cast - /// Channel is closed. - Connect() -> (chromium.web.MessagePort channel); + /// Receives an opened Cast |channel| from the Cast application. + /// The return callback is invoked when the service is ready to accept a new + /// Cast Channel. OnOpened() should not be called again until this happens. + OnOpened(chromium.web.MessagePort channel) -> (); };
diff --git a/fuchsia/runners/BUILD.gn b/fuchsia/runners/BUILD.gn index e04a406c..fe19b7b 100644 --- a/fuchsia/runners/BUILD.gn +++ b/fuchsia/runners/BUILD.gn
@@ -30,18 +30,21 @@ source_set("cast_runner_core") { sources = [ - "cast/bindings/cast_channel.cc", - "cast/bindings/cast_channel.h", + "cast/cast_channel_bindings.cc", + "cast/cast_channel_bindings.h", + "cast/cast_component.cc", + "cast/cast_component.h", "cast/cast_runner.cc", "cast/cast_runner.h", ] data = [ - "cast/bindings/cast_channel.js", + "cast/cast_channel_bindings.js", ] deps = [ "//base", "//fuchsia:mem_buffer_common", "//fuchsia:named_message_port_connector", + "//fuchsia:web_fidl", "//url", ] public_deps = [ @@ -97,24 +100,13 @@ visibility = [ ":*" ] } -test("cast_runner_unittests") { - sources = [ - "cast/cast_runner_unittest.cc", - ] - deps = [ - ":cast_runner_core", - ":cast_runner_test_core", - "//base/test:run_all_unittests", - "//base/test:test_support", - "//fuchsia:test_support", - "//testing/gtest", - ] -} - test("cast_runner_integration_tests") { sources = [ "cast/cast_runner_integration_test.cc", ] + data = [ + "cast/testdata", + ] deps = [ ":cast_runner_core", ":cast_runner_test_core", @@ -132,7 +124,7 @@ test("cast_runner_browsertests") { sources = [ - "cast/bindings/cast_channel_browsertest.cc", + "cast/cast_channel_bindings_browsertest.cc", ] defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] data = [
diff --git a/fuchsia/runners/cast/bindings/cast_channel.cc b/fuchsia/runners/cast/bindings/cast_channel.cc deleted file mode 100644 index 5066bd97..0000000 --- a/fuchsia/runners/cast/bindings/cast_channel.cc +++ /dev/null
@@ -1,117 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "fuchsia/runners/cast/bindings/cast_channel.h" - -#include <lib/fit/function.h> -#include <string> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/fuchsia/fuchsia_logging.h" -#include "base/macros.h" -#include "base/path_service.h" -#include "base/threading/thread_task_runner_handle.h" -#include "fuchsia/common/mem_buffer_util.h" -#include "fuchsia/common/named_message_port_connector.h" - -// Unique identifier of the Cast Channel message port, used by the JavaScript -// API to connect to the port. -const char kMessagePortName[] = "cast.__platform__.channel"; - -CastChannelImpl::CastChannelImpl( - chromium::web::Frame* frame, - webrunner::NamedMessagePortConnector* connector) - : frame_(frame), connector_(connector) { - DCHECK(connector_); - DCHECK(frame_); - - connector->Register( - kMessagePortName, - base::BindRepeating(&CastChannelImpl::OnMasterPortReceived, - base::Unretained(this)), - frame_); - - // Load the cast.__platform__.channel bundle from the package assets, into a - // mem::Buffer. - base::FilePath assets_path; - CHECK(base::PathService::Get(base::DIR_ASSETS, &assets_path)); - fuchsia::mem::Buffer bindings_buf = webrunner::MemBufferFromFile(base::File( - assets_path.AppendASCII("fuchsia/runners/cast/bindings/cast_channel.js"), - base::File::FLAG_OPEN | base::File::FLAG_READ)); - CHECK(bindings_buf.vmo); - - // Inject the cast.__platform__.channel API to all origins. - std::vector<std::string> origins = {"*"}; - - // Configure the bundle to be re-injected every time the |frame_| content is - // loaded. - frame_->ExecuteJavaScript( - std::move(origins), std::move(bindings_buf), - chromium::web::ExecuteMode::ON_PAGE_LOAD, - [](bool success) { CHECK(success) << "Couldn't insert bindings."; }); -} - -CastChannelImpl::~CastChannelImpl() { - connector_->Unregister(frame_, kMessagePortName); -} - -void CastChannelImpl::OnMasterPortError() { - master_port_.Unbind(); -} - -void CastChannelImpl::Connect(ConnectCallback callback) { - // If there is already a bound Cast Channel ready, then return it. - if (pending_channel_) { - callback(std::move(pending_channel_)); - return; - } - - pending_connect_cb_ = std::move(callback); - - if (master_port_) { - master_port_->ReceiveMessage( - fit::bind_member(this, &CastChannelImpl::OnCastChannelMessageReceived)); - } - - // If there is no master port available at this time, then defer invocation of - // |pending_connect_cb_| until the master port has been received. -} - -void CastChannelImpl::OnMasterPortReceived(chromium::web::MessagePortPtr port) { - DCHECK(port); - - master_port_ = std::move(port); - master_port_.set_error_handler([this](zx_status_t status) { - ZX_LOG_IF(WARNING, status != ZX_ERR_PEER_CLOSED, status) - << "Cast Channel master port disconnected."; - OnMasterPortError(); - }); - - if (pending_connect_cb_) { - // Resolve the in-flight Connect call. - Connect(std::move(pending_connect_cb_)); - } -} - -void CastChannelImpl::OnCastChannelMessageReceived( - chromium::web::WebMessage message) { - if (!message.incoming_transfer || - !message.incoming_transfer->is_message_port()) { - LOG(WARNING) << "Received a CastChannel without a message port."; - OnMasterPortError(); - return; - } - - // Fulfill an outstanding Connect() operation, if there is one. - if (pending_connect_cb_) { - pending_connect_cb_(std::move(message.incoming_transfer->message_port())); - pending_connect_cb_ = {}; - return; - } - - pending_channel_ = std::move(message.incoming_transfer->message_port()); -}
diff --git a/fuchsia/runners/cast/bindings/cast_channel.h b/fuchsia/runners/cast/bindings/cast_channel.h deleted file mode 100644 index e8d1601..0000000 --- a/fuchsia/runners/cast/bindings/cast_channel.h +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FUCHSIA_RUNNERS_CAST_BINDINGS_CAST_CHANNEL_H_ -#define FUCHSIA_RUNNERS_CAST_BINDINGS_CAST_CHANNEL_H_ - -#include <string> - -#include "base/callback.h" -#include "base/macros.h" -#include "base/strings/string_piece.h" -#include "fuchsia/common/fuchsia_export.h" -#include "fuchsia/fidl/chromium/cast/cpp/fidl.h" - -namespace webrunner { -class NamedMessagePortConnector; -} - -// Handles the injection of cast.__platform__.channel bindings into pages' -// scripting context, and establishes a bidirectional message pipe over -// which the two communicate. -class FUCHSIA_EXPORT CastChannelImpl : public chromium::cast::CastChannel { - public: - // Attaches CastChannel bindings and port to a |frame|. - // |frame|: The frame to be provided with a CastChannel. - // |connector|: The NamedMessagePortConnector to use for establishing - // transport. - // Both |frame| and |connector| must outlive |this|. - CastChannelImpl(chromium::web::Frame* frame, - webrunner::NamedMessagePortConnector* connector); - ~CastChannelImpl() override; - - // chromium::cast::CastChannel implementation. - void Connect(ConnectCallback callback) override; - - private: - // Receives a port used for receiving new Cast Channel ports. - void OnMasterPortReceived(chromium::web::MessagePortPtr port); - - // Receives a message containing a newly opened Cast Channel from - // |master_port_|. - void OnCastChannelMessageReceived(chromium::web::WebMessage message); - - // Handles error conditions on |master_port_|. - void OnMasterPortError(); - - chromium::web::Frame* const frame_; - webrunner::NamedMessagePortConnector* const connector_; - - // A long-lived port, used to receive new Cast Channel ports when they are - // opened. Should be automatically populated by the - // NamedMessagePortConnector whenever |frame| loads a new page. - chromium::web::MessagePortPtr master_port_; - - fuchsia::mem::Buffer bindings_script_; - ConnectCallback pending_connect_cb_; - - // A Cast Channel received from the webpage, waiting to be handled via - // ListenForChannel(). - fidl::InterfaceHandle<chromium::web::MessagePort> pending_channel_; - - DISALLOW_COPY_AND_ASSIGN(CastChannelImpl); -}; - -#endif // FUCHSIA_RUNNERS_CAST_BINDINGS_CAST_CHANNEL_H_
diff --git a/fuchsia/runners/cast/bindings/cast_channel_browsertest.cc b/fuchsia/runners/cast/bindings/cast_channel_browsertest.cc deleted file mode 100644 index 65779fe0..0000000 --- a/fuchsia/runners/cast/bindings/cast_channel_browsertest.cc +++ /dev/null
@@ -1,218 +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 <lib/fidl/cpp/binding.h> - -#include "base/barrier_closure.h" -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/macros.h" -#include "base/path_service.h" -#include "base/test/test_timeouts.h" -#include "base/threading/thread_restrictions.h" -#include "fuchsia/common/mem_buffer_util.h" -#include "fuchsia/common/named_message_port_connector.h" -#include "fuchsia/common/test/test_common.h" -#include "fuchsia/common/test/webrunner_browser_test.h" -#include "fuchsia/runners/cast/bindings/cast_channel.h" -#include "fuchsia/test/promise.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/url_constants.h" - -// Use a shorter name for NavigationEvent, because it is -// referenced frequently in this file. -using NavigationDetails = chromium::web::NavigationEvent; - -class CastChannelImplTest : public webrunner::WebRunnerBrowserTest, - public chromium::web::NavigationEventObserver { - public: - CastChannelImplTest() : run_timeout_(TestTimeouts::action_timeout()) { - set_test_server_root(base::FilePath("fuchsia/runners/cast/testdata")); - } - - ~CastChannelImplTest() override = default; - - protected: - void SetUpOnMainThread() override { - webrunner::WebRunnerBrowserTest::SetUpOnMainThread(); - base::ScopedAllowBlockingForTesting allow_blocking; - frame_ = WebRunnerBrowserTest::CreateFrame(this); - connector_ = std::make_unique<webrunner::NamedMessagePortConnector>(); - } - - void OnNavigationStateChanged( - chromium::web::NavigationEvent change, - OnNavigationStateChangedCallback callback) override { - connector_->NotifyPageLoad(frame_.get()); - if (navigate_run_loop_) - navigate_run_loop_->Quit(); - callback(); - } - - void CheckLoadUrl(const std::string& url, - chromium::web::NavigationController* controller) { - navigate_run_loop_ = std::make_unique<base::RunLoop>(); - controller->LoadUrl(url, nullptr); - navigate_run_loop_->Run(); - navigate_run_loop_.reset(); - } - - std::unique_ptr<base::RunLoop> navigate_run_loop_; - chromium::web::FramePtr frame_; - std::unique_ptr<webrunner::NamedMessagePortConnector> connector_; - - private: - const base::RunLoop::ScopedRunTimeoutForTest run_timeout_; - - DISALLOW_COPY_AND_ASSIGN(CastChannelImplTest); -}; - -IN_PROC_BROWSER_TEST_F(CastChannelImplTest, CastChannelBuffered) { - base::ScopedAllowBlockingForTesting allow_blocking; - ASSERT_TRUE(embedded_test_server()->Start()); - GURL test_url(embedded_test_server()->GetURL("/cast_channel.html")); - - frame_->SetJavaScriptLogLevel(chromium::web::LogLevel::INFO); - chromium::web::NavigationControllerPtr controller; - frame_->GetNavigationController(controller.NewRequest()); - - testing::InSequence seq; - CastChannelImpl cast_channel_instance(frame_.get(), connector_.get()); - fidl::Binding<chromium::cast::CastChannel> cast_channel_binding( - &cast_channel_instance); - chromium::cast::CastChannelPtr cast_channel = - cast_channel_binding.NewBinding().Bind(); - - // Verify that CastChannelImpl can properly handle message, connect, - // disconnect, and MessagePort disconnection events. - CheckLoadUrl(test_url.spec(), controller.get()); - - chromium::web::MessagePortPtr channel; - - // Expect channel open. - { - base::RunLoop run_loop; - webrunner::Promise<fidl::InterfaceHandle<chromium::web::MessagePort>> - channel_promise(run_loop.QuitClosure()); - cast_channel->Connect( - webrunner::ConvertToFitFunction(channel_promise.GetReceiveCallback())); - run_loop.Run(); - - channel = channel_promise->Bind(); - } - - // Send a message to the channel. - auto expected_list = {"this", "is", "a", "test"}; - for (const std::string& expected : expected_list) { - base::RunLoop run_loop; - webrunner::Promise<chromium::web::WebMessage> message( - run_loop.QuitClosure()); - channel->ReceiveMessage( - webrunner::ConvertToFitFunction(message.GetReceiveCallback())); - run_loop.Run(); - - EXPECT_EQ(webrunner::StringFromMemBufferOrDie(message->data), expected); - } -} - -IN_PROC_BROWSER_TEST_F(CastChannelImplTest, CastChannelReconnect) { - base::ScopedAllowBlockingForTesting allow_blocking; - ASSERT_TRUE(embedded_test_server()->Start()); - GURL test_url(embedded_test_server()->GetURL("/cast_channel_reconnect.html")); - GURL empty_url(embedded_test_server()->GetURL("/defaultresponse")); - - frame_->SetJavaScriptLogLevel(chromium::web::LogLevel::INFO); - chromium::web::NavigationControllerPtr controller; - frame_->GetNavigationController(controller.NewRequest()); - - testing::InSequence seq; - CastChannelImpl cast_channel_instance(frame_.get(), connector_.get()); - fidl::Binding<chromium::cast::CastChannel> cast_channel_binding( - &cast_channel_instance); - chromium::cast::CastChannelPtr cast_channel = - cast_channel_binding.NewBinding().Bind(); - - // Verify that CastChannelImpl can properly handle message, connect, - // disconnect, and MessagePort disconnection events. - // Also verify that the cast channel is used across inter-page navigations. - for (int i = 0; i < 5; ++i) { - CheckLoadUrl(test_url.spec(), controller.get()); - - chromium::web::MessagePortPtr channel; - - // Expect channel open. - { - base::RunLoop run_loop; - webrunner::Promise<fidl::InterfaceHandle<chromium::web::MessagePort>> - channel_promise(run_loop.QuitClosure()); - cast_channel->Connect(webrunner::ConvertToFitFunction( - channel_promise.GetReceiveCallback())); - run_loop.Run(); - - channel = channel_promise->Bind(); - } - - // Expect channel close. - { - base::RunLoop run_loop; - channel.set_error_handler([&run_loop](zx_status_t) { run_loop.Quit(); }); - run_loop.Run(); - } - - // Expect channel re-open. - { - base::RunLoop run_loop; - webrunner::Promise<fidl::InterfaceHandle<chromium::web::MessagePort>> - channel_promise(run_loop.QuitClosure()); - cast_channel->Connect(webrunner::ConvertToFitFunction( - channel_promise.GetReceiveCallback())); - run_loop.Run(); - - channel = channel_promise->Bind(); - } - - // Read "reconnected" from the channel. - { - base::RunLoop run_loop; - webrunner::Promise<chromium::web::WebMessage> message( - run_loop.QuitClosure()); - channel->ReceiveMessage( - webrunner::ConvertToFitFunction(message.GetReceiveCallback())); - run_loop.Run(); - - EXPECT_EQ(webrunner::StringFromMemBufferOrDie(message->data), - "reconnected"); - } - - // Send a message to the channel. - { - chromium::web::WebMessage message; - message.data = webrunner::MemBufferFromString("hello"); - - base::RunLoop run_loop; - webrunner::Promise<bool> post_result(run_loop.QuitClosure()); - channel->PostMessage( - std::move(message), - webrunner::ConvertToFitFunction(post_result.GetReceiveCallback())); - run_loop.Run(); - EXPECT_EQ(true, *post_result); - } - - // Get a message from the channel. - { - base::RunLoop run_loop; - webrunner::Promise<chromium::web::WebMessage> message( - run_loop.QuitClosure()); - channel->ReceiveMessage( - webrunner::ConvertToFitFunction(message.GetReceiveCallback())); - run_loop.Run(); - - EXPECT_EQ(webrunner::StringFromMemBufferOrDie(message->data), - "ack hello"); - } - - // Navigate away. - CheckLoadUrl(empty_url.spec(), controller.get()); - } -}
diff --git a/fuchsia/runners/cast/cast_channel_bindings.cc b/fuchsia/runners/cast/cast_channel_bindings.cc new file mode 100644 index 0000000..7e78b58 --- /dev/null +++ b/fuchsia/runners/cast/cast_channel_bindings.cc
@@ -0,0 +1,128 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "fuchsia/runners/cast/cast_channel_bindings.h" + +#include <lib/fit/function.h> +#include <string> +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/fuchsia/fuchsia_logging.h" +#include "base/macros.h" +#include "base/path_service.h" +#include "base/threading/thread_task_runner_handle.h" +#include "fuchsia/common/mem_buffer_util.h" +#include "fuchsia/common/named_message_port_connector.h" + +// Unique identifier of the Cast Channel message port, used by the JavaScript +// API to connect to the port. +const char kMessagePortName[] = "cast.__platform__.channel"; + +CastChannelBindings::CastChannelBindings( + chromium::web::Frame* frame, + webrunner::NamedMessagePortConnector* connector, + chromium::cast::CastChannelPtr channel_consumer, + base::OnceClosure on_error_closure) + : frame_(frame), + connector_(connector), + on_error_closure_(std::move(on_error_closure)), + channel_consumer_(std::move(channel_consumer)) { + DCHECK(connector_); + DCHECK(frame_); + + channel_consumer_.set_error_handler([this](zx_status_t status) mutable { + ZX_LOG(ERROR, status) << "CastChannel error:"; + std::move(on_error_closure_).Run(); + }); + + connector->Register( + kMessagePortName, + base::BindRepeating(&CastChannelBindings::OnMasterPortReceived, + base::Unretained(this)), + frame_); + + // Load the cast.__platform__.channel bundle from the package assets, into a + // mem::Buffer. + base::FilePath assets_path; + CHECK(base::PathService::Get(base::DIR_ASSETS, &assets_path)); + fuchsia::mem::Buffer bindings_buf = webrunner::MemBufferFromFile(base::File( + assets_path.AppendASCII("fuchsia/runners/cast/cast_channel_bindings.js"), + base::File::FLAG_OPEN | base::File::FLAG_READ)); + CHECK(bindings_buf.vmo); + + // Inject the cast.__platform__.channel API to all origins. + std::vector<std::string> origins = {"*"}; + + // Configure the bundle to be re-injected every time the |frame_| content is + // loaded. + frame_->ExecuteJavaScript( + std::move(origins), std::move(bindings_buf), + chromium::web::ExecuteMode::ON_PAGE_LOAD, + [](bool success) { CHECK(success) << "Couldn't insert bindings."; }); +} + +CastChannelBindings::~CastChannelBindings() { + connector_->Unregister(frame_, kMessagePortName); +} + +void CastChannelBindings::OnMasterPortError() { + master_port_.Unbind(); +} + +void CastChannelBindings::OnMasterPortReceived( + chromium::web::MessagePortPtr port) { + DCHECK(port); + + master_port_ = std::move(port); + master_port_.set_error_handler([this](zx_status_t status) { + ZX_LOG_IF(WARNING, status != ZX_ERR_PEER_CLOSED, status) + << "Cast Channel master port disconnected."; + OnMasterPortError(); + }); + master_port_->ReceiveMessage(fit::bind_member( + this, &CastChannelBindings::OnCastChannelMessageReceived)); +} + +void CastChannelBindings::OnCastChannelMessageReceived( + chromium::web::WebMessage message) { + if (!message.incoming_transfer || + !message.incoming_transfer->is_message_port()) { + LOG(WARNING) << "Received a CastChannel without a message port."; + OnMasterPortError(); + return; + } + + SendChannelToConsumer(message.incoming_transfer->message_port().Bind()); + + master_port_->ReceiveMessage(fit::bind_member( + this, &CastChannelBindings::OnCastChannelMessageReceived)); +} + +void CastChannelBindings::SendChannelToConsumer( + chromium::web::MessagePortPtr channel) { + if (consumer_ready_for_port_) { + consumer_ready_for_port_ = false; + channel_consumer_->OnOpened( + std::move(channel), + fit::bind_member(this, &CastChannelBindings::OnConsumerReadyForPort)); + } else { + connected_channel_queue_.push_front(std::move(channel)); + } +} + +void CastChannelBindings::OnConsumerReadyForPort() { + DCHECK(!consumer_ready_for_port_); + + consumer_ready_for_port_ = true; + if (!connected_channel_queue_.empty()) { + // Deliver the next enqueued channel. + chromium::web::MessagePortPtr next_port = + std::move(connected_channel_queue_.back()); + SendChannelToConsumer(std::move(next_port)); + connected_channel_queue_.pop_back(); + } +}
diff --git a/fuchsia/runners/cast/cast_channel_bindings.h b/fuchsia/runners/cast/cast_channel_bindings.h new file mode 100644 index 0000000..01146e6 --- /dev/null +++ b/fuchsia/runners/cast/cast_channel_bindings.h
@@ -0,0 +1,83 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FUCHSIA_RUNNERS_CAST_CAST_CHANNEL_BINDINGS_H_ +#define FUCHSIA_RUNNERS_CAST_CAST_CHANNEL_BINDINGS_H_ + +#include <deque> +#include <string> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/strings/string_piece.h" +#include "fuchsia/common/fuchsia_export.h" +#include "fuchsia/fidl/chromium/cast/cpp/fidl.h" + +namespace webrunner { +class NamedMessagePortConnector; +} + +// Handles the injection of cast.__platform__.channel bindings into pages' +// scripting context, and establishes a bidirectional message pipe over +// which the two communicate. +class FUCHSIA_EXPORT CastChannelBindings { + public: + // Attaches CastChannel bindings and port to a |frame|. + // |frame|: The frame to be provided with a CastChannel. + // |connector|: The NamedMessagePortConnector to use for establishing + // transport. + // |on_error_closure|: Invoked in the event of an unrecoverable error (e.g. + // lost connection to the Agent). The callback must + // remain valid for the entire lifetime of |this|. + // |channel_consumer|: A FIDL service which receives opened Cast Channels. + // Both |frame| and |connector| must outlive |this|. + CastChannelBindings(chromium::web::Frame* frame, + webrunner::NamedMessagePortConnector* connector, + chromium::cast::CastChannelPtr channel_consumer, + base::OnceClosure on_error_closure); + ~CastChannelBindings(); + + private: + // Receives a port used for receiving new Cast Channel ports. + void OnMasterPortReceived(chromium::web::MessagePortPtr port); + + // Receives a message containing a newly opened Cast Channel from + // |master_port_|. + void OnCastChannelMessageReceived(chromium::web::WebMessage message); + + // Indicates that |channel_consumer_| is ready to take another port. + void OnConsumerReadyForPort(); + + // Sends or enqueues a Cast Channel for sending to |channel_consumer_|. + void SendChannelToConsumer(chromium::web::MessagePortPtr channel); + + // Handles error conditions on |master_port_|. + void OnMasterPortError(); + + chromium::web::Frame* const frame_; + webrunner::NamedMessagePortConnector* const connector_; + + // A queue of channels waiting to be sent the Cast Channel FIDL service. + std::deque<chromium::web::MessagePortPtr> connected_channel_queue_; + + // A long-lived port, used to receive new Cast Channel ports when they are + // opened. Should be automatically populated by the + // NamedMessagePortConnector whenever |frame| loads a new page. + chromium::web::MessagePortPtr master_port_; + + fuchsia::mem::Buffer bindings_script_; + + base::OnceClosure on_error_closure_; + + // The service which will receive connected Cast Channels. + chromium::cast::CastChannelPtr channel_consumer_; + + // If set, indicates that |channel_consumer_| is ready to accept another Cast + // Channel. + bool consumer_ready_for_port_ = true; + + DISALLOW_COPY_AND_ASSIGN(CastChannelBindings); +}; + +#endif // FUCHSIA_RUNNERS_CAST_CAST_CHANNEL_BINDINGS_H_
diff --git a/fuchsia/runners/cast/bindings/cast_channel.js b/fuchsia/runners/cast/cast_channel_bindings.js similarity index 100% rename from fuchsia/runners/cast/bindings/cast_channel.js rename to fuchsia/runners/cast/cast_channel_bindings.js
diff --git a/fuchsia/runners/cast/cast_channel_bindings_browsertest.cc b/fuchsia/runners/cast/cast_channel_bindings_browsertest.cc new file mode 100644 index 0000000..fb00446c --- /dev/null +++ b/fuchsia/runners/cast/cast_channel_bindings_browsertest.cc
@@ -0,0 +1,211 @@ +// 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 <lib/fidl/cpp/binding.h> + +#include "base/barrier_closure.h" +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/macros.h" +#include "base/path_service.h" +#include "base/test/bind_test_util.h" +#include "base/test/test_timeouts.h" +#include "base/threading/thread_restrictions.h" +#include "fuchsia/common/mem_buffer_util.h" +#include "fuchsia/common/named_message_port_connector.h" +#include "fuchsia/common/test/test_common.h" +#include "fuchsia/common/test/webrunner_browser_test.h" +#include "fuchsia/runners/cast/cast_channel_bindings.h" +#include "fuchsia/test/promise.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/url_constants.h" + +namespace { + +// Use a shorter name for NavigationEvent, because it is +// referenced frequently in this file. +using NavigationDetails = chromium::web::NavigationEvent; + +void OnError() { + ADD_FAILURE(); +} + +class CastChannelBindingsTest : public webrunner::WebRunnerBrowserTest, + public chromium::web::NavigationEventObserver, + public chromium::cast::CastChannel { + public: + CastChannelBindingsTest() + : receiver_binding_(this), run_timeout_(TestTimeouts::action_timeout()) { + set_test_server_root(base::FilePath("fuchsia/runners/cast/testdata")); + } + + ~CastChannelBindingsTest() override = default; + + protected: + void SetUpOnMainThread() override { + webrunner::WebRunnerBrowserTest::SetUpOnMainThread(); + base::ScopedAllowBlockingForTesting allow_blocking; + frame_ = WebRunnerBrowserTest::CreateFrame(this); + connector_ = std::make_unique<webrunner::NamedMessagePortConnector>(); + } + + void OnNavigationStateChanged( + chromium::web::NavigationEvent change, + OnNavigationStateChangedCallback callback) override { + connector_->NotifyPageLoad(frame_.get()); + if (navigate_run_loop_) + navigate_run_loop_->Quit(); + callback(); + } + + void OnOpened(fidl::InterfaceHandle<chromium::web::MessagePort> channel, + OnOpenedCallback receive_next_channel_cb) override { + connected_channel_ = channel.Bind(); + receive_next_channel_cb_ = std::move(receive_next_channel_cb); + + if (on_channel_connected_cb_) + std::move(on_channel_connected_cb_).Run(); + } + + void SignalReadyForNewChannel() { receive_next_channel_cb_(); } + + void WaitUntilCastChannelOpened() { + if (connected_channel_) + return; + + base::RunLoop run_loop; + on_channel_connected_cb_ = run_loop.QuitClosure(); + run_loop.Run(); + } + + void WaitUntilCastChannelClosed() { + if (!connected_channel_) + return; + + base::RunLoop run_loop; + connected_channel_.set_error_handler( + [quit_closure = run_loop.QuitClosure()](zx_status_t) { + quit_closure.Run(); + }); + run_loop.Run(); + } + + std::string ReadStringFromChannel() { + base::RunLoop run_loop; + webrunner::Promise<chromium::web::WebMessage> message( + run_loop.QuitClosure()); + connected_channel_->ReceiveMessage( + webrunner::ConvertToFitFunction(message.GetReceiveCallback())); + run_loop.Run(); + return webrunner::StringFromMemBufferOrDie(message->data); + } + + void CheckLoadUrl(const std::string& url, + chromium::web::NavigationController* controller) { + navigate_run_loop_ = std::make_unique<base::RunLoop>(); + controller->LoadUrl(url, nullptr); + navigate_run_loop_->Run(); + navigate_run_loop_.reset(); + } + + std::unique_ptr<base::RunLoop> navigate_run_loop_; + chromium::web::FramePtr frame_; + std::unique_ptr<webrunner::NamedMessagePortConnector> connector_; + fidl::Binding<chromium::cast::CastChannel> receiver_binding_; + + // The connected Cast Channel. + chromium::web::MessagePortPtr connected_channel_; + + // A pending on-connect callback, to be invoked once a Cast Channel is + // received. + base::OnceClosure on_channel_connected_cb_; + + private: + const base::RunLoop::ScopedRunTimeoutForTest run_timeout_; + OnOpenedCallback receive_next_channel_cb_; + + DISALLOW_COPY_AND_ASSIGN(CastChannelBindingsTest); +}; + +IN_PROC_BROWSER_TEST_F(CastChannelBindingsTest, CastChannelBufferedInput) { + base::ScopedAllowBlockingForTesting allow_blocking; + ASSERT_TRUE(embedded_test_server()->Start()); + GURL test_url(embedded_test_server()->GetURL("/cast_channel.html")); + + frame_->SetJavaScriptLogLevel(chromium::web::LogLevel::INFO); + chromium::web::NavigationControllerPtr controller; + frame_->GetNavigationController(controller.NewRequest()); + + testing::InSequence seq; + CastChannelBindings cast_channel_instance( + frame_.get(), connector_.get(), receiver_binding_.NewBinding().Bind(), + base::MakeExpectedNotRunClosure(FROM_HERE)); + + // Verify that CastChannelBindings can properly handle message, connect, + // disconnect, and MessagePort disconnection events. + CheckLoadUrl(test_url.spec(), controller.get()); + + WaitUntilCastChannelOpened(); + + auto expected_list = {"this", "is", "a", "test"}; + for (const std::string& expected : expected_list) { + EXPECT_EQ(ReadStringFromChannel(), expected); + } +} + +IN_PROC_BROWSER_TEST_F(CastChannelBindingsTest, CastChannelReconnect) { + base::ScopedAllowBlockingForTesting allow_blocking; + ASSERT_TRUE(embedded_test_server()->Start()); + GURL test_url(embedded_test_server()->GetURL("/cast_channel_reconnect.html")); + GURL empty_url(embedded_test_server()->GetURL("/defaultresponse")); + + frame_->SetJavaScriptLogLevel(chromium::web::LogLevel::INFO); + chromium::web::NavigationControllerPtr controller; + frame_->GetNavigationController(controller.NewRequest()); + + testing::InSequence seq; + CastChannelBindings cast_channel_instance( + frame_.get(), connector_.get(), receiver_binding_.NewBinding().Bind(), + base::BindOnce(&OnError)); + + // Verify that CastChannelBindings can properly handle message, connect, + // disconnect, and MessagePort disconnection events. + // Also verify that the cast channel is used across inter-page navigations. + for (int i = 0; i < 5; ++i) { + CheckLoadUrl(test_url.spec(), controller.get()); + + WaitUntilCastChannelOpened(); + + WaitUntilCastChannelClosed(); + + SignalReadyForNewChannel(); + + WaitUntilCastChannelOpened(); + + EXPECT_EQ("reconnected", ReadStringFromChannel()); + + // Send a message to the channel. + { + chromium::web::WebMessage message; + message.data = webrunner::MemBufferFromString("hello"); + + base::RunLoop run_loop; + webrunner::Promise<bool> post_result(run_loop.QuitClosure()); + connected_channel_->PostMessage( + std::move(message), + webrunner::ConvertToFitFunction(post_result.GetReceiveCallback())); + run_loop.Run(); + EXPECT_EQ(true, *post_result); + } + + EXPECT_EQ("ack hello", ReadStringFromChannel()); + + // Navigate away. + CheckLoadUrl(empty_url.spec(), controller.get()); + + SignalReadyForNewChannel(); + } +} + +} // namespace
diff --git a/fuchsia/runners/cast/cast_component.cc b/fuchsia/runners/cast/cast_component.cc new file mode 100644 index 0000000..03216c0 --- /dev/null +++ b/fuchsia/runners/cast/cast_component.cc
@@ -0,0 +1,67 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "fuchsia/runners/cast/cast_component.h" + +#include <lib/fidl/cpp/binding.h> +#include <algorithm> +#include <utility> + +#include "base/auto_reset.h" +#include "base/fuchsia/fuchsia_logging.h" +#include "fuchsia/fidl/chromium/cast/cpp/fidl.h" +#include "fuchsia/runners/cast/cast_runner.h" +#include "fuchsia/runners/common/web_component.h" + +namespace { +constexpr int kBindingsFailureExitCode = 129; +} // namespace + +CastComponent::CastComponent( + CastRunner* runner, + fuchsia::sys::StartupInfo startup_info, + fidl::InterfaceRequest<fuchsia::sys::ComponentController> + controller_request) + : WebComponent(runner, + std::move(startup_info), + std::move(controller_request)), + navigation_observer_binding_(this) { + base::AutoReset<bool> constructor_active_reset(&constructor_active_, true); + + if (!additional_services() || std::find(additional_service_names().begin(), + additional_service_names().end(), + chromium::cast::CastChannel::Name_) == + additional_service_names().end()) { + LOG(ERROR) << "Component instantiated without required service: " + << chromium::cast::CastChannel::Name_; + DestroyComponent(1, fuchsia::sys::TerminationReason::UNSUPPORTED); + return; + } + + cast_channel_ = std::make_unique<CastChannelBindings>( + frame(), &connector_, + additional_services()->ConnectToService<chromium::cast::CastChannel>(), + base::BindOnce(&CastComponent::DestroyComponent, base::Unretained(this), + kBindingsFailureExitCode, + fuchsia::sys::TerminationReason::INTERNAL_ERROR)); + frame()->SetNavigationEventObserver( + navigation_observer_binding_.NewBinding()); +} + +CastComponent::~CastComponent() = default; + +void CastComponent::DestroyComponent(int termination_exit_code, + fuchsia::sys::TerminationReason reason) { + DCHECK(!constructor_active_); + + WebComponent::DestroyComponent(termination_exit_code, reason); +} + +void CastComponent::OnNavigationStateChanged( + chromium::web::NavigationEvent change, + OnNavigationStateChangedCallback callback) { + if (change.url) + connector_.NotifyPageLoad(frame()); + callback(); +}
diff --git a/fuchsia/runners/cast/cast_component.h b/fuchsia/runners/cast/cast_component.h new file mode 100644 index 0000000..7bb33b8 --- /dev/null +++ b/fuchsia/runners/cast/cast_component.h
@@ -0,0 +1,50 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FUCHSIA_RUNNERS_CAST_CAST_COMPONENT_H_ +#define FUCHSIA_RUNNERS_CAST_CAST_COMPONENT_H_ + +#include <lib/fidl/cpp/binding.h> +#include <memory> + +#include "base/fuchsia/service_directory.h" +#include "fuchsia/common/named_message_port_connector.h" +#include "fuchsia/fidl/chromium/web/cpp/fidl.h" +#include "fuchsia/runners/cast/cast_channel_bindings.h" +#include "fuchsia/runners/common/web_component.h" + +class CastRunner; + +// A specialization of WebComponent which adds Cast-specific services. +class CastComponent : public WebComponent, + public chromium::web::NavigationEventObserver { + public: + CastComponent(CastRunner* runner, + fuchsia::sys::StartupInfo startup_info, + fidl::InterfaceRequest<fuchsia::sys::ComponentController> + controller_request); + ~CastComponent() override; + + private: + // WebComponent overrides. + void DestroyComponent(int termination_exit_code, + fuchsia::sys::TerminationReason reason) override; + + // chromium::web::NavigationEventObserver implementation. + // Triggers the injection of API channels into the page content. + void OnNavigationStateChanged( + chromium::web::NavigationEvent change, + OnNavigationStateChangedCallback callback) override; + + bool constructor_active_ = false; + webrunner::NamedMessagePortConnector connector_; + std::unique_ptr<CastChannelBindings> cast_channel_; + + fidl::Binding<chromium::web::NavigationEventObserver> + navigation_observer_binding_; + + DISALLOW_COPY_AND_ASSIGN(CastComponent); +}; + +#endif // FUCHSIA_RUNNERS_CAST_CAST_COMPONENT_H_
diff --git a/fuchsia/runners/cast/cast_runner.cc b/fuchsia/runners/cast/cast_runner.cc index 10e4b80..caeb1aa 100644 --- a/fuchsia/runners/cast/cast_runner.cc +++ b/fuchsia/runners/cast/cast_runner.cc
@@ -5,10 +5,13 @@ #include "fuchsia/runners/cast/cast_runner.h" #include <fuchsia/sys/cpp/fidl.h> +#include <memory> +#include <string> #include <utility> #include "base/logging.h" -#include "fuchsia/runners/common/web_component.h" +#include "base/memory/ptr_util.h" +#include "fuchsia/runners/cast/cast_component.h" #include "url/gurl.h" CastRunner::CastRunner( @@ -69,7 +72,8 @@ // If a config was returned then use it to launch a component. GURL cast_app_url(app_config->web_url); - RegisterComponent(WebComponent::ForUrlRequest(this, std::move(cast_app_url), - std::move(startup_info), - std::move(controller_request))); + auto component = std::make_unique<CastComponent>( + this, std::move(startup_info), std::move(controller_request)); + component->LoadUrl(std::move(cast_app_url)); + RegisterComponent(std::move(component)); }
diff --git a/fuchsia/runners/cast/cast_runner.h b/fuchsia/runners/cast/cast_runner.h index da1b86a..b77eccf 100644 --- a/fuchsia/runners/cast/cast_runner.h +++ b/fuchsia/runners/cast/cast_runner.h
@@ -28,14 +28,14 @@ controller_request) override; private: - chromium::cast::ApplicationConfigManagerPtr app_config_manager_; - void GetConfigCallback( fuchsia::sys::StartupInfo startup_info, fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller_request, chromium::cast::ApplicationConfigPtr app_config); + const chromium::cast::ApplicationConfigManagerPtr app_config_manager_; + DISALLOW_COPY_AND_ASSIGN(CastRunner); };
diff --git a/fuchsia/runners/cast/cast_runner_integration_test.cc b/fuchsia/runners/cast/cast_runner_integration_test.cc index 3f8b577..bf57eb58 100644 --- a/fuchsia/runners/cast/cast_runner_integration_test.cc +++ b/fuchsia/runners/cast/cast_runner_integration_test.cc
@@ -11,16 +11,24 @@ #include "base/message_loop/message_loop.h" #include "base/strings/stringprintf.h" #include "base/test/test_timeouts.h" +#include "fuchsia/common/test/test_common.h" +#include "fuchsia/fidl/chromium/web/cpp/fidl.h" #include "fuchsia/runners/cast/cast_runner.h" #include "fuchsia/runners/cast/fake_application_config_manager.h" #include "fuchsia/runners/cast/test_common.h" #include "fuchsia/runners/common/web_component.h" #include "fuchsia/runners/common/web_content_runner.h" #include "fuchsia/test/promise.h" +#include "net/test/embedded_test_server/default_handlers.h" #include "testing/gtest/include/gtest/gtest.h" +namespace castrunner { + namespace { +const char kTestServerRoot[] = + FILE_PATH_LITERAL("fuchsia/runners/cast/testdata"); + void ComponentErrorHandler(zx_status_t status) { ZX_LOG(ERROR, status) << "Component launch failed."; ADD_FAILURE(); @@ -28,9 +36,12 @@ } // namespace -class CastRunnerIntegrationTest : public testing::Test { +class CastRunnerIntegrationTest : public testing::Test, + public chromium::cast::CastChannel { public: - CastRunnerIntegrationTest() : run_timeout_(TestTimeouts::action_timeout()) { + CastRunnerIntegrationTest() + : run_timeout_(TestTimeouts::action_timeout()), + cast_channel_binding_(this) { // Create a new test ServiceDirectory, and a test ComponentContext // connected to it, for the test to use to drive the CastRunner. zx::channel service_directory_request, service_directory_client; @@ -44,11 +55,9 @@ std::move(service_directory_client)); // Create the AppConfigManager. - app_config_manager_ = - std::make_unique<FakeApplicationConfigManager>(&test_server_); app_config_binding_ = std::make_unique< fidl::Binding<chromium::cast::ApplicationConfigManager>>( - app_config_manager_.get()); + &app_config_manager_); chromium::cast::ApplicationConfigManagerPtr app_config_manager_interface; app_config_binding_->Bind(app_config_manager_interface.NewRequest()); @@ -69,7 +78,11 @@ }); } - void SetUp() override { ASSERT_TRUE(test_server_.Start()); } + void SetUp() override { + test_server_.ServeFilesFromSourceDirectory(kTestServerRoot); + net::test_server::RegisterDefaultHandlers(&test_server_); + ASSERT_TRUE(test_server_.Start()); + } void TearDown() override { // Disconnect the CastRunner. @@ -77,17 +90,46 @@ cast_runner_run_loop_.Run(); } + void WaitUntilCastChannelOpened() { + if (connected_channel_) + return; + + base::RunLoop run_loop; + on_channel_connected_cb_ = run_loop.QuitClosure(); + run_loop.Run(); + } + + // chromium::web::CastChannel implementation. + void OnOpened(fidl::InterfaceHandle<chromium::web::MessagePort> channel, + OnOpenedCallback callback_ignored) override { + // |callback_ignored| is dropped because these tests don't exercise multiple + // channel lifetimes. + connected_channel_ = channel.Bind(); + + if (on_channel_connected_cb_) + std::move(on_channel_connected_cb_).Run(); + } + protected: const base::RunLoop::ScopedRunTimeoutForTest run_timeout_; - base::MessageLoopForIO message_loop_; - net::EmbeddedTestServer test_server_; - std::unique_ptr<FakeApplicationConfigManager> app_config_manager_; + // Returns fake Cast application information to the CastRunner. + FakeApplicationConfigManager app_config_manager_; std::unique_ptr<fidl::Binding<chromium::cast::ApplicationConfigManager>> app_config_binding_; + // The connected Cast Channel. + chromium::web::MessagePortPtr connected_channel_; + + // A pending on-connect callback, to be invoked once a Cast Channel is + // received. + base::OnceClosure on_channel_connected_cb_; + + // Receives connected channels from the CastRunner. + fidl::Binding<chromium::cast::CastChannel> cast_channel_binding_; + // ServiceDirectory into which the CastRunner will publish itself. std::unique_ptr<base::fuchsia::ServiceDirectory> test_service_directory_; std::unique_ptr<base::fuchsia::ComponentContext> test_component_context_; @@ -102,12 +144,16 @@ // A basic integration test ensuring a basic cast request launches the right // URL in the Chromium service. TEST_F(CastRunnerIntegrationTest, BasicRequest) { + const char kBlankAppId[] = "00000000"; + const char kBlankAppPath[] = "/defaultresponse"; + app_config_manager_.AddAppMapping(kBlankAppId, + test_server_.GetURL(kBlankAppPath)); + // Launch the test-app component. fuchsia::sys::ComponentControllerPtr component_controller_ptr; base::fuchsia::ComponentContext component_services(StartCastComponent( - base::StringPrintf("cast:%s", - FakeApplicationConfigManager::kTestCastAppId), - &cast_runner_ptr_, component_controller_ptr.NewRequest())); + base::StringPrintf("cast:%s", kBlankAppId), &cast_runner_ptr_, + component_controller_ptr.NewRequest(), &cast_channel_binding_)); component_controller_ptr.set_error_handler(&ComponentErrorHandler); // Access the NavigationController from the WebComponent. The test will hang @@ -132,16 +178,24 @@ nav_controller->GetVisibleEntry( webrunner::ConvertToFitFunction(nav_entry.GetReceiveCallback())); run_loop.Run(); - EXPECT_EQ(nav_entry->get()->url, test_server_.base_url().spec()); + EXPECT_EQ(nav_entry->get()->url, test_server_.GetURL(kBlankAppPath).spec()); } + + // Verify that the component is torn down when |component_controller_ptr| is + // unbound, by observing the destruction of its child Interfaces. + base::RunLoop destruction_run_loop; + nav_controller.set_error_handler( + [&destruction_run_loop](zx_status_t) { destruction_run_loop.Quit(); }); + component_controller_ptr.Unbind(); + destruction_run_loop.Run(); } TEST_F(CastRunnerIntegrationTest, IncorrectCastAppId) { // Launch the test-app component. fuchsia::sys::ComponentControllerPtr component_controller_ptr; - base::fuchsia::ComponentContext component_services( - StartCastComponent("cast:99999999", &cast_runner_ptr_, - component_controller_ptr.NewRequest())); + base::fuchsia::ComponentContext component_services(StartCastComponent( + "cast:99999999", &cast_runner_ptr_, component_controller_ptr.NewRequest(), + &cast_channel_binding_)); component_controller_ptr.set_error_handler(&ComponentErrorHandler); // Ensure no WebComponent was created. @@ -151,3 +205,110 @@ run_loop.Run(); EXPECT_EQ(*web_component, nullptr); } + +TEST_F(CastRunnerIntegrationTest, CastChannel) { + const char kCastChannelAppId[] = "00000001"; + const char kCastChannelAppPath[] = "/cast_channel.html"; + app_config_manager_.AddAppMapping(kCastChannelAppId, + test_server_.GetURL(kCastChannelAppPath)); + + // Launch the test-app component. + fuchsia::sys::ComponentControllerPtr component_controller_ptr; + base::fuchsia::ComponentContext component_services(StartCastComponent( + base::StringPrintf("cast:%s", kCastChannelAppId), &cast_runner_ptr_, + component_controller_ptr.NewRequest(), &cast_channel_binding_)); + component_controller_ptr.set_error_handler(&ComponentErrorHandler); + + // Access the NavigationController from the WebComponent. The test will hang + // here if no WebComponent was created. + chromium::web::NavigationControllerPtr nav_controller; + { + base::RunLoop run_loop; + webrunner::Promise<WebComponent*> web_component(run_loop.QuitClosure()); + cast_runner_->GetWebComponentForTest(web_component.GetReceiveCallback()); + run_loop.Run(); + ASSERT_NE(*web_component, nullptr); + (*web_component) + ->frame() + ->GetNavigationController(nav_controller.NewRequest()); + } + + // Ensure the NavigationEntry has the expected URL. + { + base::RunLoop run_loop; + webrunner::Promise<std::unique_ptr<chromium::web::NavigationEntry>> + nav_entry(run_loop.QuitClosure()); + nav_controller->GetVisibleEntry( + webrunner::ConvertToFitFunction(nav_entry.GetReceiveCallback())); + run_loop.Run(); + EXPECT_EQ(nav_entry->get()->url, + test_server_.GetURL(kCastChannelAppPath).spec()); + } + + WaitUntilCastChannelOpened(); + + auto expected_list = {"this", "is", "a", "test"}; + for (const std::string& expected : expected_list) { + base::RunLoop run_loop; + webrunner::Promise<chromium::web::WebMessage> message( + run_loop.QuitClosure()); + connected_channel_->ReceiveMessage( + webrunner::ConvertToFitFunction(message.GetReceiveCallback())); + run_loop.Run(); + + EXPECT_EQ(webrunner::StringFromMemBufferOrDie(message->data), expected); + } + + component_controller_ptr.Unbind(); + base::RunLoop run_loop; + cast_channel_binding_.set_error_handler( + [&run_loop](zx_status_t) { run_loop.Quit(); }); + run_loop.Run(); +} + +TEST_F(CastRunnerIntegrationTest, CastChannelConsumerDropped) { + const char kCastChannelAppId[] = "00000001"; + const char kCastChannelAppPath[] = "/cast_channel.html"; + app_config_manager_.AddAppMapping(kCastChannelAppId, + test_server_.GetURL(kCastChannelAppPath)); + + // Launch the test-app component. + fuchsia::sys::ComponentControllerPtr component_controller_ptr; + base::fuchsia::ComponentContext component_services(StartCastComponent( + base::StringPrintf("cast:%s", kCastChannelAppId), &cast_runner_ptr_, + component_controller_ptr.NewRequest(), &cast_channel_binding_)); + + // Expect that disconnecting the Cast Channel consumer service will trigger + // the destruction of the Cast Component. + cast_channel_binding_.Unbind(); + base::RunLoop run_loop; + component_controller_ptr.set_error_handler( + [&run_loop](zx_status_t) { run_loop.Quit(); }); + run_loop.Run(); + + EXPECT_FALSE(component_controller_ptr.is_bound()); +} + +TEST_F(CastRunnerIntegrationTest, CastChannelComponentControllerDropped) { + const char kCastChannelAppId[] = "00000001"; + const char kCastChannelAppPath[] = "/cast_channel.html"; + app_config_manager_.AddAppMapping(kCastChannelAppId, + test_server_.GetURL(kCastChannelAppPath)); + + // Launch the test-app component. + fuchsia::sys::ComponentControllerPtr component_controller_ptr; + base::fuchsia::ComponentContext component_services(StartCastComponent( + base::StringPrintf("cast:%s", kCastChannelAppId), &cast_runner_ptr_, + component_controller_ptr.NewRequest(), &cast_channel_binding_)); + + // Expect that disconnecting the ComponentController will kill the Cast + // Component, which we verify indirectly by listening for the disconnection + // of one of its CastChannel FIDL client. + component_controller_ptr.Unbind(); + base::RunLoop run_loop; + cast_channel_binding_.set_error_handler( + [&run_loop](zx_status_t) { run_loop.Quit(); }); + run_loop.Run(); +} + +} // namespace castrunner
diff --git a/fuchsia/runners/cast/cast_runner_unittest.cc b/fuchsia/runners/cast/cast_runner_unittest.cc deleted file mode 100644 index 0c6b4fa..0000000 --- a/fuchsia/runners/cast/cast_runner_unittest.cc +++ /dev/null
@@ -1,125 +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 "fuchsia/runners/cast/cast_runner.h" - -#include <lib/fidl/cpp/binding.h> -#include <lib/zx/channel.h> -#include <zircon/status.h> - -#include "base/fuchsia/component_context.h" -#include "base/fuchsia/fuchsia_logging.h" -#include "base/fuchsia/service_directory.h" -#include "base/message_loop/message_loop.h" -#include "base/strings/stringprintf.h" -#include "fuchsia/runners/cast/fake_application_config_manager.h" -#include "fuchsia/runners/cast/test_common.h" -#include "fuchsia/test/fake_context.h" -#include "testing/gtest/include/gtest/gtest.h" - -class CastRunnerUnitTest : public testing::Test { - public: - CastRunnerUnitTest() - : fake_context_binding_(&fake_context_, fake_context_ptr_.NewRequest()) { - // Create a new ServiceDirectory, and a scoped default ComponentContext - // connected to it, for the test to use to drive the CastRunner. - zx::channel service_directory_request, service_directory_client; - zx_status_t status = zx::channel::create(0, &service_directory_client, - &service_directory_request); - ZX_CHECK(status == ZX_OK, status) << "zx_channel_create"; - - service_directory_ = std::make_unique<base::fuchsia::ServiceDirectory>( - std::move(service_directory_request)); - scoped_default_component_context_ = - std::make_unique<base::fuchsia::ScopedDefaultComponentContext>( - std::move(service_directory_client)); - - // Create the AppConfigManager. - app_config_manager_ = - std::make_unique<FakeApplicationConfigManager>(&test_server_); - app_config_binding_ = std::make_unique< - fidl::Binding<chromium::cast::ApplicationConfigManager>>( - app_config_manager_.get()); - chromium::cast::ApplicationConfigManagerPtr app_config_manager_interface; - app_config_binding_->Bind(app_config_manager_interface.NewRequest()); - - // Create the CastRunner, published into |service_directory_|. - cast_runner_ = std::make_unique<CastRunner>( - service_directory_.get(), std::move(fake_context_ptr_), - std::move(app_config_manager_interface), - until_runner_idle_loop_.QuitClosure()); - - // Connect to the CastRunner's fuchsia.sys.Runner interface. - cast_runner_ptr_ = base::fuchsia::ComponentContext::GetDefault() - ->ConnectToService<fuchsia::sys::Runner>(); - cast_runner_ptr_.set_error_handler([this](zx_status_t status) { - ADD_FAILURE() << "CastRunner closed channel."; - until_runner_idle_loop_.Quit(); - }); - } - - void SetUp() override { ASSERT_TRUE(test_server_.Start()); } - - void RunUntilCastRunnerIsIdle() { until_runner_idle_loop_.Run(); } - - protected: - base::MessageLoopForIO message_loop_; - base::RunLoop until_runner_idle_loop_; - - // Test server. - net::EmbeddedTestServer test_server_; - - // Test AppConfigManager and its binding. - std::unique_ptr<FakeApplicationConfigManager> app_config_manager_; - std::unique_ptr<fidl::Binding<chromium::cast::ApplicationConfigManager>> - app_config_binding_; - - // Temporarily holds the InterfacePtr to the FakeContext, until it is passed - // to the CastRunner. - chromium::web::ContextPtr fake_context_ptr_; - - // Fake web::Context, and binding to the client CastRunner. - webrunner::FakeContext fake_context_; - fidl::Binding<chromium::web::Context> fake_context_binding_; - - // ServiceDirectory into which the CastRunner will publish itself. - std::unique_ptr<base::fuchsia::ServiceDirectory> service_directory_; - std::unique_ptr<base::fuchsia::ScopedDefaultComponentContext> - scoped_default_component_context_; - - std::unique_ptr<CastRunner> cast_runner_; - fuchsia::sys::RunnerPtr cast_runner_ptr_; - - DISALLOW_COPY_AND_ASSIGN(CastRunnerUnitTest); -}; - -TEST_F(CastRunnerUnitTest, TeardownOnClientUnbind) { - // Disconnect from the CastRunner and wait for it to terminate. - cast_runner_ptr_.Unbind(); - RunUntilCastRunnerIsIdle(); -} - -TEST_F(CastRunnerUnitTest, TeardownOnComponentControllerUnbind) { - // Create a ComponentController pointer, to manage the component lifetime. - fuchsia::sys::ComponentControllerPtr component_controller_ptr; - - // Launch the test-app component, passing a ComponentController request. - base::fuchsia::ComponentContext component_services(StartCastComponent( - base::StringPrintf("cast:%s", - FakeApplicationConfigManager::kTestCastAppId), - &cast_runner_ptr_, component_controller_ptr.NewRequest())); - - // Pump the message-loop to process StartComponent(). If the call is rejected - // then the ComponentControllerPtr's error-handler will be invoked at this - // point. - component_controller_ptr.set_error_handler([](zx_status_t status) { - ZX_LOG(ERROR, status) << "Component launch failed"; - ADD_FAILURE(); - }); - base::RunLoop().RunUntilIdle(); - - // Disconnect ComponentController and expect the CastRunner will terminate. - component_controller_ptr.Unbind(); - RunUntilCastRunnerIsIdle(); -}
diff --git a/fuchsia/runners/cast/fake_application_config_manager.cc b/fuchsia/runners/cast/fake_application_config_manager.cc index 185b8ee..8172e78 100644 --- a/fuchsia/runners/cast/fake_application_config_manager.cc +++ b/fuchsia/runners/cast/fake_application_config_manager.cc
@@ -4,19 +4,19 @@ #include "fuchsia/runners/cast/fake_application_config_manager.h" +#include <string> +#include <utility> + #include "base/logging.h" -const char FakeApplicationConfigManager::kTestCastAppId[] = "00000000"; +FakeApplicationConfigManager::FakeApplicationConfigManager() = default; -FakeApplicationConfigManager::FakeApplicationConfigManager( - net::EmbeddedTestServer* embedded_test_server) - : embedded_test_server_(embedded_test_server) {} FakeApplicationConfigManager::~FakeApplicationConfigManager() = default; void FakeApplicationConfigManager::GetConfig(std::string id, GetConfigCallback callback) { - if (id != kTestCastAppId) { - LOG(ERROR) << "Unknown Cast app Id: " << id; + if (id_to_url_.find(id) == id_to_url_.end()) { + LOG(ERROR) << "Unknown Cast App ID: " << id; callback(chromium::cast::ApplicationConfigPtr()); return; } @@ -25,6 +25,12 @@ chromium::cast::ApplicationConfig::New(); app_config->id = id; app_config->display_name = "Dummy test app"; - app_config->web_url = embedded_test_server_->base_url().spec(); + app_config->web_url = id_to_url_[id].spec(); + callback(std::move(app_config)); } + +void FakeApplicationConfigManager::AddAppMapping(const std::string& id, + const GURL& url) { + id_to_url_[id] = url; +}
diff --git a/fuchsia/runners/cast/fake_application_config_manager.h b/fuchsia/runners/cast/fake_application_config_manager.h index eee8008..7c6a5e1 100644 --- a/fuchsia/runners/cast/fake_application_config_manager.h +++ b/fuchsia/runners/cast/fake_application_config_manager.h
@@ -5,26 +5,30 @@ #ifndef FUCHSIA_RUNNERS_CAST_FAKE_APPLICATION_CONFIG_MANAGER_H_ #define FUCHSIA_RUNNERS_CAST_FAKE_APPLICATION_CONFIG_MANAGER_H_ +#include <map> +#include <string> + #include "base/macros.h" #include "fuchsia/fidl/chromium/cast/cpp/fidl.h" -#include "net/test/embedded_test_server/embedded_test_server.h" +#include "url/gurl.h" // Test cast.ApplicationConfigManager implementation which maps a test Cast -// AppId to an embedded test server address. +// AppId to a URL. class FakeApplicationConfigManager : public chromium::cast::ApplicationConfigManager { public: - static const char kTestCastAppId[]; - - explicit FakeApplicationConfigManager( - net::EmbeddedTestServer* embedded_test_server); + FakeApplicationConfigManager(); ~FakeApplicationConfigManager() override; + // Associates a Cast application |id| with a url, to be served from the + // EmbeddedTestServer. + void AddAppMapping(const std::string& id, const GURL& url); + // chromium::cast::ApplicationConfigManager interface. void GetConfig(std::string id, GetConfigCallback config_callback) override; private: - net::EmbeddedTestServer* embedded_test_server_; + std::map<std::string, GURL> id_to_url_; DISALLOW_COPY_AND_ASSIGN(FakeApplicationConfigManager); };
diff --git a/fuchsia/runners/cast/test_common.cc b/fuchsia/runners/cast/test_common.cc index 2f56a7e..3b8b0c0454 100644 --- a/fuchsia/runners/cast/test_common.cc +++ b/fuchsia/runners/cast/test_common.cc
@@ -4,21 +4,54 @@ #include "fuchsia/runners/cast/test_common.h" +#include <lib/fidl/cpp/binding.h> +#include <memory> +#include <utility> + +#include "base/bind.h" #include "base/fuchsia/fuchsia_logging.h" +#include "base/fuchsia/service_directory.h" +#include "base/run_loop.h" zx::channel StartCastComponent( const base::StringPiece& cast_url, fuchsia::sys::RunnerPtr* sys_runner, fidl::InterfaceRequest<fuchsia::sys::ComponentController> - component_controller_request) { + component_controller_request, + fidl::Binding<chromium::cast::CastChannel>* cast_channel_binding) { + // Construct, bind, and populate a ServiceDirectory for publishing + // the CastChannel service to the CastComponent. + auto service_list = std::make_unique<fuchsia::sys::ServiceList>(); + zx::channel cast_channel_dir_request, cast_channel_dir_client; + zx_status_t status = zx::channel::create(0, &cast_channel_dir_request, + &cast_channel_dir_client); + ZX_CHECK(status == ZX_OK, status) << "zx_channel_create"; + base::fuchsia::ServiceDirectory cast_channel_directory( + std::move(cast_channel_dir_request)); + base::RunLoop service_connect_runloop; + cast_channel_directory.AddService( + chromium::cast::CastChannel::Name_, + base::BindRepeating( + [](base::RepeatingClosure on_connect_cb, + fidl::Binding<chromium::cast::CastChannel>* cast_channel_binding_, + zx::channel channel) { + cast_channel_binding_->Bind(std::move(channel)); + on_connect_cb.Run(); + }, + base::Passed(service_connect_runloop.QuitClosure()), + base::Unretained(cast_channel_binding))); + service_list->names.push_back(chromium::cast::CastChannel::Name_); + service_list->host_directory = std::move(cast_channel_dir_client); + fuchsia::sys::LaunchInfo launch_info; launch_info.url = cast_url.as_string(); + launch_info.additional_services = std::move(service_list); // Create a channel to pass to the Runner, through which to expose the new // component's ServiceDirectory. zx::channel service_directory_client; - zx_status_t status = zx::channel::create(0, &service_directory_client, - &launch_info.directory_request); + status = zx::channel::create(0, &service_directory_client, + &launch_info.directory_request); ZX_CHECK(status == ZX_OK, status) << "zx_channel_create"; fuchsia::sys::StartupInfo startup_info; @@ -33,5 +66,12 @@ sys_runner->get()->StartComponent(std::move(package), std::move(startup_info), std::move(component_controller_request)); + + // Process the runloop until the CastChannel FIDL service is connected. + service_connect_runloop.Run(); + + // Prepare the service directory for clean teardown. + cast_channel_directory.RemoveAllServices(); + return service_directory_client; }
diff --git a/fuchsia/runners/cast/test_common.h b/fuchsia/runners/cast/test_common.h index a811210..98dbac32 100644 --- a/fuchsia/runners/cast/test_common.h +++ b/fuchsia/runners/cast/test_common.h
@@ -6,15 +6,21 @@ #define FUCHSIA_RUNNERS_CAST_TEST_COMMON_H_ #include <fuchsia/sys/cpp/fidl.h> +#include <lib/fidl/cpp/binding.h> #include "base/strings/string_piece.h" +#include "fuchsia/fidl/chromium/cast/cpp/fidl.h" -// Starts a cast component from the runner |sys_runner| with the URL |cast_url| -// and returns the service directory client channel. +// Starts a Cast component from the runner |sys_runner| with the URL |cast_url| +// and returns the outgoing service directory client channel. +// The Cast component will connect to the CastChannel FIDL service bound at +// |cast_channel_binding|. +// Blocks until |cast_channel_binding| is bound. zx::channel StartCastComponent( const base::StringPiece& cast_url, fuchsia::sys::RunnerPtr* sys_runner, fidl::InterfaceRequest<fuchsia::sys::ComponentController> - component_controller_request); + component_controller_request, + fidl::Binding<chromium::cast::CastChannel>* cast_channel_binding); -#endif // FUCHSIA_RUNNERS_CAST_TEST_COMMON_H_ \ No newline at end of file +#endif // FUCHSIA_RUNNERS_CAST_TEST_COMMON_H_
diff --git a/fuchsia/runners/common/web_component.cc b/fuchsia/runners/common/web_component.cc index e410f79..50864fa 100644 --- a/fuchsia/runners/common/web_component.cc +++ b/fuchsia/runners/common/web_component.cc
@@ -20,19 +20,10 @@ termination_reason_); } -// static -std::unique_ptr<WebComponent> WebComponent::ForUrlRequest( - WebContentRunner* runner, - const GURL& url, - fuchsia::sys::StartupInfo startup_info, - fidl::InterfaceRequest<fuchsia::sys::ComponentController> - controller_request) { +void WebComponent::LoadUrl(const GURL& url) { DCHECK(url.is_valid()); - std::unique_ptr<WebComponent> component(new WebComponent( - runner, std::move(startup_info), std::move(controller_request))); chromium::web::NavigationControllerPtr navigation_controller; - component->frame()->GetNavigationController( - navigation_controller.NewRequest()); + frame()->GetNavigationController(navigation_controller.NewRequest()); // Set the page activation flag on the initial load, so that features like // autoplay work as expected when a WebComponent first loads the specified @@ -41,8 +32,6 @@ params->user_activated = true; navigation_controller->LoadUrl(url.spec(), std::move(params)); - - return component; } WebComponent::WebComponent( @@ -53,6 +42,16 @@ : runner_(runner), controller_binding_(this) { DCHECK(runner); + // Handle the incoming services directory for this component. + if (startup_info.launch_info.additional_services && + startup_info.launch_info.additional_services->host_directory) { + additional_services_ = + std::make_unique<base::fuchsia::ComponentContext>(std::move( + startup_info.launch_info.additional_services->host_directory)); + additional_service_names_ = + std::move(startup_info.launch_info.additional_services->names); + } + // If the ComponentController request is valid then bind it, and configure it // to destroy this component on error. if (controller_request.is_valid()) {
diff --git a/fuchsia/runners/common/web_component.h b/fuchsia/runners/common/web_component.h index 3bd4334..6d493835 100644 --- a/fuchsia/runners/common/web_component.h +++ b/fuchsia/runners/common/web_component.h
@@ -11,9 +11,11 @@ #include <lib/fidl/cpp/binding.h> #include <lib/fidl/cpp/binding_set.h> #include <memory> +#include <string> #include <utility> #include <vector> +#include "base/fuchsia/component_context.h" #include "base/fuchsia/scoped_service_binding.h" #include "base/fuchsia/service_directory.h" #include "base/logging.h" @@ -32,19 +34,6 @@ public fuchsia::ui::app::ViewProvider, public fuchsia::ui::viewsv1::ViewProvider { public: - ~WebComponent() override; - - // Creates a WebComponent and navigates its Frame to |url|. - static std::unique_ptr<WebComponent> ForUrlRequest( - WebContentRunner* runner, - const GURL& url, - fuchsia::sys::StartupInfo startup_info, - fidl::InterfaceRequest<fuchsia::sys::ComponentController> - controller_request); - - chromium::web::Frame* frame() { return frame_.get(); } - - protected: // Creates a WebComponent encapsulating a web.Frame. A ViewProvider service // will be published to the service-directory specified in |startup_info|, and // if |controller_request| is valid then it will be bound to this component, @@ -55,6 +44,14 @@ fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller_request); + ~WebComponent() override; + + // Navigates this component's Frame to |url|. + void LoadUrl(const GURL& url); + + chromium::web::Frame* frame() const { return frame_.get(); } + + protected: // fuchsia::sys::ComponentController implementation. void Kill() override; void Detach() override; @@ -73,20 +70,37 @@ // Reports the supplied exit-code and reason to the |controller_binding_| and // requests that the |runner_| delete this component. - void DestroyComponent(int termination_exit_code, - fuchsia::sys::TerminationReason reason); + virtual void DestroyComponent(int termination_exit_code, + fuchsia::sys::TerminationReason reason); - base::fuchsia::ServiceDirectory* service_directory() { + // Gets a directory of incoming services provided to the component, or returns + // nullptr if none was provided. + base::fuchsia::ComponentContext* additional_services() const { + return additional_services_.get(); + } + + // Gets the names of services available in additional_services(). + const std::vector<std::string> additional_service_names() { + return additional_service_names_; + } + + base::fuchsia::ServiceDirectory* service_directory() const { return service_directory_.get(); } private: - WebContentRunner* runner_ = nullptr; + WebContentRunner* const runner_ = nullptr; chromium::web::FramePtr frame_; fidl::Binding<fuchsia::sys::ComponentController> controller_binding_; + // Incoming services provided at component creation. + std::unique_ptr<base::fuchsia::ComponentContext> additional_services_; + + // The names of services provided at component creation. + std::vector<std::string> additional_service_names_; + // Objects used for binding and exporting the ViewProvider service. std::unique_ptr<base::fuchsia::ServiceDirectory> service_directory_; std::unique_ptr<
diff --git a/fuchsia/runners/common/web_content_runner.cc b/fuchsia/runners/common/web_content_runner.cc index 510de976..3eb9995 100644 --- a/fuchsia/runners/common/web_content_runner.cc +++ b/fuchsia/runners/common/web_content_runner.cc
@@ -73,9 +73,10 @@ return; } - RegisterComponent(WebComponent::ForUrlRequest(this, std::move(url), - std::move(startup_info), - std::move(controller_request))); + std::unique_ptr<WebComponent> component = std::make_unique<WebComponent>( + this, std::move(startup_info), std::move(controller_request)); + component->LoadUrl(url); + RegisterComponent(std::move(component)); } void WebContentRunner::GetWebComponentForTest( @@ -88,6 +89,7 @@ } void WebContentRunner::DestroyComponent(WebComponent* component) { + LOG(ERROR) << "DestroyComponent " << components_.size(); components_.erase(components_.find(component)); if (components_.empty()) @@ -99,9 +101,7 @@ if (web_component_test_callback_) { std::move(web_component_test_callback_).Run(component.get()); } - if (component) { - components_.insert(std::move(component)); - } + components_.insert(std::move(component)); } void WebContentRunner::RunOnIdleClosureIfValid() {
diff --git a/gpu/command_buffer/service/gl_utils.cc b/gpu/command_buffer/service/gl_utils.cc index 39428c16..25def54d 100644 --- a/gpu/command_buffer/service/gl_utils.cc +++ b/gpu/command_buffer/service/gl_utils.cc
@@ -903,6 +903,19 @@ break; } + // CopyTex{Sub}Image2D() from GL_RGB10_A2 has issues on some Android chipsets. + if (source_internal_format == GL_RGB10_A2) { + if (feature_info->workarounds().disable_copy_tex_image_2d_rgb10_a2_tegra) { + if (dest_internal_format == GL_RGBA4) + return CopyTextureMethod::DIRECT_DRAW; + return CopyTextureMethod::DRAW_AND_COPY; + } + if (feature_info->workarounds().disable_copy_tex_image_2d_rgb10_a2_adreno && + dest_internal_format != GL_RGB10_A2) { + return CopyTextureMethod::DRAW_AND_COPY; + } + } + // CopyTexImage* should not allow internalformat of GL_BGRA_EXT and // GL_BGRA8_EXT. https://crbug.com/663086. bool copy_tex_image_format_valid = @@ -1018,7 +1031,8 @@ source_internal_format == GL_BGRA8_EXT || source_internal_format == GL_RGB_YCBCR_420V_CHROMIUM || source_internal_format == GL_RGB_YCBCR_422_CHROMIUM || - source_internal_format == GL_R16_EXT; + source_internal_format == GL_R16_EXT || + source_internal_format == GL_RGB10_A2; if (!valid_source_format) { *output_error_msg = "invalid source internal format " + GLES2Util::GetStringEnum(source_internal_format);
diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc index 939bf436..a58de95 100644 --- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc +++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
@@ -43,6 +43,7 @@ S_FORMAT_RGB_YCBCR_420V_CHROMIUM, S_FORMAT_RGB_YCBCR_422_CHROMIUM, S_FORMAT_COMPRESSED, + S_FORMAT_RGB10_A2, NUM_S_FORMAT }; @@ -185,8 +186,12 @@ case GL_ETC1_RGB8_OES: sourceFormatIndex = S_FORMAT_COMPRESSED; break; + case GL_RGB10_A2: + sourceFormatIndex = S_FORMAT_RGB10_A2; + break; default: - NOTREACHED(); + NOTREACHED() << "Invalid source format " + << gl::GLEnums::GetStringEnum(source_format); break; }
diff --git a/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc b/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc index 78255a9..92a1da40 100644 --- a/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc +++ b/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc
@@ -14,10 +14,12 @@ #include <stdint.h> #include "base/stl_util.h" +#include "build/build_config.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" +#include "ui/gl/gl_enums.h" #include "ui/gl/gl_version_info.h" namespace gpu { @@ -153,11 +155,11 @@ color[3] = a; } -void getExpectedColor(GLenum src_internal_format, - GLenum dest_internal_format, - uint8_t* color, - uint8_t* expected_color, - uint8_t* mask) { +void getExpectedColorAndMask(GLenum src_internal_format, + GLenum dest_internal_format, + const uint8_t* color, + uint8_t* expected_color, + uint8_t* expected_mask) { uint8_t adjusted_color[4]; switch (src_internal_format) { case GL_ALPHA: @@ -187,37 +189,34 @@ case GL_BGRA8_EXT: setColor(color[2], color[1], color[0], color[3], adjusted_color); break; + case GL_RGB10_A2: { + // Map the source 2-bit Alpha to 8-bits. + const uint8_t alpha_value = (color[3] & 0x3) * 255 / 3; + setColor(color[0] >> 2, color[1] >> 2, color[2] >> 2, alpha_value, + adjusted_color); + break; + } default: - NOTREACHED(); + NOTREACHED() << gl::GLEnums::GetStringEnum(src_internal_format); break; } switch (dest_internal_format) { - case GL_ALPHA: - setColor(0, 0, 0, adjusted_color[3], expected_color); - setColor(0, 0, 0, 1, mask); - break; + // TODO(crbug.com/577144): Enable GL_ALPHA, GL_LUMINANCE and + // GL_LUMINANCE_ALPHA. case GL_R8: case GL_R16F: case GL_R32F: case GL_R8UI: setColor(adjusted_color[0], 0, 0, 0, expected_color); - setColor(1, 0, 0, 0, mask); - break; - case GL_LUMINANCE: - setColor(adjusted_color[0], 0, 0, 0, expected_color); - setColor(1, 0, 0, 0, mask); - break; - case GL_LUMINANCE_ALPHA: - setColor(adjusted_color[0], 0, 0, adjusted_color[3], expected_color); - setColor(1, 0, 0, 1, mask); + setColor(1, 0, 0, 0, expected_mask); break; case GL_RG8: case GL_RG16F: case GL_RG32F: case GL_RG8UI: setColor(adjusted_color[0], adjusted_color[1], 0, 0, expected_color); - setColor(1, 1, 0, 0, mask); + setColor(1, 1, 0, 0, expected_mask); break; case GL_RGB: case GL_RGB8: @@ -231,7 +230,7 @@ case GL_RGB8UI: setColor(adjusted_color[0], adjusted_color[1], adjusted_color[2], 0, expected_color); - setColor(1, 1, 1, 0, mask); + setColor(1, 1, 1, 0, expected_mask); break; case GL_RGBA: case GL_RGBA8: @@ -245,8 +244,25 @@ case GL_RGBA8UI: setColor(adjusted_color[0], adjusted_color[1], adjusted_color[2], adjusted_color[3], expected_color); - setColor(1, 1, 1, 1, mask); + setColor(1, 1, 1, 1, expected_mask); break; + case GL_RGB10_A2: { + // Map the 2-bit Alpha values back to full bytes. + constexpr uint8_t step = 0x55; + const uint8_t alpha_value = (adjusted_color[3] + step / 2) / step * step; + + setColor(adjusted_color[0], adjusted_color[1], adjusted_color[2], + alpha_value, expected_color); +#if defined(OS_MACOSX) || defined(OS_LINUX) + // The alpha channel values for LUMINANCE_ALPHA source don't work OK + // on Mac or Linux, so skip comparison of those, see crbug.com/926579 + setColor(1, 1, 1, src_internal_format != GL_LUMINANCE_ALPHA, + expected_mask); +#else + setColor(1, 1, 1, 1, expected_mask); +#endif + break; + } case GL_RGB5_A1: setColor(adjusted_color[0], adjusted_color[1], adjusted_color[2], (adjusted_color[3] >> 7) ? 0xFF : 0x0, expected_color); @@ -254,10 +270,10 @@ // channel of expected color is the source alpha value other than 255. // This should be wrong. Skip the alpha channel check and revisit this in // future. - setColor(1, 1, 1, 0, mask); + setColor(1, 1, 1, 0, expected_mask); break; default: - NOTREACHED(); + NOTREACHED() << gl::GLEnums::GetStringEnum(dest_internal_format); break; } } @@ -271,38 +287,51 @@ uint8_t* expected_mask) { const uint32_t src_channel_count = gles2::GLES2Util::ElementsPerGroup( src_format_type.format, src_format_type.type); - uint8_t color[4] = {1u, 63u, 127u, 255u}; - getExpectedColor(src_format_type.internal_format, - dest_format_type.internal_format, color, expected_color, - expected_mask); + constexpr uint8_t color[4] = {1u, 63u, 127u, 255u}; + getExpectedColorAndMask(src_format_type.internal_format, + dest_format_type.internal_format, color, + expected_color, expected_mask); + const size_t num_pixels = width * height; + // TODO(mcasas): use std::make_unique<uint8_t[]> in this function. + if (src_format_type.type == GL_UNSIGNED_BYTE) { std::unique_ptr<uint8_t[]> pixels( - new uint8_t[width * height * src_channel_count]); - for (uint32_t i = 0; i < width * height * src_channel_count; + new uint8_t[num_pixels * src_channel_count]); + for (uint32_t i = 0; i < num_pixels * src_channel_count; i += src_channel_count) { for (uint32_t j = 0; j < src_channel_count; ++j) pixels[i + j] = color[j]; } return pixels; } else if (src_format_type.type == GL_UNSIGNED_SHORT) { - uint16_t color_16bit[4] = {1u << 8, 63u << 8, 127u << 8, 255u << 8}; + constexpr uint16_t color_16bit[4] = {color[0] << 8, color[1] << 8, + color[2] << 8, color[3] << 8}; std::unique_ptr<uint8_t[]> data( - new uint8_t[width * height * src_channel_count * sizeof(uint16_t)]); + new uint8_t[num_pixels * src_channel_count * sizeof(uint16_t)]); uint16_t* pixels = reinterpret_cast<uint16_t*>(data.get()); int16_t flip_sign = -1; - for (uint32_t i = 0; i < width * height * src_channel_count; + for (uint32_t i = 0; i < num_pixels * src_channel_count; i += src_channel_count) { for (uint32_t j = 0; j < src_channel_count; ++j) { // Introduce an offset to the value to check. Expected value should be // the same as without the offset. flip_sign *= -1; pixels[i + j] = - color_16bit[j] + flip_sign * (0x7F * (i + j)) / (width * height); + color_16bit[j] + flip_sign * (0x7F * (i + j)) / num_pixels; } } return data; + } else if (src_format_type.type == GL_UNSIGNED_INT_2_10_10_10_REV) { + DCHECK_EQ(src_channel_count, 1u); + constexpr uint32_t color_rgb10_a2 = ((color[3] & 0x3) << 30) + + (color[2] << 20) + (color[1] << 10) + + color[0]; + std::unique_ptr<uint8_t[]> data(new uint8_t[num_pixels * sizeof(uint32_t)]); + uint32_t* pixels = reinterpret_cast<uint32_t*>(data.get()); + std::fill(pixels, pixels + num_pixels, color_rgb10_a2); + return data; } - NOTREACHED(); + NOTREACHED() << gl::GLEnums::GetStringEnum(src_format_type.type); return nullptr; } @@ -477,7 +506,9 @@ textures_[1], dest_level, 0, 0, 0, 0, width_, height_, false, false, false); } - EXPECT_TRUE(glGetError() == GL_NO_ERROR); + const GLenum last_error = glGetError(); + EXPECT_TRUE(last_error == GL_NO_ERROR) + << gl::GLEnums::GetStringError(last_error); // Draw destination texture to a fbo with a TEXTURE_2D texture attachment // in RGBA format. @@ -571,6 +602,20 @@ #endif return !gl_.decoder()->GetFeatureInfo()->feature_flags().ext_texture_norm16; } + + bool ShouldSkipRGB10A2() const { + DCHECK(!ShouldSkipTest()); + const gl::GLVersionInfo& gl_version_info = + gl_.decoder()->GetFeatureInfo()->gl_version_info(); + // XB30 support was introduced in GLES 3.0/ OpenGL 3.3, before that it was + // signalled via a specific extension. + const bool supports_rgb10_a2 = + gl_version_info.IsAtLeastGL(3, 3) || + gl_version_info.IsAtLeastGLES(3, 0) || + GLTestHelper::HasExtension("GL_EXT_texture_type_2_10_10_10_REV"); + EXPECT_TRUE(supports_rgb10_a2); + return !supports_rgb10_a2; + } }; INSTANTIATE_TEST_CASE_P(CopyType, @@ -627,7 +672,7 @@ << "Passthrough command decoder expected failure. Skipping test..."; return; } - CopyType copy_type = GetParam(); + const CopyType copy_type = GetParam(); FormatType src_format_types[] = { {GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE}, @@ -639,6 +684,7 @@ {GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE}, {GL_BGRA8_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE}, {GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT}, + {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, }; FormatType dest_format_types[] = { @@ -683,6 +729,7 @@ {GL_RGBA16F, GL_RGBA, GL_FLOAT}, {GL_RGBA32F, GL_RGBA, GL_FLOAT}, {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE}, + {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, }; for (auto src_format_type : src_format_types) { @@ -695,14 +742,18 @@ continue; } if (gles2::GLES2Util::IsFloatFormat(dest_format_type.internal_format) && - ShouldSkipFloatFormat()) + ShouldSkipFloatFormat()) { continue; + } if ((dest_format_type.internal_format == GL_SRGB_EXT || dest_format_type.internal_format == GL_SRGB_ALPHA_EXT) && - ShouldSkipSRGBEXT()) + ShouldSkipSRGBEXT()) { continue; + } if (src_format_type.internal_format == GL_R16_EXT && ShouldSkipNorm16()) continue; + if (src_format_type.internal_format == GL_RGB10_A2 && ShouldSkipRGB10A2()) + continue; RunCopyTexture(GL_TEXTURE_2D, copy_type, src_format_type, 0, dest_format_type, 0, true);
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json index 2ac3cf7..9544558e 100644 --- a/gpu/config/gpu_driver_bug_list.json +++ b/gpu/config/gpu_driver_bug_list.json
@@ -3067,6 +3067,41 @@ "features": [ "disable_direct_composition" ] + }, + { + "id": 287, + "description": "glCopyTexImage2D on Adreno fails if source is GL_RGB10_A2 and destination is not.", + "cr_bugs": [925986], + "os": { + "type": "android", + "version": { + "op": ">=", + "value": "5.0.0" + } + }, + "gl_vendor": "Qualcomm.*", + "gl_renderer": ".*4\\d\\d", + "gl_renderer": "Adreno \\(TM\\) [345].*", + "features": [ + "disable_copy_tex_image_2d_rgb10_a2_adreno" + ] + }, + { + "id": 288, + "description": "glCopyTexImage2D on NVIDIA Tegra fails in certain cases if source is GL_RGB10_A2.", + "cr_bugs": [925986], + "os": { + "type": "android" + }, + "gl_vendor": "NVIDIA.*", + "gl_type": "gles", + "gl_version": { + "op": ">=", + "value": "3.0" + }, + "features": [ + "disable_copy_tex_image_2d_rgb10_a2_tegra" + ] } ] }
diff --git a/gpu/config/gpu_workaround_list.txt b/gpu/config/gpu_workaround_list.txt index 826c74a..15db5f45 100644 --- a/gpu/config/gpu_workaround_list.txt +++ b/gpu/config/gpu_workaround_list.txt
@@ -106,3 +106,5 @@ validate_multisample_buffer_allocation wake_up_gpu_before_drawing use_copyteximage2d_instead_of_readpixels_on_multisampled_textures +disable_copy_tex_image_2d_rgb10_a2_adreno +disable_copy_tex_image_2d_rgb10_a2_tegra
diff --git a/ios/chrome/browser/snapshots/BUILD.gn b/ios/chrome/browser/snapshots/BUILD.gn index f6f575e1..a35f0093 100644 --- a/ios/chrome/browser/snapshots/BUILD.gn +++ b/ios/chrome/browser/snapshots/BUILD.gn
@@ -12,7 +12,6 @@ "snapshot_cache_tab_model_list_observer.h", "snapshot_cache_web_state_list_observer.h", "snapshot_generator_delegate.h", - "snapshot_overlay.h", "snapshot_tab_helper.h", "snapshots_util.h", ] @@ -24,7 +23,6 @@ "snapshot_cache_web_state_list_observer.mm", "snapshot_generator.h", "snapshot_generator.mm", - "snapshot_overlay.mm", "snapshot_tab_helper.mm", "snapshots_util.mm", ]
diff --git a/ios/chrome/browser/snapshots/fake_snapshot_generator_delegate.mm b/ios/chrome/browser/snapshots/fake_snapshot_generator_delegate.mm index 3565213..b81b35f 100644 --- a/ios/chrome/browser/snapshots/fake_snapshot_generator_delegate.mm +++ b/ios/chrome/browser/snapshots/fake_snapshot_generator_delegate.mm
@@ -22,9 +22,8 @@ return UIEdgeInsetsZero; } -- (NSArray<SnapshotOverlay*>*)snapshotGenerator: - (SnapshotGenerator*)snapshotGenerator - snapshotOverlaysForWebState:(web::WebState*)webState { +- (NSArray<UIView*>*)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator + snapshotOverlaysForWebState:(web::WebState*)webState { return nil; }
diff --git a/ios/chrome/browser/snapshots/snapshot_generator.mm b/ios/chrome/browser/snapshots/snapshot_generator.mm index 2a4b6e59..4b6bacb 100644 --- a/ios/chrome/browser/snapshots/snapshot_generator.mm +++ b/ios/chrome/browser/snapshots/snapshot_generator.mm
@@ -13,7 +13,6 @@ #import "ios/chrome/browser/snapshots/snapshot_cache.h" #import "ios/chrome/browser/snapshots/snapshot_cache_factory.h" #import "ios/chrome/browser/snapshots/snapshot_generator_delegate.h" -#import "ios/chrome/browser/snapshots/snapshot_overlay.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/web/public/web_state/web_state.h" @@ -27,6 +26,14 @@ #error "This file requires ARC support." #endif +// Contains information needed for snapshotting. +struct SnapshotInfo { + UIView* baseView; + CGRect snapshotFrameInBaseView; + CGRect snapshotFrameInWindow; + NSArray<UIView*>* overlays; +}; + @interface SnapshotGenerator ()<CRWWebStateObserver> // Property providing access to the snapshot's cache. May be nil. @@ -115,23 +122,23 @@ } return; } - UIView* snapshotView = [self.delegate snapshotGenerator:self - baseViewForWebState:self.webState]; - CGRect snapshotFrame = - [self.webState->GetView() convertRect:[self snapshotFrame] - fromView:snapshotView]; - NSArray<SnapshotOverlay*>* overlays = - [self.delegate snapshotGenerator:self - snapshotOverlaysForWebState:self.webState]; - + SnapshotInfo snapshotInfo = [self getSnapshotInfo]; + CGRect snapshotFrameInWebView = + [self.webState->GetView() convertRect:snapshotInfo.snapshotFrameInBaseView + fromView:snapshotInfo.baseView]; [self.delegate snapshotGenerator:self willUpdateSnapshotForWebState:self.webState]; __weak SnapshotGenerator* weakSelf = self; self.webState->TakeSnapshot( - gfx::RectF(snapshotFrame), base::BindOnce(^(const gfx::Image& image) { - UIImage* snapshot = [weakSelf snapshotWithOverlays:overlays - baseImage:image - frame:snapshotFrame]; + gfx::RectF(snapshotFrameInWebView), + base::BindOnce(^(const gfx::Image& image) { + UIImage* snapshot = nil; + if (!image.IsEmpty()) { + snapshot = [weakSelf + snapshotWithOverlays:snapshotInfo.overlays + baseImage:image.ToUIImage() + frameInWindow:snapshotInfo.snapshotFrameInWindow]; + } [weakSelf updateSnapshotCacheWithImage:snapshot]; if (completion) completion(snapshot); @@ -141,17 +148,16 @@ - (UIImage*)generateSnapshotWithOverlays:(BOOL)shouldAddOverlay { if (![self canTakeSnapshot]) return nil; - NSArray<SnapshotOverlay*>* overlays = - shouldAddOverlay ? [self.delegate snapshotGenerator:self - snapshotOverlaysForWebState:self.webState] - : nil; - UIView* view = [self.delegate snapshotGenerator:self - baseViewForWebState:self.webState]; + SnapshotInfo snapshotInfo = [self getSnapshotInfo]; [self.delegate snapshotGenerator:self willUpdateSnapshotForWebState:self.webState]; - return [self snapshotWithOverlays:overlays - baseView:view - frame:[self snapshotFrame]]; + UIImage* baseImage = + [self snapshotNonWebView:snapshotInfo.baseView + frameInBaseView:snapshotInfo.snapshotFrameInBaseView]; + return [self + snapshotWithOverlays:(shouldAddOverlay ? snapshotInfo.overlays : nil) + baseImage:baseImage + frameInWindow:snapshotInfo.snapshotFrameInWindow]; } - (void)removeSnapshot { @@ -175,37 +181,27 @@ canTakeSnapshotForWebState:self.webState]; } -// Returns the frame of the snapshot. -- (CGRect)snapshotFrame { - UIView* view = [self.delegate snapshotGenerator:self - baseViewForWebState:self.webState]; - UIEdgeInsets headerInsets = [self.delegate snapshotGenerator:self - snapshotEdgeInsetsForWebState:self.webState]; - CGRect frame = UIEdgeInsetsInsetRect(view.bounds, headerInsets); - DCHECK(!CGRectIsEmpty(frame)); - return frame; -} - -// Returns an image of the |view| overlaid with |overlays| with the given -// |frame|. -- (UIImage*)snapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays - baseView:(UIView*)view - frame:(CGRect)frame { - DCHECK(view); - DCHECK(!CGRectIsEmpty(frame)); +// Returns a snapshot of |baseView| with |frameInBaseView|. +- (UIImage*)snapshotNonWebView:(UIView*)baseView + frameInBaseView:(CGRect)frameInBaseView { + DCHECK(baseView); + DCHECK(!CGRectIsEmpty(frameInBaseView)); const CGFloat kScale = std::max<CGFloat>(1.0, [self.snapshotCache snapshotScaleForDevice]); - UIGraphicsBeginImageContextWithOptions(frame.size, YES, kScale); + UIGraphicsBeginImageContextWithOptions(frameInBaseView.size, YES, kScale); CGContext* context = UIGraphicsGetCurrentContext(); - CGContextTranslateCTM(context, -frame.origin.x, -frame.origin.y); + // This shifts the origin of the context to be the origin of the snapshot + // frame. + CGContextTranslateCTM(context, -frameInBaseView.origin.x, + -frameInBaseView.origin.y); BOOL snapshotSuccess = YES; if (base::FeatureList::IsEnabled(kSnapshotDrawView)) { - snapshotSuccess = - [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO]; + // The rect's origin is ignored. Only size is used. + snapshotSuccess = [baseView drawViewHierarchyInRect:frameInBaseView + afterScreenUpdates:NO]; } else { - [[view layer] renderInContext:context]; + [[baseView layer] renderInContext:context]; } - [self drawOverlays:overlays context:context]; UIImage* image = nil; if (snapshotSuccess) image = UIGraphicsGetImageFromCurrentImageContext(); @@ -213,21 +209,30 @@ return image; } -// Returns an image of the |image| overlaid with |overlays| with the given -// |frame|. -- (UIImage*)snapshotWithOverlays:(NSArray<SnapshotOverlay*>*)overlays - baseImage:(const gfx::Image&)image - frame:(CGRect)frame { - DCHECK(!CGRectIsEmpty(frame)); - if (image.IsEmpty()) +// Returns an image of the |baseImage| overlaid with |overlays| with the given +// |frameInWindow|. +- (UIImage*)snapshotWithOverlays:(NSArray<UIView*>*)overlays + baseImage:(UIImage*)baseImage + frameInWindow:(CGRect)frameInWindow { + DCHECK(!CGRectIsEmpty(frameInWindow)); + if (!baseImage) return nil; + DCHECK(CGSizeEqualToSize(baseImage.size, frameInWindow.size)); if (overlays.count == 0) - return image.ToUIImage(); + return baseImage; const CGFloat kScale = std::max<CGFloat>(1.0, [self.snapshotCache snapshotScaleForDevice]); - UIGraphicsBeginImageContextWithOptions(frame.size, YES, kScale); + UIGraphicsBeginImageContextWithOptions(frameInWindow.size, YES, kScale); CGContext* context = UIGraphicsGetCurrentContext(); - [image.ToUIImage() drawAtPoint:CGPointZero]; + // The base image is already a cropped snapshot so it is drawn at the origin + // of the new image. + [baseImage drawAtPoint:CGPointZero]; + // This shifts the origin of the context so that future drawings can be in + // window coordinates. For example, suppose that the desired snapshot area is + // at (0, 99) in the window coordinate space. Drawing at (0, 99) will appear + // as (0, 0) in the resulting image. + CGContextTranslateCTM(context, -frameInWindow.origin.x, + -frameInWindow.origin.y); [self drawOverlays:overlays context:context]; UIImage* snapshot = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); @@ -244,30 +249,49 @@ } } -// Draws |overlays| onto |context|. -- (void)drawOverlays:(NSArray<SnapshotOverlay*>*)overlays - context:(CGContext*)context { - for (SnapshotOverlay* overlay in overlays) { - // Render the overlay view at the desired offset. It is achieved - // by shifting origin of context because view frame is ignored when - // drawing to context. +// Draws |overlays| onto |context| at offsets relative to the window. +- (void)drawOverlays:(NSArray<UIView*>*)overlays context:(CGContext*)context { + for (UIView* overlay in overlays) { CGContextSaveGState(context); - CGContextTranslateCTM(context, 0, overlay.yOffset); + CGRect frameInWindow = [overlay.superview convertRect:overlay.frame + toView:nil]; + // This shifts the context so that drawing starts at the overlay's offset. + CGContextTranslateCTM(context, frameInWindow.origin.x, + frameInWindow.origin.y); // |drawViewHierarchyInRect:| has undefined behavior when the view is not // in the visible view hierarchy. In practice, when this method is called // on a view that is part of view controller containment, an // UIViewControllerHierarchyInconsistency exception will be thrown. - if (base::FeatureList::IsEnabled(kSnapshotDrawView) && - overlay.view.window) { - [overlay.view drawViewHierarchyInRect:overlay.view.bounds - afterScreenUpdates:YES]; + if (base::FeatureList::IsEnabled(kSnapshotDrawView) && overlay.window) { + // The rect's origin is ignored. Only size is used. + [overlay drawViewHierarchyInRect:overlay.bounds afterScreenUpdates:YES]; } else { - [[overlay.view layer] renderInContext:context]; + [[overlay layer] renderInContext:context]; } CGContextRestoreGState(context); } } +// Retrieves information needed for snapshotting. +- (SnapshotInfo)getSnapshotInfo { + SnapshotInfo snapshotInfo; + snapshotInfo.baseView = [self.delegate snapshotGenerator:self + baseViewForWebState:self.webState]; + DCHECK(snapshotInfo.baseView); + UIEdgeInsets baseViewInsets = [self.delegate snapshotGenerator:self + snapshotEdgeInsetsForWebState:self.webState]; + snapshotInfo.snapshotFrameInBaseView = + UIEdgeInsetsInsetRect(snapshotInfo.baseView.bounds, baseViewInsets); + DCHECK(!CGRectIsEmpty(snapshotInfo.snapshotFrameInBaseView)); + snapshotInfo.snapshotFrameInWindow = + [snapshotInfo.baseView convertRect:snapshotInfo.snapshotFrameInBaseView + toView:nil]; + DCHECK(!CGRectIsEmpty(snapshotInfo.snapshotFrameInWindow)); + snapshotInfo.overlays = [self.delegate snapshotGenerator:self + snapshotOverlaysForWebState:self.webState]; + return snapshotInfo; +} + #pragma mark - Properties - (SnapshotCache*)snapshotCache {
diff --git a/ios/chrome/browser/snapshots/snapshot_generator_delegate.h b/ios/chrome/browser/snapshots/snapshot_generator_delegate.h index b5e61940..1f3fa51 100644 --- a/ios/chrome/browser/snapshots/snapshot_generator_delegate.h +++ b/ios/chrome/browser/snapshots/snapshot_generator_delegate.h
@@ -8,7 +8,6 @@ #import <UIKit/UIKit.h> @class SnapshotGenerator; -@class SnapshotOverlay; namespace web { class WebState; @@ -28,12 +27,13 @@ - (UIEdgeInsets)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator snapshotEdgeInsetsForWebState:(web::WebState*)webState; -// Returns the list of SnapshotOverlays that should be rendered over the +// Returns the list of overlay views that should be rendered over the // page when generating the snapshot for |webState|. If no overlays should -// be rendered, the list may be nil or empty. -- (NSArray<SnapshotOverlay*>*)snapshotGenerator: - (SnapshotGenerator*)snapshotGenerator - snapshotOverlaysForWebState:(web::WebState*)webState; +// be rendered, the list may be nil or empty. The order of views in the array +// will be the z order of their image in the composed snapshot. A view at the +// end of the array will appear in front of a view at the beginning. +- (NSArray<UIView*>*)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator + snapshotOverlaysForWebState:(web::WebState*)webState; // Invoked before capturing a snapshot for |webState|. The delegate can remove // subviews from the hierarchy or take other actions to ensure the snapshot
diff --git a/ios/chrome/browser/snapshots/snapshot_overlay.h b/ios/chrome/browser/snapshots/snapshot_overlay.h deleted file mode 100644 index 6253795e..0000000 --- a/ios/chrome/browser/snapshots/snapshot_overlay.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2013 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_CHROME_BROWSER_SNAPSHOTS_SNAPSHOT_OVERLAY_H_ -#define IOS_CHROME_BROWSER_SNAPSHOTS_SNAPSHOT_OVERLAY_H_ - -#import <UIKit/UIKit.h> - -// Simple object containing all the information needed to display an overlay -// view in a snapshot. -@interface SnapshotOverlay : NSObject - -// Initialize SnapshotOverlay with the given |view| and |yOffset|. -- (instancetype)initWithView:(UIView*)view - yOffset:(CGFloat)yOffset NS_DESIGNATED_INITIALIZER; - -- (instancetype)init NS_UNAVAILABLE; - -// The overlay view. -@property(nonatomic, strong, readonly) UIView* view; - -// Y offset for the overlay view. Used to adjust the y position of |_view| -// within the snapshot. -@property(nonatomic, assign, readonly) CGFloat yOffset; - -@end - -#endif // IOS_CHROME_BROWSER_SNAPSHOTS_SNAPSHOT_OVERLAY_H_
diff --git a/ios/chrome/browser/snapshots/snapshot_overlay.mm b/ios/chrome/browser/snapshots/snapshot_overlay.mm deleted file mode 100644 index b936f4e..0000000 --- a/ios/chrome/browser/snapshots/snapshot_overlay.mm +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/snapshots/snapshot_overlay.h" - -#include "base/logging.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@implementation SnapshotOverlay - -@synthesize view = _view; -@synthesize yOffset = _yOffset; - -- (instancetype)initWithView:(UIView*)view yOffset:(CGFloat)yOffset { - self = [super init]; - if (self) { - DCHECK(view); - _view = view; - _yOffset = yOffset; - } - return self; -} - -@end
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index d17989e0..3d3a21f 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -60,7 +60,6 @@ #import "ios/chrome/browser/signin/account_consistency_service_factory.h" #include "ios/chrome/browser/signin/account_reconcilor_factory.h" #import "ios/chrome/browser/snapshots/snapshot_generator_delegate.h" -#import "ios/chrome/browser/snapshots/snapshot_overlay.h" #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" #import "ios/chrome/browser/ssl/captive_portal_detector_tab_helper.h" #import "ios/chrome/browser/ssl/captive_portal_detector_tab_helper_delegate.h" @@ -2920,40 +2919,28 @@ return insets; } -- (NSArray<SnapshotOverlay*>*)snapshotGenerator: - (SnapshotGenerator*)snapshotGenerator - snapshotOverlaysForWebState:(web::WebState*)webState { +- (NSArray<UIView*>*)snapshotGenerator:(SnapshotGenerator*)snapshotGenerator + snapshotOverlaysForWebState:(web::WebState*)webState { DCHECK(webState); Tab* tab = LegacyTabHelper::GetTabForWebState(webState); DCHECK([self.tabModel indexOfTab:tab] != NSNotFound); if (!self.webUsageEnabled) return @[]; - NSMutableArray* overlays = [NSMutableArray array]; + NSMutableArray<UIView*>* overlays = [NSMutableArray array]; UIView* infoBarView = [self infoBarOverlayViewForTab:tab]; if (infoBarView) { - CGFloat infoBarYOffset = [self infoBarOverlayYOffsetForTab:tab]; - SnapshotOverlay* infoBarOverlay = - [[SnapshotOverlay alloc] initWithView:infoBarView - yOffset:infoBarYOffset]; - [overlays addObject:infoBarOverlay]; + [overlays addObject:infoBarView]; } UIView* downloadManagerView = _downloadManagerCoordinator.viewController.view; if (downloadManagerView) { - CGFloat offset = [self downloadManagerOverlayYOffsetForTab:tab]; - SnapshotOverlay* downloadManagerOverlay = - [[SnapshotOverlay alloc] initWithView:downloadManagerView - yOffset:offset]; - [overlays addObject:downloadManagerOverlay]; + [overlays addObject:downloadManagerView]; } UIView* sadTabView = _sadTabCoordinator.viewController.view; if (sadTabView) { - SnapshotOverlay* sadTabOverlay = - [[SnapshotOverlay alloc] initWithView:sadTabView - yOffset:self.headerHeight]; - [overlays addObject:sadTabOverlay]; + [overlays addObject:sadTabView]; } return overlays; @@ -3002,23 +2989,6 @@ return nil; } -// Returns a vertical infobar offset relative to the tab content. It is an error -// to call this method on a tab that does not have an infobar overlay. -- (CGFloat)infoBarOverlayYOffsetForTab:(Tab*)tab { - DCHECK_EQ(tab, self.tabModel.currentTab); - DCHECK([self.infobarContainerCoordinator - isInfobarPresentingForWebState:tab.webState]); - CGRect visibleFrame = [self visibleFrameForTab:self.tabModel.currentTab]; - return CGRectGetMaxY(visibleFrame) - - CGRectGetHeight([self.infobarContainerCoordinator view].frame); -} - -// Returns a vertical download manager offset relative to the tab content. -- (CGFloat)downloadManagerOverlayYOffsetForTab:(Tab*)tab { - return CGRectGetMaxY([self visibleFrameForTab:tab]) - - CGRectGetHeight(_downloadManagerCoordinator.viewController.view.frame); -} - #pragma mark - PasswordControllerDelegate methods - (BOOL)displaySignInNotification:(UIViewController*)viewController
diff --git a/ios/chrome/browser/ui/settings/cells/BUILD.gn b/ios/chrome/browser/ui/settings/cells/BUILD.gn index 0b9fcb0..7020b30 100644 --- a/ios/chrome/browser/ui/settings/cells/BUILD.gn +++ b/ios/chrome/browser/ui/settings/cells/BUILD.gn
@@ -10,16 +10,12 @@ "autofill_data_item.mm", "byo_textfield_item.h", "byo_textfield_item.mm", - "card_multiline_item.h", - "card_multiline_item.mm", "clear_browsing_data_constants.h", "clear_browsing_data_constants.mm", "clear_browsing_data_item.h", "clear_browsing_data_item.mm", "copied_to_chrome_item.h", "copied_to_chrome_item.mm", - "encryption_item.h", - "encryption_item.mm", "passphrase_error_item.h", "passphrase_error_item.mm", "settings_cells_constants.h", @@ -77,10 +73,8 @@ sources = [ "autofill_data_item_unittest.mm", "byo_textfield_item_unittest.mm", - "card_multiline_item_unittest.mm", "clear_browsing_data_item_unittest.mm", "copied_to_chrome_item_unittest.mm", - "encryption_item_unittest.mm", "passphrase_error_item_unittest.mm", "settings_multiline_detail_item_unittest.mm", "text_and_error_item_unittest.mm",
diff --git a/ios/chrome/browser/ui/settings/cells/card_multiline_item.h b/ios/chrome/browser/ui/settings/cells/card_multiline_item.h deleted file mode 100644 index 2dd1d4c..0000000 --- a/ios/chrome/browser/ui/settings/cells/card_multiline_item.h +++ /dev/null
@@ -1,27 +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 IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_CARD_MULTILINE_ITEM_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_CARD_MULTILINE_ITEM_H_ - -#import <UIKit/UIKit.h> - -#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" - -// Item to display a multiline text, presented in the card style. -@interface CardMultilineItem : TableViewItem - -// The text to display. -@property(nonatomic, copy) NSString* text; - -@end - -@interface CardMultilineCell : UITableViewCell - -// UILabel corresponding to |text| from the item. -@property(nonatomic, readonly, strong) UILabel* textLabel; - -@end - -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_CARD_MULTILINE_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/card_multiline_item.mm b/ios/chrome/browser/ui/settings/cells/card_multiline_item.mm deleted file mode 100644 index 31ccb4e..0000000 --- a/ios/chrome/browser/ui/settings/cells/card_multiline_item.mm +++ /dev/null
@@ -1,91 +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. - -#import "ios/chrome/browser/ui/settings/cells/card_multiline_item.h" - -#import "ios/chrome/browser/ui/util/uikit_ui_util.h" -#import "ios/chrome/common/ui_util/constraints_ui_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { -// Padding used on the leading and trailing edges of the cell. -const CGFloat kHorizontalPadding = 16; - -// Padding used on the top and bottom edges of the cell. -const CGFloat kVerticalPadding = 16; -} // namespace - -@implementation CardMultilineItem - -@synthesize text = _text; - -- (instancetype)initWithType:(NSInteger)type { - self = [super initWithType:type]; - if (self) { - self.cellClass = [CardMultilineCell class]; - } - return self; -} - -#pragma mark TableViewItem - -- (void)configureCell:(CardMultilineCell*)cell - withStyler:(ChromeTableViewStyler*)styler { - [super configureCell:cell withStyler:styler]; - cell.selectionStyle = UITableViewCellSelectionStyleNone; - cell.textLabel.text = self.text; -} - -@end - -@implementation CardMultilineCell - -@synthesize textLabel = _textLabel; - -- (instancetype)initWithStyle:(UITableViewCellStyle)style - reuseIdentifier:(NSString*)reuseIdentifier { - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) { - UIView* contentView = self.contentView; - - _textLabel = [[UILabel alloc] init]; - _textLabel.translatesAutoresizingMaskIntoConstraints = NO; - _textLabel.numberOfLines = 0; - _textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; - _textLabel.adjustsFontForContentSizeCategory = YES; - [contentView addSubview:_textLabel]; - - // Set up the constraints. - [NSLayoutConstraint activateConstraints:@[ - [_textLabel.leadingAnchor - constraintEqualToAnchor:contentView.leadingAnchor - constant:kHorizontalPadding], - [_textLabel.trailingAnchor - constraintEqualToAnchor:contentView.trailingAnchor - constant:-kHorizontalPadding], - ]]; - AddOptionalVerticalPadding(contentView, _textLabel, kVerticalPadding); - } - return self; -} - -// Implements -layoutSubviews as per instructions in documentation for -// +[MDCCollectionViewCell cr_preferredHeightForWidth:forItem:]. -- (void)layoutSubviews { - [super layoutSubviews]; - - // Adjust the text label preferredMaxLayoutWidth when the parent's width - // changes, for instance on screen rotation. - CGFloat parentWidth = CGRectGetWidth(self.contentView.bounds); - self.textLabel.preferredMaxLayoutWidth = parentWidth - 2 * kHorizontalPadding; - - // Re-layout with the new preferred width to allow the label to adjust its - // height. - [super layoutSubviews]; -} - -@end
diff --git a/ios/chrome/browser/ui/settings/cells/card_multiline_item_unittest.mm b/ios/chrome/browser/ui/settings/cells/card_multiline_item_unittest.mm deleted file mode 100644 index 2514f83..0000000 --- a/ios/chrome/browser/ui/settings/cells/card_multiline_item_unittest.mm +++ /dev/null
@@ -1,44 +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. - -#import "ios/chrome/browser/ui/settings/cells/card_multiline_item.h" - -#import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" -#include "testing/gtest/include/gtest/gtest.h" -#import "testing/gtest_mac.h" -#include "testing/platform_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -using CardMultilineItemTest = PlatformTest; - -// Tests that the text is honoured after a call to |configureCell:|. -TEST_F(CardMultilineItemTest, ConfigureCell) { - CardMultilineItem* item = [[CardMultilineItem alloc] initWithType:0]; - NSString* text = @"Test Disclaimer"; - - item.text = text; - - id cell = [[[item cellClass] alloc] init]; - ASSERT_TRUE([cell isMemberOfClass:[CardMultilineCell class]]); - - CardMultilineCell* disclaimerCell = static_cast<CardMultilineCell*>(cell); - EXPECT_FALSE(disclaimerCell.textLabel.text); - - [item configureCell:cell withStyler:[[ChromeTableViewStyler alloc] init]]; - EXPECT_NSEQ(text, disclaimerCell.textLabel.text); -} - -// Tests that the text label of an CardMultilineCell spans multiple -// lines. -TEST_F(CardMultilineItemTest, MultipleLines) { - CardMultilineCell* cell = [[CardMultilineCell alloc] init]; - EXPECT_EQ(0, cell.textLabel.numberOfLines); -} - -} // namespace
diff --git a/ios/chrome/browser/ui/settings/cells/encryption_item.h b/ios/chrome/browser/ui/settings/cells/encryption_item.h deleted file mode 100644 index 9029d49..0000000 --- a/ios/chrome/browser/ui/settings/cells/encryption_item.h +++ /dev/null
@@ -1,32 +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 IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_ENCRYPTION_ITEM_H_ -#define IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_ENCRYPTION_ITEM_H_ - -#import <UIKit/UIKit.h> - -#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" - -// Item displaying possible options in the Sync Encryption screen. -@interface EncryptionItem : TableViewItem - -// The text to display. -@property(nonatomic, copy) NSString* text; - -// Whether or not the cell is enabled. Disabled cells are drawn with dimmed -// text. -@property(nonatomic, assign, getter=isEnabled) BOOL enabled; - -@end - -// The cell associated to |EncryptionCell|. -@interface EncryptionCell : UITableViewCell - -// UILabel corresponding to |text| from the item. -@property(nonatomic, readonly, strong) UILabel* textLabel; - -@end - -#endif // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_ENCRYPTION_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/encryption_item.mm b/ios/chrome/browser/ui/settings/cells/encryption_item.mm deleted file mode 100644 index ce476d6..0000000 --- a/ios/chrome/browser/ui/settings/cells/encryption_item.mm +++ /dev/null
@@ -1,84 +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. - -#import "ios/chrome/browser/ui/settings/cells/encryption_item.h" - -#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" -#import "ios/chrome/browser/ui/util/uikit_ui_util.h" -#import "ios/chrome/common/ui_util/constraints_ui_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@implementation EncryptionItem - -@synthesize text = _text; -@synthesize enabled = _enabled; - -- (instancetype)initWithType:(NSInteger)type { - self = [super initWithType:type]; - if (self) { - self.cellClass = [EncryptionCell class]; - self.enabled = YES; - self.accessibilityTraits |= UIAccessibilityTraitButton; - } - return self; -} - -- (void)configureCell:(EncryptionCell*)cell - withStyler:(ChromeTableViewStyler*)styler { - [super configureCell:cell withStyler:styler]; - cell.textLabel.text = self.text; - cell.textLabel.textColor = - self.enabled ? [UIColor blackColor] - : UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor); -} - -@end - -@implementation EncryptionCell - -@synthesize textLabel = _textLabel; - -- (instancetype)initWithStyle:(UITableViewCellStyle)style - reuseIdentifier:(NSString*)reuseIdentifier { - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) { - self.isAccessibilityElement = YES; - - _textLabel = [[UILabel alloc] init]; - _textLabel.translatesAutoresizingMaskIntoConstraints = NO; - _textLabel.numberOfLines = 0; - _textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; - _textLabel.adjustsFontForContentSizeCategory = YES; - [self.contentView addSubview:_textLabel]; - - // Set up the constraints. - [NSLayoutConstraint activateConstraints:@[ - [_textLabel.leadingAnchor - constraintEqualToAnchor:self.contentView.leadingAnchor - constant:kTableViewHorizontalSpacing], - [_textLabel.trailingAnchor - constraintEqualToAnchor:self.contentView.trailingAnchor - constant:-kTableViewHorizontalSpacing], - ]]; - AddOptionalVerticalPadding(self.contentView, _textLabel, - kTableViewLargeVerticalSpacing); - } - return self; -} - -- (void)prepareForReuse { - [super prepareForReuse]; - self.textLabel.text = nil; -} - -#pragma mark - UIAccessibility - -- (NSString*)accessibilityLabel { - return self.textLabel.text; -} - -@end
diff --git a/ios/chrome/browser/ui/settings/cells/encryption_item_unittest.mm b/ios/chrome/browser/ui/settings/cells/encryption_item_unittest.mm deleted file mode 100644 index 1e0dc9c..0000000 --- a/ios/chrome/browser/ui/settings/cells/encryption_item_unittest.mm +++ /dev/null
@@ -1,40 +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. - -#import "ios/chrome/browser/ui/settings/cells/encryption_item.h" - -#import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" -#include "testing/gtest/include/gtest/gtest.h" -#import "testing/gtest_mac.h" -#include "testing/platform_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -using EncryptionItemTest = PlatformTest; - -// Tests that the text label, enabled status and accessory type are set properly -// after a call to |configureCell:|. -TEST_F(EncryptionItemTest, ConfigureCell) { - EncryptionItem* item = [[EncryptionItem alloc] initWithType:0]; - EncryptionCell* cell = [[[item cellClass] alloc] init]; - EXPECT_TRUE([cell isMemberOfClass:[EncryptionCell class]]); - EXPECT_NSEQ(nil, cell.textLabel.text); - NSString* text = @"Test text"; - UIColor* enabledColor = cell.textLabel.textColor; - - item.text = text; - item.enabled = NO; - item.accessoryType = UITableViewCellAccessoryCheckmark; - [item configureCell:cell withStyler:[[ChromeTableViewStyler alloc] init]]; - - EXPECT_NSEQ(text, cell.textLabel.text); - EXPECT_NE(enabledColor, cell.textLabel.textColor); - EXPECT_EQ(UITableViewCellAccessoryCheckmark, cell.accessoryType); -} - -} // namespace
diff --git a/ios/chrome/browser/ui/settings/import_data_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/import_data_table_view_controller_unittest.mm index 3fb7a8c..88b7a91 100644 --- a/ios/chrome/browser/ui/settings/import_data_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/import_data_table_view_controller_unittest.mm
@@ -6,7 +6,6 @@ #include "base/mac/foundation_util.h" #include "base/strings/sys_string_conversions.h" -#import "ios/chrome/browser/ui/settings/cells/card_multiline_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_multiline_detail_item.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h" #import "ios/chrome/browser/ui/table_view/table_view_model.h" @@ -71,7 +70,7 @@ CheckController(); ASSERT_EQ(2, NumberOfSections()); EXPECT_EQ(1, NumberOfItemsInSection(0)); - CardMultilineItem* item = GetTableViewItem(0, 0); + SettingsMultilineDetailItem* item = GetTableViewItem(0, 0); EXPECT_NSEQ( l10n_util::GetNSStringF(IDS_IOS_OPTIONS_IMPORT_DATA_HEADER, base::SysNSStringToUTF16(@"fromEmail@gmail.com")), @@ -97,7 +96,7 @@ CheckController(); ASSERT_EQ(2, NumberOfSections()); EXPECT_EQ(1, NumberOfItemsInSection(0)); - CardMultilineItem* item = GetTableViewItem(0, 0); + SettingsMultilineDetailItem* item = GetTableViewItem(0, 0); EXPECT_NSEQ( l10n_util::GetNSStringF(IDS_IOS_OPTIONS_IMPORT_DATA_HEADER, base::SysNSStringToUTF16(@"fromEmail@gmail.com")),
diff --git a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm index 742753dc..a7e067e 100644 --- a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm +++ b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
@@ -30,7 +30,6 @@ #import "ios/chrome/browser/ui/payments/cells/autofill_profile_item.h" #import "ios/chrome/browser/ui/payments/cells/payments_text_item.h" #import "ios/chrome/browser/ui/payments/cells/price_item.h" -#import "ios/chrome/browser/ui/settings/cells/card_multiline_item.h" #import "ios/chrome/browser/ui/settings/cells/copied_to_chrome_item.h" #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_account_signin_item.h" #import "ios/chrome/browser/ui/settings/cells/legacy/legacy_settings_detail_item.h"
diff --git a/ios/chrome/browser/ui/settings/sync/BUILD.gn b/ios/chrome/browser/ui/settings/sync/BUILD.gn index 7400f1d..31980a4 100644 --- a/ios/chrome/browser/ui/settings/sync/BUILD.gn +++ b/ios/chrome/browser/ui/settings/sync/BUILD.gn
@@ -86,6 +86,7 @@ "//ios/chrome/browser/ui/settings/cells/legacy", "//ios/chrome/browser/ui/settings/sync/utils", "//ios/chrome/browser/ui/table_view:test_support", + "//ios/chrome/browser/ui/table_view/cells", "//ios/web/public/test", "//testing/gtest", "//ui/base",
diff --git a/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm b/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm index cfd1bb4..feab597 100644 --- a/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.mm
@@ -23,12 +23,12 @@ #include "ios/chrome/browser/sync/sync_setup_service.h" #include "ios/chrome/browser/sync/sync_setup_service_factory.h" #import "ios/chrome/browser/ui/settings/cells/byo_textfield_item.h" -#import "ios/chrome/browser/ui/settings/cells/card_multiline_item.h" #import "ios/chrome/browser/ui/settings/cells/passphrase_error_item.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h" #import "ios/chrome/browser/ui/settings/utils/settings_utils.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_link_header_footer_item.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" @@ -189,9 +189,10 @@ // Returns a passphrase message item. - (TableViewItem*)passphraseMessageItem { - CardMultilineItem* item = - [[CardMultilineItem alloc] initWithType:ItemTypeMessage]; + TableViewTextItem* item = + [[TableViewTextItem alloc] initWithType:ItemTypeMessage]; item.text = self.headerMessage; + item.enabled = NO; return item; }
diff --git a/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller_unittest.mm index 9f8e3bf..e84e5543 100644 --- a/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller_unittest.mm
@@ -20,9 +20,9 @@ #include "ios/chrome/browser/sync/sync_setup_service_factory.h" #include "ios/chrome/browser/sync/sync_setup_service_mock.h" #import "ios/chrome/browser/ui/settings/cells/byo_textfield_item.h" -#import "ios/chrome/browser/ui/settings/cells/card_multiline_item.h" #import "ios/chrome/browser/ui/settings/passphrase_table_view_controller_test.h" #import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h" #import "testing/gtest_mac.h" #include "testing/platform_test.h" #include "ui/base/l10n/l10n_util.h" @@ -105,7 +105,7 @@ EXPECT_EQ(1, NumberOfSections()); EXPECT_EQ(2, NumberOfItemsInSection(0)); // Passphrase message item. - CardMultilineItem* item = GetTableViewItem(0, 0); + TableViewTextItem* item = GetTableViewItem(0, 0); EXPECT_NSEQ(l10n_util::GetNSString(IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY), item.text); // Passphrase items.
diff --git a/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.mm b/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.mm index 02c605a..57a844f7 100644 --- a/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller.mm
@@ -19,15 +19,16 @@ #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/sync/profile_sync_service_factory.h" #import "ios/chrome/browser/sync/sync_observer_bridge.h" -#import "ios/chrome/browser/ui/settings/cells/encryption_item.h" #import "ios/chrome/browser/ui/settings/sync/sync_create_passphrase_table_view_controller.h" #import "ios/chrome/browser/ui/settings/sync/sync_encryption_passphrase_table_view_controller.h" #import "ios/chrome/browser/ui/settings/utils/settings_utils.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" #import "ios/chrome/browser/ui/table_view/cells/table_view_link_header_footer_item.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h" #import "ios/chrome/browser/ui/table_view/table_view_model.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" +#import "ios/chrome/browser/ui/util/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util_mac.h" #include "url/gurl.h" @@ -154,18 +155,6 @@ return footerView; } -- (BOOL)tableView:(UITableView*)tableView - shouldHighlightRowAtIndexPath:(NSIndexPath*)indexPath { - TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; - if (item.type == ItemTypePassphrase || item.type == ItemTypeAccount) { - EncryptionItem* encryptionItem = - base::mac::ObjCCastStrict<EncryptionItem>(item); - // Don't perform any action if the cell isn't enabled. - return encryptionItem.isEnabled; - } - return YES; -} - - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { DCHECK_EQ(indexPath.section, @@ -173,12 +162,6 @@ sectionForSectionIdentifier:SectionIdentifierEncryption]); TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; - if ([item respondsToSelector:@selector(isEnabled)] && - ![item performSelector:@selector(isEnabled)]) { - // Don't perform any action if the cell isn't enabled. - return; - } - switch (item.type) { case ItemTypePassphrase: { DCHECK(browser_sync::ProfileSyncService::IsSyncAllowedByFlag()); @@ -226,10 +209,14 @@ text:(NSString*)text checked:(BOOL)checked enabled:(BOOL)enabled { - EncryptionItem* item = [[EncryptionItem alloc] initWithType:type]; + TableViewTextItem* item = [[TableViewTextItem alloc] initWithType:type]; + item.accessibilityTraits |= UIAccessibilityTraitButton; item.text = text; item.accessoryType = checked ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; + item.textColor = + enabled ? [UIColor blackColor] + : UIColorFromRGB(kTableViewSecondaryLabelLightGrayTextColor); item.enabled = enabled; return item; }
diff --git a/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller_unittest.mm index 2b0336d..e8bcd9e 100644 --- a/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/sync/sync_encryption_table_view_controller_unittest.mm
@@ -13,7 +13,7 @@ #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #include "ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.h" #include "ios/chrome/browser/sync/profile_sync_service_factory.h" -#import "ios/chrome/browser/ui/settings/cells/encryption_item.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_text_item.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_controller_test.h" #include "ios/chrome/grit/ios_strings.h" #include "ios/web/public/test/test_web_thread_bundle.h" @@ -84,11 +84,11 @@ NSInteger const kSection = 0; EXPECT_EQ(2, NumberOfItemsInSection(kSection)); - EncryptionItem* accountItem = GetTableViewItem(kSection, 0); + TableViewTextItem* accountItem = GetTableViewItem(kSection, 0); EXPECT_NSEQ(l10n_util::GetNSString(IDS_SYNC_BASIC_ENCRYPTION_DATA), accountItem.text); - EncryptionItem* passphraseItem = GetTableViewItem(kSection, 1); + TableViewTextItem* passphraseItem = GetTableViewItem(kSection, 1); EXPECT_NSEQ(l10n_util::GetNSString(IDS_SYNC_FULL_ENCRYPTION_DATA), passphraseItem.text); }
diff --git a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm index d0570e0..42b36f5fa 100644 --- a/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm +++ b/ios/chrome/browser/ui/settings/table_cell_catalog_view_controller.mm
@@ -13,7 +13,6 @@ #import "ios/chrome/browser/ui/settings/cells/account_sign_in_item.h" #import "ios/chrome/browser/ui/settings/cells/autofill_data_item.h" #import "ios/chrome/browser/ui/settings/cells/copied_to_chrome_item.h" -#import "ios/chrome/browser/ui/settings/cells/encryption_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_detail_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_image_detail_text_item.h" #import "ios/chrome/browser/ui/settings/cells/settings_switch_item.h" @@ -60,7 +59,6 @@ ItemTypeURLWithSupplementalText, ItemTypeURLWithBadgeImage, ItemTypeTextSettingsDetail, - ItemTypeEncryption, ItemTypeLinkFooter, ItemTypeDetailText, ItemTypeAccountSignInItem, @@ -227,25 +225,6 @@ [model addItem:imageDetailTextItem toSectionWithIdentifier:SectionIdentifierSettings]; - EncryptionItem* encryptionChecked = - [[EncryptionItem alloc] initWithType:ItemTypeEncryption]; - encryptionChecked.text = - @"These two cells have exactly the same text, but one has a checkmark " - @"and the other does not. They should lay out identically, and the " - @"presence of the checkmark should not cause the text to reflow."; - encryptionChecked.accessoryType = UITableViewCellAccessoryCheckmark; - [model addItem:encryptionChecked - toSectionWithIdentifier:SectionIdentifierSettings]; - - EncryptionItem* encryptionUnchecked = - [[EncryptionItem alloc] initWithType:ItemTypeEncryption]; - encryptionUnchecked.text = - @"These two cells have exactly the same text, but one has a checkmark " - @"and the other does not. They should lay out identically, and the " - @"presence of the checkmark should not cause the text to reflow."; - [model addItem:encryptionUnchecked - toSectionWithIdentifier:SectionIdentifierSettings]; - TableViewLinkHeaderFooterItem* linkFooter = [[TableViewLinkHeaderFooterItem alloc] initWithType:ItemTypeLinkFooter]; linkFooter.text =
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.h b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.h index a9606d5..a26c511 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.h +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.h
@@ -25,6 +25,10 @@ // If set to YES, |text| will be shown as "••••••" with fixed length. @property(nonatomic, assign) BOOL masked; +// Whether this item is enabled. If it is not enabled, the corresponding cell +// has its user interaction disabled. Enabled by default. +@property(nonatomic, assign, getter=isEnabled) BOOL enabled; + @end // UITableViewCell that displays a text label.
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm index d0e7537..caec2cb 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm
@@ -28,6 +28,7 @@ self = [super initWithType:type]; if (self) { self.cellClass = [TableViewTextCell class]; + _enabled = YES; } return self; } @@ -71,6 +72,8 @@ } cell.textLabel.textAlignment = self.textAlignment ? self.textAlignment : NSTextAlignmentLeft; + + cell.userInteractionEnabled = self.enabled; } @end @@ -128,6 +131,7 @@ - (void)prepareForReuse { [super prepareForReuse]; self.checked = NO; + self.userInteractionEnabled = YES; } @end
diff --git a/media/cdm/cdm_proxy.h b/media/cdm/cdm_proxy.h index 91d4085..6d908e0 100644 --- a/media/cdm/cdm_proxy.h +++ b/media/cdm/cdm_proxy.h
@@ -34,8 +34,11 @@ public: Client(); virtual ~Client(); - // Called when there is a hardware reset and all the hardware context is - // lost. + + // Called when there is a hardware reset. When hardware reset happens, all + // the hardware context is lost and all crypto sessions are destroyed. The + // CdmProxy returns to an uninitialized state and the caller must call + // Initialize() on the CdmProxy again to be able to continue using it. virtual void NotifyHardwareReset() = 0; }; @@ -82,7 +85,10 @@ void(Status status, Protocol protocol, uint32_t crypto_session_id)>; // Initializes the proxy. The status and the return values of the call is - // reported to |init_cb|. + // reported to |init_cb|. All other methods should only be called after the + // proxy is fully initialized. Otherwise they may fail. + // Note: The proxy also needs to be reinitialized after hardware reset. See + // Client::NotifyHardwareReset() for details. virtual void Initialize(Client* client, InitializeCB init_cb) = 0; // Callback for Process(). |output_data| is the output of processing.
diff --git a/net/BUILD.gn b/net/BUILD.gn index e4866fc..311e601 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1811,6 +1811,8 @@ "reporting/reporting_browsing_data_remover.h", "reporting/reporting_cache.cc", "reporting/reporting_cache.h", + "reporting/reporting_cache_impl.cc", + "reporting/reporting_cache_impl.h", "reporting/reporting_cache_observer.cc", "reporting/reporting_cache_observer.h", "reporting/reporting_client.cc",
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc index e9b0c4c..81705d66 100644 --- a/net/cookies/cookie_monster.cc +++ b/net/cookies/cookie_monster.cc
@@ -675,18 +675,18 @@ if (HasCookieableScheme(url)) { std::vector<CanonicalCookie*> cookie_ptrs; FindCookiesForRegistryControlledHost(url, &cookie_ptrs); + std::sort(cookie_ptrs.begin(), cookie_ptrs.end(), CookieSorter); cookies.reserve(cookie_ptrs.size()); - std::vector<CanonicalCookie*> filtered_cookie_ptrs; - FilterCookiesWithOptions(url, options, &cookie_ptrs, &filtered_cookie_ptrs); + std::vector<CanonicalCookie*> included_cookie_ptrs; + FilterCookiesWithOptions(url, options, &cookie_ptrs, &included_cookie_ptrs, + &excluded_cookies); - std::sort(filtered_cookie_ptrs.begin(), filtered_cookie_ptrs.end(), - CookieSorter); - - for (auto* cookie : filtered_cookie_ptrs) { + for (auto* cookie : included_cookie_ptrs) { cookies.push_back(*cookie); } } + MaybeRunCookieCallback(std::move(callback), cookies, excluded_cookies); } @@ -781,12 +781,13 @@ CookieOptions::SameSiteCookieMode::INCLUDE_STRICT_AND_LAX); // Get the cookies for this host and its domain(s). std::vector<CanonicalCookie*> cookie_ptrs; - std::vector<CanonicalCookie*> filtered_cookie_ptrs; + std::vector<CanonicalCookie*> included_cookie_ptrs; FindCookiesForRegistryControlledHost(url, &cookie_ptrs); - FilterCookiesWithOptions(url, options, &cookie_ptrs, &filtered_cookie_ptrs); + FilterCookiesWithOptions(url, options, &cookie_ptrs, &included_cookie_ptrs, + nullptr); std::set<CanonicalCookie*> matching_cookies; - for (auto* cookie : filtered_cookie_ptrs) { + for (auto* cookie : included_cookie_ptrs) { DCHECK(cookie->IsOnPath(url.path())); DCHECK(cookie->IsDomainMatch(url.host())); if (cookie->Name() != cookie_name) @@ -1113,7 +1114,8 @@ const GURL url, const CookieOptions options, std::vector<CanonicalCookie*>* cookie_ptrs, - std::vector<CanonicalCookie*>* cookies) { + std::vector<CanonicalCookie*>* included_cookie_ptrs, + CookieStatusList* excluded_cookies) { DCHECK(thread_checker_.CalledOnValidThread()); // Probe to save statistics relatively frequently. We do it here rather @@ -1127,15 +1129,19 @@ // Filter out cookies that should not be included for a request to the // given |url|. HTTP only cookies are filtered depending on the passed // cookie |options|. - if ((*it)->IncludeForRequestURL(url, options) != - CanonicalCookie::CookieInclusionStatus::INCLUDE) { + CanonicalCookie::CookieInclusionStatus status = + (*it)->IncludeForRequestURL(url, options); + + if (status != CanonicalCookie::CookieInclusionStatus::INCLUDE) { + if (options.return_excluded_cookies()) + excluded_cookies->push_back({**it, status}); continue; } if (options.update_access_time()) InternalUpdateCookieAccessTime(*it, current_time); - cookies->push_back(*it); + included_cookie_ptrs->push_back(*it); } }
diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h index a4bb4e81..1138ffd 100644 --- a/net/cookies/cookie_monster.h +++ b/net/cookies/cookie_monster.h
@@ -450,10 +450,12 @@ const GURL& url, std::vector<CanonicalCookie*>* cookies); - void FilterCookiesWithOptions(const GURL url, - const CookieOptions options, - std::vector<CanonicalCookie*>* cookie_ptrs, - std::vector<CanonicalCookie*>* cookies); + void FilterCookiesWithOptions( + const GURL url, + const CookieOptions options, + std::vector<CanonicalCookie*>* cookie_ptrs, + std::vector<CanonicalCookie*>* included_cookie_ptrs, + CookieStatusList* excluded_cookie_ptrs); // Delete any cookies that are equivalent to |ecc| (same path, domain, etc). // |source_secure| indicates if the source may override existing secure // cookies.
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc index 33d2459..c7f47ec 100644 --- a/net/cookies/cookie_monster_unittest.cc +++ b/net/cookies/cookie_monster_unittest.cc
@@ -152,6 +152,20 @@ return callback.cookies(); } + CookieStatusList GetExcludedCookiesForURLWithOptions( + CookieMonster* cm, + const GURL& url, + const CookieOptions& options) { + DCHECK(cm); + GetCookieListCallback callback; + cm->GetCookieListWithOptionsAsync( + url, options, + base::BindOnce(&GetCookieListCallback::Run, + base::Unretained(&callback))); + callback.WaitUntilDone(); + return callback.excluded_cookies(); + } + bool SetAllCookies(CookieMonster* cm, const CookieList& list) { DCHECK(cm); ResultSavingCookieCallback<bool> callback; @@ -1633,6 +1647,78 @@ EXPECT_EQ(last_access_date, GetFirstCookieAccessDate(cm.get())); } +TEST_F(CookieMonsterTest, GetExcludedCookiesForURL) { + std::unique_ptr<CookieMonster> cm( + new CookieMonster(nullptr, kLastAccessThreshold, &net_log_)); + + // Create an httponly cookie. + CookieOptions options; + options.set_include_httponly(); + + EXPECT_TRUE(SetCookieWithOptions(cm.get(), http_www_foo_.url(), + "A=B; httponly", options)); + EXPECT_TRUE(SetCookieWithOptions(cm.get(), http_www_foo_.url(), + http_www_foo_.Format("C=D; domain=.%D"), + options)); + EXPECT_TRUE(SetCookieWithOptions( + cm.get(), https_www_foo_.url(), + http_www_foo_.Format("E=F; domain=.%D; secure"), options)); + + base::PlatformThread::Sleep(kAccessDelay); + + // Check that no cookies are sent when option is turned off + CookieOptions do_not_return_excluded; + do_not_return_excluded.unset_return_excluded_cookies(); + + CookieStatusList excluded_cookies = GetExcludedCookiesForURLWithOptions( + cm.get(), http_www_foo_.url(), do_not_return_excluded); + auto iter = excluded_cookies.begin(); + + EXPECT_TRUE(excluded_cookies.empty()); + + // Checking that excluded cookies get sent with their statuses with http + // request. + excluded_cookies = GetExcludedCookiesForURL(cm.get(), http_www_foo_.url()); + iter = excluded_cookies.begin(); + + ASSERT_TRUE(iter != excluded_cookies.end()); + EXPECT_EQ(http_www_foo_.Format(".%D"), iter->cookie.Domain()); + EXPECT_EQ("E", iter->cookie.Name()); + EXPECT_EQ(CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY, + iter->status); + + ASSERT_TRUE(++iter == excluded_cookies.end()); + + // Checking that excluded cookies get sent with their statuses with http-only. + CookieOptions return_excluded = CookieOptions(); + return_excluded.set_return_excluded_cookies(); + return_excluded.set_exclude_httponly(); + + excluded_cookies = GetExcludedCookiesForURLWithOptions( + cm.get(), http_www_foo_.url(), return_excluded); + iter = excluded_cookies.begin(); + + ASSERT_TRUE(iter != excluded_cookies.end()); + EXPECT_EQ(http_www_foo_.host(), iter->cookie.Domain()); + EXPECT_EQ("A", iter->cookie.Name()); + EXPECT_EQ(CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY, + iter->status); + + ASSERT_TRUE(++iter != excluded_cookies.end()); + EXPECT_EQ(http_www_foo_.Format(".%D"), iter->cookie.Domain()); + EXPECT_EQ("E", iter->cookie.Name()); + EXPECT_EQ(CanonicalCookie::CookieInclusionStatus::EXCLUDE_SECURE_ONLY, + iter->status); + + ASSERT_TRUE(++iter == excluded_cookies.end()); + + // Check that no excluded cookies are sent with secure request + excluded_cookies = GetExcludedCookiesForURL(cm.get(), https_www_foo_.url()); + iter = excluded_cookies.begin(); + + EXPECT_TRUE(excluded_cookies.empty()); +} + TEST_F(CookieMonsterTest, GetAllCookiesForURLPathMatching) { std::unique_ptr<CookieMonster> cm( new CookieMonster(nullptr, nullptr, &net_log_)); @@ -1672,6 +1758,42 @@ ASSERT_TRUE(++it == cookies.end()); } +TEST_F(CookieMonsterTest, GetExcludedCookiesForURLPathMatching) { + std::unique_ptr<CookieMonster> cm( + new CookieMonster(nullptr, nullptr, &net_log_)); + CookieOptions options; + + EXPECT_TRUE(SetCookieWithOptions(cm.get(), www_foo_foo_.url(), + "A=B; path=/foo;", options)); + EXPECT_TRUE(SetCookieWithOptions(cm.get(), www_foo_bar_.url(), + "C=D; path=/bar;", options)); + EXPECT_TRUE( + SetCookieWithOptions(cm.get(), http_www_foo_.url(), "E=F;", options)); + + CookieStatusList excluded_cookies = + GetExcludedCookiesForURL(cm.get(), www_foo_foo_.url()); + auto it = excluded_cookies.begin(); + + ASSERT_TRUE(it != excluded_cookies.end()); + EXPECT_EQ("C", it->cookie.Name()); + EXPECT_EQ("/bar", it->cookie.Path()); + EXPECT_EQ(CanonicalCookie::CookieInclusionStatus::EXCLUDE_NOT_ON_PATH, + it->status); + + ASSERT_TRUE(++it == excluded_cookies.end()); + + excluded_cookies = GetExcludedCookiesForURL(cm.get(), www_foo_bar_.url()); + it = excluded_cookies.begin(); + + ASSERT_TRUE(it != excluded_cookies.end()); + EXPECT_EQ("A", it->cookie.Name()); + EXPECT_EQ("/foo", it->cookie.Path()); + EXPECT_EQ(CanonicalCookie::CookieInclusionStatus::EXCLUDE_NOT_ON_PATH, + it->status); + + ASSERT_TRUE(++it == excluded_cookies.end()); +} + TEST_F(CookieMonsterTest, CookieSorting) { std::unique_ptr<CookieMonster> cm( new CookieMonster(nullptr, nullptr, &net_log_));
diff --git a/net/cookies/cookie_options.cc b/net/cookies/cookie_options.cc index 1b97f85..f7b0426 100644 --- a/net/cookies/cookie_options.cc +++ b/net/cookies/cookie_options.cc
@@ -13,6 +13,7 @@ : exclude_httponly_(true), same_site_cookie_mode_(SameSiteCookieMode::DO_NOT_INCLUDE), update_access_time_(true), - server_time_() {} + server_time_(), + return_excluded_cookies_(false) {} } // namespace net
diff --git a/net/cookies/cookie_options.h b/net/cookies/cookie_options.h index 0e312b0..6d8f3e4 100644 --- a/net/cookies/cookie_options.h +++ b/net/cookies/cookie_options.h
@@ -63,11 +63,16 @@ void set_do_not_update_access_time() { update_access_time_ = false; } bool update_access_time() const { return update_access_time_; } + void set_return_excluded_cookies() { return_excluded_cookies_ = true; } + void unset_return_excluded_cookies() { return_excluded_cookies_ = false; } + bool return_excluded_cookies() const { return return_excluded_cookies_; } + private: bool exclude_httponly_; SameSiteCookieMode same_site_cookie_mode_; bool update_access_time_; base::Time server_time_; + bool return_excluded_cookies_; }; } // namespace net
diff --git a/net/cookies/cookie_store_test_callbacks.cc b/net/cookies/cookie_store_test_callbacks.cc index f50f3685..58a9c25 100644 --- a/net/cookies/cookie_store_test_callbacks.cc +++ b/net/cookies/cookie_store_test_callbacks.cc
@@ -53,6 +53,7 @@ void GetCookieListCallback::Run(const CookieList& cookies, const CookieStatusList& excluded_cookies) { cookies_ = cookies; + excluded_cookies_ = excluded_cookies; CallbackEpilogue(); }
diff --git a/net/cookies/cookie_store_test_callbacks.h b/net/cookies/cookie_store_test_callbacks.h index fa9ddb6..4a5ea9e 100644 --- a/net/cookies/cookie_store_test_callbacks.h +++ b/net/cookies/cookie_store_test_callbacks.h
@@ -90,9 +90,11 @@ void Run(const CookieList& cookies, const CookieStatusList& excluded_cookies); const CookieList& cookies() { return cookies_; } + const CookieStatusList& excluded_cookies() { return excluded_cookies_; } private: CookieList cookies_; + CookieStatusList excluded_cookies_; }; } // namespace net
diff --git a/net/cookies/cookie_store_unittest.h b/net/cookies/cookie_store_unittest.h index c15f43c..5c5fb91 100644 --- a/net/cookies/cookie_store_unittest.h +++ b/net/cookies/cookie_store_unittest.h
@@ -169,6 +169,22 @@ return callback.cookies(); } + CookieStatusList GetExcludedCookiesForURL(CookieStore* cs, const GURL& url) { + DCHECK(cs); + GetCookieListCallback callback; + CookieOptions options; + options.set_include_httponly(); + options.set_same_site_cookie_mode( + CookieOptions::SameSiteCookieMode::INCLUDE_STRICT_AND_LAX); + options.set_return_excluded_cookies(); + cs->GetCookieListWithOptionsAsync( + url, options, + base::BindOnce(&GetCookieListCallback::Run, + base::Unretained(&callback))); + callback.WaitUntilDone(); + return callback.excluded_cookies(); + } + CookieList GetAllCookies(CookieStore* cs) { DCHECK(cs); GetCookieListCallback callback;
diff --git a/net/reporting/reporting_cache.cc b/net/reporting/reporting_cache.cc index 01a7e06..8773122 100644 --- a/net/reporting/reporting_cache.cc +++ b/net/reporting/reporting_cache.cc
@@ -4,634 +4,11 @@ #include "net/reporting/reporting_cache.h" -#include <algorithm> -#include <map> -#include <set> -#include <string> -#include <unordered_map> -#include <unordered_set> -#include <utility> -#include <vector> - -#include "base/stl_util.h" -#include "base/time/tick_clock.h" -#include "base/time/time.h" -#include "net/log/net_log.h" -#include "net/reporting/reporting_client.h" +#include "net/reporting/reporting_cache_impl.h" #include "net/reporting/reporting_context.h" -#include "net/reporting/reporting_report.h" -#include "url/gurl.h" namespace net { -namespace { - -// Returns the superdomain of a given domain, or the empty string if the given -// domain is just a single label. Note that this does not take into account -// anything like the Public Suffix List, so the superdomain may end up being a -// bare TLD. -// -// Examples: -// -// GetSuperdomain("assets.example.com") -> "example.com" -// GetSuperdomain("example.net") -> "net" -// GetSuperdomain("littlebox") -> "" -std::string GetSuperdomain(const std::string& domain) { - size_t dot_pos = domain.find('.'); - if (dot_pos == std::string::npos) - return ""; - - return domain.substr(dot_pos + 1); -} - -struct ClientMetadata { - base::TimeTicks last_used; - ReportingCache::ClientStatistics stats; -}; - -class ReportingCacheImpl : public ReportingCache { - public: - ReportingCacheImpl(ReportingContext* context) : context_(context) { - DCHECK(context_); - } - - ~ReportingCacheImpl() override { - base::TimeTicks now = tick_clock()->NowTicks(); - - // Mark all undoomed reports as erased at shutdown, and record outcomes of - // all remaining reports (doomed or not). - for (auto it = reports_.begin(); it != reports_.end(); ++it) { - ReportingReport* report = it->second.get(); - if (!base::ContainsKey(doomed_reports_, report)) - report->outcome = ReportingReport::Outcome::ERASED_REPORTING_SHUT_DOWN; - report->RecordOutcome(now); - } - - reports_.clear(); - } - - void AddReport(const GURL& url, - const std::string& user_agent, - const std::string& group, - const std::string& type, - std::unique_ptr<const base::Value> body, - int depth, - base::TimeTicks queued, - int attempts) override { - auto report = std::make_unique<ReportingReport>( - url, user_agent, group, type, std::move(body), depth, queued, attempts); - - auto inserted = - reports_.insert(std::make_pair(report.get(), std::move(report))); - DCHECK(inserted.second); - - if (reports_.size() > context_->policy().max_report_count) { - // There should be at most one extra report (the one added above). - DCHECK_EQ(context_->policy().max_report_count + 1, reports_.size()); - const ReportingReport* to_evict = FindReportToEvict(); - DCHECK_NE(nullptr, to_evict); - // The newly-added report isn't pending, so even if all other reports are - // pending, the cache should have a report to evict. - DCHECK(!base::ContainsKey(pending_reports_, to_evict)); - reports_[to_evict]->outcome = ReportingReport::Outcome::ERASED_EVICTED; - RemoveReportInternal(to_evict); - } - - context_->NotifyCachedReportsUpdated(); - } - - void GetReports( - std::vector<const ReportingReport*>* reports_out) const override { - reports_out->clear(); - for (const auto& it : reports_) { - if (!base::ContainsKey(doomed_reports_, it.first)) - reports_out->push_back(it.second.get()); - } - } - - base::Value GetReportsAsValue() const override { - // Sort the queued reports by origin and timestamp. - std::vector<const ReportingReport*> sorted_reports; - sorted_reports.reserve(reports_.size()); - for (const auto& it : reports_) { - sorted_reports.push_back(it.second.get()); - } - std::sort( - sorted_reports.begin(), sorted_reports.end(), - [](const ReportingReport* report1, const ReportingReport* report2) { - if (report1->queued < report2->queued) - return true; - else if (report1->queued > report2->queued) - return false; - else - return report1->url < report2->url; - }); - - std::vector<base::Value> report_list; - for (const ReportingReport* report : sorted_reports) { - base::Value report_dict(base::Value::Type::DICTIONARY); - report_dict.SetKey("url", base::Value(report->url.spec())); - report_dict.SetKey("group", base::Value(report->group)); - report_dict.SetKey("type", base::Value(report->type)); - report_dict.SetKey("depth", base::Value(report->depth)); - report_dict.SetKey( - "queued", base::Value(NetLog::TickCountToString(report->queued))); - report_dict.SetKey("attempts", base::Value(report->attempts)); - if (report->body) { - report_dict.SetKey("body", report->body->Clone()); - } - if (base::ContainsKey(doomed_reports_, report)) { - report_dict.SetKey("status", base::Value("doomed")); - } else if (base::ContainsKey(pending_reports_, report)) { - report_dict.SetKey("status", base::Value("pending")); - } else { - report_dict.SetKey("status", base::Value("queued")); - } - report_list.push_back(std::move(report_dict)); - } - return base::Value(std::move(report_list)); - } - - void GetNonpendingReports( - std::vector<const ReportingReport*>* reports_out) const override { - reports_out->clear(); - for (const auto& it : reports_) { - if (!base::ContainsKey(pending_reports_, it.first) && - !base::ContainsKey(doomed_reports_, it.first)) { - reports_out->push_back(it.second.get()); - } - } - } - - void SetReportsPending( - const std::vector<const ReportingReport*>& reports) override { - for (const ReportingReport* report : reports) { - auto inserted = pending_reports_.insert(report); - DCHECK(inserted.second); - } - } - - void ClearReportsPending( - const std::vector<const ReportingReport*>& reports) override { - std::vector<const ReportingReport*> reports_to_remove; - - for (const ReportingReport* report : reports) { - size_t erased = pending_reports_.erase(report); - DCHECK_EQ(1u, erased); - if (base::ContainsKey(doomed_reports_, report)) { - reports_to_remove.push_back(report); - doomed_reports_.erase(report); - } - } - - for (const ReportingReport* report : reports_to_remove) - RemoveReportInternal(report); - } - - void IncrementReportsAttempts( - const std::vector<const ReportingReport*>& reports) override { - for (const ReportingReport* report : reports) { - DCHECK(base::ContainsKey(reports_, report)); - reports_[report]->attempts++; - } - - context_->NotifyCachedReportsUpdated(); - } - - void IncrementEndpointDeliveries(const url::Origin& origin, - const GURL& endpoint, - int reports_delivered, - bool successful) override { - const ReportingClient* client = - GetClientByOriginAndEndpoint(origin, endpoint); - if (client) { - auto& metadata = client_metadata_[client]; - metadata.stats.attempted_uploads++; - metadata.stats.attempted_reports += reports_delivered; - if (successful) { - metadata.stats.successful_uploads++; - metadata.stats.successful_reports += reports_delivered; - } - } - } - - void RemoveReports(const std::vector<const ReportingReport*>& reports, - ReportingReport::Outcome outcome) override { - for (const ReportingReport* report : reports) { - reports_[report]->outcome = outcome; - if (base::ContainsKey(pending_reports_, report)) { - doomed_reports_.insert(report); - } else { - DCHECK(!base::ContainsKey(doomed_reports_, report)); - RemoveReportInternal(report); - } - } - - context_->NotifyCachedReportsUpdated(); - } - - void RemoveAllReports(ReportingReport::Outcome outcome) override { - std::vector<const ReportingReport*> reports_to_remove; - for (auto it = reports_.begin(); it != reports_.end(); ++it) { - ReportingReport* report = it->second.get(); - report->outcome = outcome; - if (!base::ContainsKey(pending_reports_, report)) - reports_to_remove.push_back(report); - else - doomed_reports_.insert(report); - } - - for (const ReportingReport* report : reports_to_remove) - RemoveReportInternal(report); - - context_->NotifyCachedReportsUpdated(); - } - - void SetClient(const url::Origin& origin, - const GURL& endpoint, - ReportingClient::Subdomains subdomains, - const std::string& group, - base::TimeTicks expires, - int priority, - int weight) override { - DCHECK(endpoint.SchemeIsCryptographic()); - - base::TimeTicks last_used = tick_clock()->NowTicks(); - - const ReportingClient* old_client = - GetClientByOriginAndEndpoint(origin, endpoint); - if (old_client) { - last_used = client_metadata_[old_client].last_used; - RemoveClient(old_client); - } - - AddClient( - std::make_unique<ReportingClient>(origin, endpoint, subdomains, group, - expires, priority, weight), - last_used); - - if (client_metadata_.size() > context_->policy().max_client_count) { - // There should only ever be one extra client, added above. - DCHECK_EQ(context_->policy().max_client_count + 1, - client_metadata_.size()); - // And that shouldn't happen if it was replaced, not added. - DCHECK(!old_client); - const ReportingClient* to_evict = - FindClientToEvict(tick_clock()->NowTicks()); - DCHECK(to_evict); - RemoveClient(to_evict); - } - - context_->NotifyCachedClientsUpdated(); - } - - void MarkClientUsed(const ReportingClient* client) override { - DCHECK(client); - client_metadata_[client].last_used = tick_clock()->NowTicks(); - } - - void GetClients( - std::vector<const ReportingClient*>* clients_out) const override { - clients_out->clear(); - for (const auto& it : clients_) - for (const auto& endpoint_and_client : it.second) - clients_out->push_back(endpoint_and_client.second.get()); - } - - base::Value GetClientsAsValue() const override { - std::map<const url::Origin, - std::map<const std::string, std::vector<const ReportingClient*>>> - clients_by_origin_and_group; - for (const auto& it : clients_) { - const url::Origin& origin = it.first; - for (const auto& endpoint_and_client : it.second) { - const ReportingClient* client = endpoint_and_client.second.get(); - clients_by_origin_and_group[origin][client->group].push_back(client); - } - } - - std::vector<base::Value> origin_list; - for (const auto& it : clients_by_origin_and_group) { - const url::Origin& origin = it.first; - base::Value origin_dict(base::Value::Type::DICTIONARY); - origin_dict.SetKey("origin", base::Value(origin.Serialize())); - std::vector<base::Value> group_list; - for (const auto& group_and_clients : it.second) { - const std::string& group = group_and_clients.first; - const std::vector<const ReportingClient*>& clients = - group_and_clients.second; - base::Value group_dict(base::Value::Type::DICTIONARY); - group_dict.SetKey("name", base::Value(group)); - std::vector<base::Value> endpoint_list; - for (const ReportingClient* client : clients) { - base::Value endpoint_dict(base::Value::Type::DICTIONARY); - // Reporting defines the group as a whole to have an expiration time - // and subdomains flag, not the individual endpoints within the group. - group_dict.SetKey( - "expires", - base::Value(NetLog::TickCountToString(client->expires))); - group_dict.SetKey("includeSubdomains", - base::Value(client->subdomains == - ReportingClient::Subdomains::INCLUDE)); - endpoint_dict.SetKey("url", base::Value(client->endpoint.spec())); - endpoint_dict.SetKey("priority", base::Value(client->priority)); - endpoint_dict.SetKey("weight", base::Value(client->weight)); - auto metadata_it = client_metadata_.find(client); - if (metadata_it != client_metadata_.end()) { - const ClientStatistics& stats = metadata_it->second.stats; - base::Value successful_dict(base::Value::Type::DICTIONARY); - successful_dict.SetKey("uploads", - base::Value(stats.successful_uploads)); - successful_dict.SetKey("reports", - base::Value(stats.successful_reports)); - endpoint_dict.SetKey("successful", std::move(successful_dict)); - base::Value failed_dict(base::Value::Type::DICTIONARY); - failed_dict.SetKey("uploads", - base::Value(stats.attempted_uploads - - stats.successful_uploads)); - failed_dict.SetKey("reports", - base::Value(stats.attempted_reports - - stats.successful_reports)); - endpoint_dict.SetKey("failed", std::move(failed_dict)); - } - endpoint_list.push_back(std::move(endpoint_dict)); - } - group_dict.SetKey("endpoints", base::Value(std::move(endpoint_list))); - group_list.push_back(std::move(group_dict)); - } - origin_dict.SetKey("groups", base::Value(std::move(group_list))); - origin_list.push_back(std::move(origin_dict)); - } - return base::Value(std::move(origin_list)); - } - - void GetClientsForOriginAndGroup( - const url::Origin& origin, - const std::string& group, - std::vector<const ReportingClient*>* clients_out) const override { - clients_out->clear(); - - const auto it = clients_.find(origin); - if (it != clients_.end()) { - for (const auto& endpoint_and_client : it->second) { - if (endpoint_and_client.second->group == group) - clients_out->push_back(endpoint_and_client.second.get()); - } - } - - // If no clients were found, try successive superdomain suffixes until a - // client with include_subdomains is found or there are no more domain - // components left. - std::string domain = origin.host(); - while (clients_out->empty() && !domain.empty()) { - GetWildcardClientsForDomainAndGroup(domain, group, clients_out); - domain = GetSuperdomain(domain); - } - } - - // TODO(juliatuttle): Unittests. - void GetEndpointsForOrigin(const url::Origin& origin, - std::vector<GURL>* endpoints_out) const override { - endpoints_out->clear(); - - const auto it = clients_.find(origin); - if (it == clients_.end()) - return; - - for (const auto& endpoint_and_client : it->second) - endpoints_out->push_back(endpoint_and_client.first); - } - - void RemoveClients( - const std::vector<const ReportingClient*>& clients_to_remove) override { - for (const ReportingClient* client : clients_to_remove) - RemoveClient(client); - - context_->NotifyCachedClientsUpdated(); - } - - void RemoveClientForOriginAndEndpoint(const url::Origin& origin, - const GURL& endpoint) override { - const ReportingClient* client = - GetClientByOriginAndEndpoint(origin, endpoint); - if (!client) - return; - RemoveClient(client); - - context_->NotifyCachedClientsUpdated(); - } - - void RemoveClientsForEndpoint(const GURL& endpoint) override { - std::vector<const ReportingClient*> clients_to_remove; - - for (auto& origin_and_endpoints : clients_) - if (base::ContainsKey(origin_and_endpoints.second, endpoint)) - clients_to_remove.push_back( - origin_and_endpoints.second[endpoint].get()); - - for (const ReportingClient* client : clients_to_remove) - RemoveClient(client); - - if (!clients_to_remove.empty()) - context_->NotifyCachedClientsUpdated(); - } - - void RemoveAllClients() override { - clients_.clear(); - wildcard_clients_.clear(); - client_metadata_.clear(); - - context_->NotifyCachedClientsUpdated(); - } - - ClientStatistics GetStatisticsForOriginAndEndpoint( - const url::Origin& origin, - const GURL& endpoint) const override { - const ReportingClient* client = - GetClientByOriginAndEndpoint(origin, endpoint); - auto it = client_metadata_.find(client); - if (it == client_metadata_.end()) { - return ClientStatistics(); - } - return it->second.stats; - } - - size_t GetFullReportCountForTesting() const override { - return reports_.size(); - } - - bool IsReportPendingForTesting(const ReportingReport* report) const override { - return base::ContainsKey(pending_reports_, report); - } - - bool IsReportDoomedForTesting(const ReportingReport* report) const override { - return base::ContainsKey(doomed_reports_, report); - } - - private: - void RemoveReportInternal(const ReportingReport* report) { - reports_[report]->RecordOutcome(tick_clock()->NowTicks()); - size_t erased = reports_.erase(report); - DCHECK_EQ(1u, erased); - } - - const ReportingReport* FindReportToEvict() const { - const ReportingReport* earliest_queued = nullptr; - - for (const auto& it : reports_) { - const ReportingReport* report = it.first; - if (base::ContainsKey(pending_reports_, report)) - continue; - if (!earliest_queued || report->queued < earliest_queued->queued) { - earliest_queued = report; - } - } - - return earliest_queued; - } - - void AddClient(std::unique_ptr<ReportingClient> client, - base::TimeTicks last_used) { - DCHECK(client); - - url::Origin origin = client->origin; - GURL endpoint = client->endpoint; - - auto inserted_metadata = client_metadata_.insert( - std::make_pair(client.get(), ClientMetadata{last_used})); - DCHECK(inserted_metadata.second); - - if (client->subdomains == ReportingClient::Subdomains::INCLUDE) { - const std::string& domain = origin.host(); - auto inserted_wildcard_client = - wildcard_clients_[domain].insert(client.get()); - DCHECK(inserted_wildcard_client.second); - } - - auto inserted_client = - clients_[origin].insert(std::make_pair(endpoint, std::move(client))); - DCHECK(inserted_client.second); - } - - void RemoveClient(const ReportingClient* client) { - DCHECK(client); - - url::Origin origin = client->origin; - GURL endpoint = client->endpoint; - - if (client->subdomains == ReportingClient::Subdomains::INCLUDE) { - const std::string& domain = origin.host(); - size_t erased_wildcard_client = wildcard_clients_[domain].erase(client); - DCHECK_EQ(1u, erased_wildcard_client); - if (wildcard_clients_[domain].empty()) { - size_t erased_wildcard_domain = wildcard_clients_.erase(domain); - DCHECK_EQ(1u, erased_wildcard_domain); - } - } - - size_t erased_metadata = client_metadata_.erase(client); - DCHECK_EQ(1u, erased_metadata); - - size_t erased_endpoint = clients_[origin].erase(endpoint); - DCHECK_EQ(1u, erased_endpoint); - if (clients_[origin].empty()) { - size_t erased_origin = clients_.erase(origin); - DCHECK_EQ(1u, erased_origin); - } - } - - const ReportingClient* GetClientByOriginAndEndpoint( - const url::Origin& origin, - const GURL& endpoint) const { - const auto& origin_it = clients_.find(origin); - if (origin_it == clients_.end()) - return nullptr; - - const auto& endpoint_it = origin_it->second.find(endpoint); - if (endpoint_it == origin_it->second.end()) - return nullptr; - - return endpoint_it->second.get(); - } - - void GetWildcardClientsForDomainAndGroup( - const std::string& domain, - const std::string& group, - std::vector<const ReportingClient*>* clients_out) const { - clients_out->clear(); - - auto it = wildcard_clients_.find(domain); - if (it == wildcard_clients_.end()) - return; - - for (const ReportingClient* client : it->second) { - DCHECK_EQ(ReportingClient::Subdomains::INCLUDE, client->subdomains); - if (client->group == group) - clients_out->push_back(client); - } - } - - const ReportingClient* FindClientToEvict(base::TimeTicks now) const { - DCHECK(!client_metadata_.empty()); - - const ReportingClient* earliest_used = nullptr; - base::TimeTicks earliest_used_last_used; - const ReportingClient* earliest_expired = nullptr; - - for (const auto& it : client_metadata_) { - const ReportingClient* client = it.first; - base::TimeTicks client_last_used = it.second.last_used; - if (earliest_used == nullptr || - client_last_used < earliest_used_last_used) { - earliest_used = client; - earliest_used_last_used = client_last_used; - } - if (earliest_expired == nullptr || - client->expires < earliest_expired->expires) { - earliest_expired = client; - } - } - - // If there are expired clients, return the earliest-expired. - if (earliest_expired->expires < now) - return earliest_expired; - else - return earliest_used; - } - - const base::TickClock* tick_clock() { return context_->tick_clock(); } - - ReportingContext* context_; - - // Owns all reports, keyed by const raw pointer for easier lookup. - std::unordered_map<const ReportingReport*, std::unique_ptr<ReportingReport>> - reports_; - - // Reports that have been marked pending (in use elsewhere and should not be - // deleted until no longer pending). - std::unordered_set<const ReportingReport*> pending_reports_; - - // Reports that have been marked doomed (would have been deleted, but were - // pending when the deletion was requested). - std::unordered_set<const ReportingReport*> doomed_reports_; - - // Owns all clients, keyed by origin, then endpoint URL. - // (These would be unordered_map, but neither url::Origin nor GURL has a hash - // function implemented.) - std::map<url::Origin, std::map<GURL, std::unique_ptr<ReportingClient>>> - clients_; - - // References but does not own all clients with include_subdomains set, keyed - // by domain name. - std::unordered_map<std::string, std::unordered_set<const ReportingClient*>> - wildcard_clients_; - - // The time that each client has last been used. - std::unordered_map<const ReportingClient*, ClientMetadata> client_metadata_; -}; - -} // namespace - // static std::unique_ptr<ReportingCache> ReportingCache::Create( ReportingContext* context) {
diff --git a/net/reporting/reporting_cache_impl.cc b/net/reporting/reporting_cache_impl.cc new file mode 100644 index 0000000..7096ee7 --- /dev/null +++ b/net/reporting/reporting_cache_impl.cc
@@ -0,0 +1,586 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/reporting/reporting_cache_impl.h" + +#include <algorithm> +#include <utility> + +#include "base/time/clock.h" +#include "base/time/tick_clock.h" +#include "net/log/net_log.h" + +namespace net { + +namespace { + +// Returns the superdomain of a given domain, or the empty string if the given +// domain is just a single label. Note that this does not take into account +// anything like the Public Suffix List, so the superdomain may end up being a +// bare TLD. +// +// Examples: +// +// GetSuperdomain("assets.example.com") -> "example.com" +// GetSuperdomain("example.net") -> "net" +// GetSuperdomain("littlebox") -> "" +std::string GetSuperdomain(const std::string& domain) { + size_t dot_pos = domain.find('.'); + if (dot_pos == std::string::npos) + return ""; + + return domain.substr(dot_pos + 1); +} + +} // namespace + +ReportingCacheImpl::ReportingCacheImpl(ReportingContext* context) + : context_(context) { + DCHECK(context_); +} + +ReportingCacheImpl::~ReportingCacheImpl() { + base::TimeTicks now = tick_clock()->NowTicks(); + + // Mark all undoomed reports as erased at shutdown, and record outcomes of + // all remaining reports (doomed or not). + for (auto it = reports_.begin(); it != reports_.end(); ++it) { + ReportingReport* report = it->second.get(); + if (!base::ContainsKey(doomed_reports_, report)) + report->outcome = ReportingReport::Outcome::ERASED_REPORTING_SHUT_DOWN; + report->RecordOutcome(now); + } + + reports_.clear(); +} + +void ReportingCacheImpl::AddReport(const GURL& url, + const std::string& user_agent, + const std::string& group, + const std::string& type, + std::unique_ptr<const base::Value> body, + int depth, + base::TimeTicks queued, + int attempts) { + auto report = std::make_unique<ReportingReport>( + url, user_agent, group, type, std::move(body), depth, queued, attempts); + + auto inserted = + reports_.insert(std::make_pair(report.get(), std::move(report))); + DCHECK(inserted.second); + + if (reports_.size() > context_->policy().max_report_count) { + // There should be at most one extra report (the one added above). + DCHECK_EQ(context_->policy().max_report_count + 1, reports_.size()); + const ReportingReport* to_evict = FindReportToEvict(); + DCHECK_NE(nullptr, to_evict); + // The newly-added report isn't pending, so even if all other reports are + // pending, the cache should have a report to evict. + DCHECK(!base::ContainsKey(pending_reports_, to_evict)); + reports_[to_evict]->outcome = ReportingReport::Outcome::ERASED_EVICTED; + RemoveReportInternal(to_evict); + } + + context_->NotifyCachedReportsUpdated(); +} + +void ReportingCacheImpl::GetReports( + std::vector<const ReportingReport*>* reports_out) const { + reports_out->clear(); + for (const auto& it : reports_) { + if (!base::ContainsKey(doomed_reports_, it.first)) + reports_out->push_back(it.second.get()); + } +} + +base::Value ReportingCacheImpl::GetReportsAsValue() const { + // Sort the queued reports by origin and timestamp. + std::vector<const ReportingReport*> sorted_reports; + sorted_reports.reserve(reports_.size()); + for (const auto& it : reports_) { + sorted_reports.push_back(it.second.get()); + } + std::sort(sorted_reports.begin(), sorted_reports.end(), + [](const ReportingReport* report1, const ReportingReport* report2) { + if (report1->queued < report2->queued) + return true; + else if (report1->queued > report2->queued) + return false; + else + return report1->url < report2->url; + }); + + std::vector<base::Value> report_list; + for (const ReportingReport* report : sorted_reports) { + base::Value report_dict(base::Value::Type::DICTIONARY); + report_dict.SetKey("url", base::Value(report->url.spec())); + report_dict.SetKey("group", base::Value(report->group)); + report_dict.SetKey("type", base::Value(report->type)); + report_dict.SetKey("depth", base::Value(report->depth)); + report_dict.SetKey("queued", + base::Value(NetLog::TickCountToString(report->queued))); + report_dict.SetKey("attempts", base::Value(report->attempts)); + if (report->body) { + report_dict.SetKey("body", report->body->Clone()); + } + if (base::ContainsKey(doomed_reports_, report)) { + report_dict.SetKey("status", base::Value("doomed")); + } else if (base::ContainsKey(pending_reports_, report)) { + report_dict.SetKey("status", base::Value("pending")); + } else { + report_dict.SetKey("status", base::Value("queued")); + } + report_list.push_back(std::move(report_dict)); + } + return base::Value(std::move(report_list)); +} + +void ReportingCacheImpl::GetNonpendingReports( + std::vector<const ReportingReport*>* reports_out) const { + reports_out->clear(); + for (const auto& it : reports_) { + if (!base::ContainsKey(pending_reports_, it.first) && + !base::ContainsKey(doomed_reports_, it.first)) { + reports_out->push_back(it.second.get()); + } + } +} + +void ReportingCacheImpl::SetReportsPending( + const std::vector<const ReportingReport*>& reports) { + for (const ReportingReport* report : reports) { + auto inserted = pending_reports_.insert(report); + DCHECK(inserted.second); + } +} + +void ReportingCacheImpl::ClearReportsPending( + const std::vector<const ReportingReport*>& reports) { + std::vector<const ReportingReport*> reports_to_remove; + + for (const ReportingReport* report : reports) { + size_t erased = pending_reports_.erase(report); + DCHECK_EQ(1u, erased); + if (base::ContainsKey(doomed_reports_, report)) { + reports_to_remove.push_back(report); + doomed_reports_.erase(report); + } + } + + for (const ReportingReport* report : reports_to_remove) + RemoveReportInternal(report); +} + +void ReportingCacheImpl::IncrementReportsAttempts( + const std::vector<const ReportingReport*>& reports) { + for (const ReportingReport* report : reports) { + DCHECK(base::ContainsKey(reports_, report)); + reports_[report]->attempts++; + } + + context_->NotifyCachedReportsUpdated(); +} + +void ReportingCacheImpl::IncrementEndpointDeliveries(const url::Origin& origin, + const GURL& endpoint, + int reports_delivered, + bool successful) { + const ReportingClient* client = + GetClientByOriginAndEndpoint(origin, endpoint); + if (client) { + auto& metadata = client_metadata_[client]; + metadata.stats.attempted_uploads++; + metadata.stats.attempted_reports += reports_delivered; + if (successful) { + metadata.stats.successful_uploads++; + metadata.stats.successful_reports += reports_delivered; + } + } +} + +void ReportingCacheImpl::RemoveReports( + const std::vector<const ReportingReport*>& reports, + ReportingReport::Outcome outcome) { + for (const ReportingReport* report : reports) { + reports_[report]->outcome = outcome; + if (base::ContainsKey(pending_reports_, report)) { + doomed_reports_.insert(report); + } else { + DCHECK(!base::ContainsKey(doomed_reports_, report)); + RemoveReportInternal(report); + } + } + + context_->NotifyCachedReportsUpdated(); +} + +void ReportingCacheImpl::RemoveAllReports(ReportingReport::Outcome outcome) { + std::vector<const ReportingReport*> reports_to_remove; + for (auto it = reports_.begin(); it != reports_.end(); ++it) { + ReportingReport* report = it->second.get(); + report->outcome = outcome; + if (!base::ContainsKey(pending_reports_, report)) + reports_to_remove.push_back(report); + else + doomed_reports_.insert(report); + } + + for (const ReportingReport* report : reports_to_remove) + RemoveReportInternal(report); + + context_->NotifyCachedReportsUpdated(); +} + +void ReportingCacheImpl::SetClient(const url::Origin& origin, + const GURL& endpoint, + ReportingClient::Subdomains subdomains, + const std::string& group, + base::TimeTicks expires, + int priority, + int weight) { + DCHECK(endpoint.SchemeIsCryptographic()); + + base::TimeTicks last_used = tick_clock()->NowTicks(); + + const ReportingClient* old_client = + GetClientByOriginAndEndpoint(origin, endpoint); + if (old_client) { + last_used = client_metadata_[old_client].last_used; + RemoveClient(old_client); + } + + AddClient(std::make_unique<ReportingClient>(origin, endpoint, subdomains, + group, expires, priority, weight), + last_used); + + if (client_metadata_.size() > context_->policy().max_client_count) { + // There should only ever be one extra client, added above. + DCHECK_EQ(context_->policy().max_client_count + 1, client_metadata_.size()); + // And that shouldn't happen if it was replaced, not added. + DCHECK(!old_client); + const ReportingClient* to_evict = + FindClientToEvict(tick_clock()->NowTicks()); + DCHECK(to_evict); + RemoveClient(to_evict); + } + + context_->NotifyCachedClientsUpdated(); +} + +void ReportingCacheImpl::MarkClientUsed(const ReportingClient* client) { + DCHECK(client); + client_metadata_[client].last_used = tick_clock()->NowTicks(); +} + +void ReportingCacheImpl::GetClients( + std::vector<const ReportingClient*>* clients_out) const { + clients_out->clear(); + for (const auto& it : clients_) + for (const auto& endpoint_and_client : it.second) + clients_out->push_back(endpoint_and_client.second.get()); +} + +base::Value ReportingCacheImpl::GetClientsAsValue() const { + std::map<const url::Origin, + std::map<const std::string, std::vector<const ReportingClient*>>> + clients_by_origin_and_group; + for (const auto& it : clients_) { + const url::Origin& origin = it.first; + for (const auto& endpoint_and_client : it.second) { + const ReportingClient* client = endpoint_and_client.second.get(); + clients_by_origin_and_group[origin][client->group].push_back(client); + } + } + + std::vector<base::Value> origin_list; + for (const auto& it : clients_by_origin_and_group) { + const url::Origin& origin = it.first; + base::Value origin_dict(base::Value::Type::DICTIONARY); + origin_dict.SetKey("origin", base::Value(origin.Serialize())); + std::vector<base::Value> group_list; + for (const auto& group_and_clients : it.second) { + const std::string& group = group_and_clients.first; + const std::vector<const ReportingClient*>& clients = + group_and_clients.second; + base::Value group_dict(base::Value::Type::DICTIONARY); + group_dict.SetKey("name", base::Value(group)); + std::vector<base::Value> endpoint_list; + for (const ReportingClient* client : clients) { + base::Value endpoint_dict(base::Value::Type::DICTIONARY); + // Reporting defines the group as a whole to have an expiration time + // and subdomains flag, not the individual endpoints within the group. + group_dict.SetKey( + "expires", base::Value(NetLog::TickCountToString(client->expires))); + group_dict.SetKey("includeSubdomains", + base::Value(client->subdomains == + ReportingClient::Subdomains::INCLUDE)); + endpoint_dict.SetKey("url", base::Value(client->endpoint.spec())); + endpoint_dict.SetKey("priority", base::Value(client->priority)); + endpoint_dict.SetKey("weight", base::Value(client->weight)); + auto metadata_it = client_metadata_.find(client); + if (metadata_it != client_metadata_.end()) { + const ClientStatistics& stats = metadata_it->second.stats; + base::Value successful_dict(base::Value::Type::DICTIONARY); + successful_dict.SetKey("uploads", + base::Value(stats.successful_uploads)); + successful_dict.SetKey("reports", + base::Value(stats.successful_reports)); + endpoint_dict.SetKey("successful", std::move(successful_dict)); + base::Value failed_dict(base::Value::Type::DICTIONARY); + failed_dict.SetKey("uploads", base::Value(stats.attempted_uploads - + stats.successful_uploads)); + failed_dict.SetKey("reports", base::Value(stats.attempted_reports - + stats.successful_reports)); + endpoint_dict.SetKey("failed", std::move(failed_dict)); + } + endpoint_list.push_back(std::move(endpoint_dict)); + } + group_dict.SetKey("endpoints", base::Value(std::move(endpoint_list))); + group_list.push_back(std::move(group_dict)); + } + origin_dict.SetKey("groups", base::Value(std::move(group_list))); + origin_list.push_back(std::move(origin_dict)); + } + return base::Value(std::move(origin_list)); +} + +void ReportingCacheImpl::GetClientsForOriginAndGroup( + const url::Origin& origin, + const std::string& group, + std::vector<const ReportingClient*>* clients_out) const { + clients_out->clear(); + + const auto it = clients_.find(origin); + if (it != clients_.end()) { + for (const auto& endpoint_and_client : it->second) { + if (endpoint_and_client.second->group == group) + clients_out->push_back(endpoint_and_client.second.get()); + } + } + + // If no clients were found, try successive superdomain suffixes until a + // client with include_subdomains is found or there are no more domain + // components left. + std::string domain = origin.host(); + while (clients_out->empty() && !domain.empty()) { + GetWildcardClientsForDomainAndGroup(domain, group, clients_out); + domain = GetSuperdomain(domain); + } +} + +// TODO(juliatuttle): Unittests. +void ReportingCacheImpl::GetEndpointsForOrigin( + const url::Origin& origin, + std::vector<GURL>* endpoints_out) const { + endpoints_out->clear(); + + const auto it = clients_.find(origin); + if (it == clients_.end()) + return; + + for (const auto& endpoint_and_client : it->second) + endpoints_out->push_back(endpoint_and_client.first); +} + +void ReportingCacheImpl::RemoveClients( + const std::vector<const ReportingClient*>& clients_to_remove) { + for (const ReportingClient* client : clients_to_remove) + RemoveClient(client); + + context_->NotifyCachedClientsUpdated(); +} + +void ReportingCacheImpl::RemoveClientForOriginAndEndpoint( + const url::Origin& origin, + const GURL& endpoint) { + const ReportingClient* client = + GetClientByOriginAndEndpoint(origin, endpoint); + if (!client) + return; + RemoveClient(client); + + context_->NotifyCachedClientsUpdated(); +} + +void ReportingCacheImpl::RemoveClientsForEndpoint(const GURL& endpoint) { + std::vector<const ReportingClient*> clients_to_remove; + + for (auto& origin_and_endpoints : clients_) + if (base::ContainsKey(origin_and_endpoints.second, endpoint)) + clients_to_remove.push_back(origin_and_endpoints.second[endpoint].get()); + + for (const ReportingClient* client : clients_to_remove) + RemoveClient(client); + + if (!clients_to_remove.empty()) + context_->NotifyCachedClientsUpdated(); +} + +void ReportingCacheImpl::RemoveAllClients() { + clients_.clear(); + wildcard_clients_.clear(); + client_metadata_.clear(); + + context_->NotifyCachedClientsUpdated(); +} + +ReportingCache::ClientStatistics +ReportingCacheImpl::GetStatisticsForOriginAndEndpoint( + const url::Origin& origin, + const GURL& endpoint) const { + const ReportingClient* client = + GetClientByOriginAndEndpoint(origin, endpoint); + auto it = client_metadata_.find(client); + if (it == client_metadata_.end()) { + return ClientStatistics(); + } + return it->second.stats; +} + +size_t ReportingCacheImpl::GetFullReportCountForTesting() const { + return reports_.size(); +} + +bool ReportingCacheImpl::IsReportPendingForTesting( + const ReportingReport* report) const { + return base::ContainsKey(pending_reports_, report); +} + +bool ReportingCacheImpl::IsReportDoomedForTesting( + const ReportingReport* report) const { + return base::ContainsKey(doomed_reports_, report); +} + +void ReportingCacheImpl::RemoveReportInternal(const ReportingReport* report) { + reports_[report]->RecordOutcome(tick_clock()->NowTicks()); + size_t erased = reports_.erase(report); + DCHECK_EQ(1u, erased); +} + +const ReportingReport* ReportingCacheImpl::FindReportToEvict() const { + const ReportingReport* earliest_queued = nullptr; + + for (const auto& it : reports_) { + const ReportingReport* report = it.first; + if (base::ContainsKey(pending_reports_, report)) + continue; + if (!earliest_queued || report->queued < earliest_queued->queued) { + earliest_queued = report; + } + } + + return earliest_queued; +} + +void ReportingCacheImpl::AddClient(std::unique_ptr<ReportingClient> client, + base::TimeTicks last_used) { + DCHECK(client); + + url::Origin origin = client->origin; + GURL endpoint = client->endpoint; + + auto inserted_metadata = client_metadata_.insert( + std::make_pair(client.get(), ClientMetadata{last_used})); + DCHECK(inserted_metadata.second); + + if (client->subdomains == ReportingClient::Subdomains::INCLUDE) { + const std::string& domain = origin.host(); + auto inserted_wildcard_client = + wildcard_clients_[domain].insert(client.get()); + DCHECK(inserted_wildcard_client.second); + } + + auto inserted_client = + clients_[origin].insert(std::make_pair(endpoint, std::move(client))); + DCHECK(inserted_client.second); +} + +void ReportingCacheImpl::RemoveClient(const ReportingClient* client) { + DCHECK(client); + + url::Origin origin = client->origin; + GURL endpoint = client->endpoint; + + if (client->subdomains == ReportingClient::Subdomains::INCLUDE) { + const std::string& domain = origin.host(); + size_t erased_wildcard_client = wildcard_clients_[domain].erase(client); + DCHECK_EQ(1u, erased_wildcard_client); + if (wildcard_clients_[domain].empty()) { + size_t erased_wildcard_domain = wildcard_clients_.erase(domain); + DCHECK_EQ(1u, erased_wildcard_domain); + } + } + + size_t erased_metadata = client_metadata_.erase(client); + DCHECK_EQ(1u, erased_metadata); + + size_t erased_endpoint = clients_[origin].erase(endpoint); + DCHECK_EQ(1u, erased_endpoint); + if (clients_[origin].empty()) { + size_t erased_origin = clients_.erase(origin); + DCHECK_EQ(1u, erased_origin); + } +} + +const ReportingClient* ReportingCacheImpl::GetClientByOriginAndEndpoint( + const url::Origin& origin, + const GURL& endpoint) const { + const auto& origin_it = clients_.find(origin); + if (origin_it == clients_.end()) + return nullptr; + + const auto& endpoint_it = origin_it->second.find(endpoint); + if (endpoint_it == origin_it->second.end()) + return nullptr; + + return endpoint_it->second.get(); +} + +void ReportingCacheImpl::GetWildcardClientsForDomainAndGroup( + const std::string& domain, + const std::string& group, + std::vector<const ReportingClient*>* clients_out) const { + clients_out->clear(); + + auto it = wildcard_clients_.find(domain); + if (it == wildcard_clients_.end()) + return; + + for (const ReportingClient* client : it->second) { + DCHECK_EQ(ReportingClient::Subdomains::INCLUDE, client->subdomains); + if (client->group == group) + clients_out->push_back(client); + } +} + +const ReportingClient* ReportingCacheImpl::FindClientToEvict( + base::TimeTicks now) const { + DCHECK(!client_metadata_.empty()); + + const ReportingClient* earliest_used = nullptr; + base::TimeTicks earliest_used_last_used; + const ReportingClient* earliest_expired = nullptr; + + for (const auto& it : client_metadata_) { + const ReportingClient* client = it.first; + base::TimeTicks client_last_used = it.second.last_used; + if (earliest_used == nullptr || + client_last_used < earliest_used_last_used) { + earliest_used = client; + earliest_used_last_used = client_last_used; + } + if (earliest_expired == nullptr || + client->expires < earliest_expired->expires) { + earliest_expired = client; + } + } + + // If there are expired clients, return the earliest-expired. + if (earliest_expired->expires < now) + return earliest_expired; + else + return earliest_used; +} + +} // namespace net
diff --git a/net/reporting/reporting_cache_impl.h b/net/reporting/reporting_cache_impl.h new file mode 100644 index 0000000..9ee2291 --- /dev/null +++ b/net/reporting/reporting_cache_impl.h
@@ -0,0 +1,152 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_REPORTING_REPORTING_CACHE_IMPL_H_ +#define NET_REPORTING_REPORTING_CACHE_IMPL_H_ + +#include <map> +#include <memory> +#include <set> +#include <string> +#include <unordered_map> +#include <unordered_set> +#include <vector> + +#include "base/macros.h" +#include "base/time/time.h" +#include "base/values.h" +#include "net/reporting/reporting_cache.h" +#include "net/reporting/reporting_client.h" +#include "net/reporting/reporting_context.h" +#include "net/reporting/reporting_report.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace net { + +class ReportingCacheImpl : public ReportingCache { + public: + explicit ReportingCacheImpl(ReportingContext* context); + + ~ReportingCacheImpl() override; + + // ReportingCache implementation + void AddReport(const GURL& url, + const std::string& user_agent, + const std::string& group, + const std::string& type, + std::unique_ptr<const base::Value> body, + int depth, + base::TimeTicks queued, + int attempts) override; + void GetReports( + std::vector<const ReportingReport*>* reports_out) const override; + base::Value GetReportsAsValue() const override; + void GetNonpendingReports( + std::vector<const ReportingReport*>* reports_out) const override; + void SetReportsPending( + const std::vector<const ReportingReport*>& reports) override; + void ClearReportsPending( + const std::vector<const ReportingReport*>& reports) override; + void IncrementReportsAttempts( + const std::vector<const ReportingReport*>& reports) override; + void IncrementEndpointDeliveries(const url::Origin& origin, + const GURL& endpoint, + int reports_delivered, + bool successful) override; + void RemoveReports(const std::vector<const ReportingReport*>& reports, + ReportingReport::Outcome outcome) override; + void RemoveAllReports(ReportingReport::Outcome outcome) override; + void SetClient(const url::Origin& origin, + const GURL& endpoint, + ReportingClient::Subdomains subdomains, + const std::string& group, + base::TimeTicks expires, + int priority, + int weight) override; + void MarkClientUsed(const ReportingClient* client) override; + void GetClients( + std::vector<const ReportingClient*>* clients_out) const override; + base::Value GetClientsAsValue() const override; + void GetClientsForOriginAndGroup( + const url::Origin& origin, + const std::string& group, + std::vector<const ReportingClient*>* clients_out) const override; + void GetEndpointsForOrigin(const url::Origin& origin, + std::vector<GURL>* endpoints_out) const override; + void RemoveClients( + const std::vector<const ReportingClient*>& clients_to_remove) override; + void RemoveClientForOriginAndEndpoint(const url::Origin& origin, + const GURL& endpoint) override; + void RemoveClientsForEndpoint(const GURL& endpoint) override; + void RemoveAllClients() override; + ClientStatistics GetStatisticsForOriginAndEndpoint( + const url::Origin& origin, + const GURL& endpoint) const override; + size_t GetFullReportCountForTesting() const override; + bool IsReportPendingForTesting(const ReportingReport* report) const override; + bool IsReportDoomedForTesting(const ReportingReport* report) const override; + + private: + struct ClientMetadata { + base::TimeTicks last_used; + ReportingCache::ClientStatistics stats; + }; + + void RemoveReportInternal(const ReportingReport* report); + + const ReportingReport* FindReportToEvict() const; + + void AddClient(std::unique_ptr<ReportingClient> client, + base::TimeTicks last_used); + + void RemoveClient(const ReportingClient* client); + + const ReportingClient* GetClientByOriginAndEndpoint( + const url::Origin& origin, + const GURL& endpoint) const; + + void GetWildcardClientsForDomainAndGroup( + const std::string& domain, + const std::string& group, + std::vector<const ReportingClient*>* clients_out) const; + + const ReportingClient* FindClientToEvict(base::TimeTicks now) const; + + const base::TickClock* tick_clock() { return context_->tick_clock(); } + + ReportingContext* context_; + + // Owns all reports, keyed by const raw pointer for easier lookup. + std::unordered_map<const ReportingReport*, std::unique_ptr<ReportingReport>> + reports_; + + // Reports that have been marked pending (in use elsewhere and should not be + // deleted until no longer pending). + std::unordered_set<const ReportingReport*> pending_reports_; + + // Reports that have been marked doomed (would have been deleted, but were + // pending when the deletion was requested). + std::unordered_set<const ReportingReport*> doomed_reports_; + + // Owns all clients, keyed by origin, then endpoint URL. + // (These would be unordered_map, but neither url::Origin nor GURL has a hash + // function implemented.) + std::map<url::Origin, std::map<GURL, std::unique_ptr<ReportingClient>>> + clients_; + + // References but does not own all clients with include_subdomains set, keyed + // by domain name. + std::unordered_map<std::string, std::unordered_set<const ReportingClient*>> + wildcard_clients_; + + // The time that each client has last been used. + std::unordered_map<const ReportingClient*, ClientMetadata> client_metadata_; + + DISALLOW_COPY_AND_ASSIGN(ReportingCacheImpl); +}; + +} // namespace net + +#endif // NET_REPORTING_REPORTING_CACHE_IMPL_H_
diff --git a/testing/BUILD.gn b/testing/BUILD.gn index fb17e192..34cf492 100644 --- a/testing/BUILD.gn +++ b/testing/BUILD.gn
@@ -31,7 +31,6 @@ data = [ "//testing/scripts/common.py", "//testing/scripts/run_performance_tests.py", - "//testing/scripts/run_telemetry_benchmark_as_googletest.py", "//tools/perf/generate_legacy_perf_dashboard_json.py", ]
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 4b6b4e0c..3b13615 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -1910,8 +1910,7 @@ }, { "args": [ - "--enable-features=NetworkService", - "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter" + "--enable-features=NetworkService" ], "name": "network_service_browser_tests", "swarming": { @@ -4023,12 +4022,6 @@ "test": "cast_runner_integration_tests" }, { - "swarming": { - "can_use_on_swarming_builders": true - }, - "test": "cast_runner_unittests" - }, - { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter" ], @@ -4186,17 +4179,6 @@ "test": "cast_runner_integration_tests" }, { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1" - } - ] - }, - "test": "cast_runner_unittests" - }, - { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter" ], @@ -4444,17 +4426,6 @@ "test": "cast_runner_integration_tests" }, { - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1" - } - ] - }, - "test": "cast_runner_unittests" - }, - { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter" ],
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 14ac270..fe4da53 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -4803,7 +4803,16 @@ ], "shards": 4 }, - "test": "dawn_end2end_tests" + "test": "dawn_end2end_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } } ] }, @@ -4950,7 +4959,16 @@ ], "shards": 4 }, - "test": "angle_end2end_tests" + "test": "angle_end2end_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -4969,7 +4987,16 @@ } ] }, - "test": "angle_unittests" + "test": "angle_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -4986,7 +5013,16 @@ } ] }, - "test": "angle_white_box_tests" + "test": "angle_white_box_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -5004,7 +5040,16 @@ ], "shards": 4 }, - "test": "dawn_end2end_tests" + "test": "dawn_end2end_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -5021,7 +5066,16 @@ } ] }, - "test": "gl_tests" + "test": "gl_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -5038,7 +5092,16 @@ } ] }, - "test": "gl_unittests" + "test": "gl_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -5054,7 +5117,16 @@ } ] }, - "test": "gles2_conform_test" + "test": "gles2_conform_test", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "swarming": { @@ -5067,7 +5139,16 @@ } ] }, - "test": "swiftshader_unittests" + "test": "swiftshader_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } } ], "isolated_scripts": [ @@ -5093,6 +5174,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -5117,6 +5207,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -5141,6 +5240,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -5165,6 +5273,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -5193,6 +5310,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -5224,6 +5350,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -5263,6 +5398,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -5288,6 +5432,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -5312,6 +5465,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -5337,6 +5499,15 @@ ], "idempotent": false, "shards": 2 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -5362,6 +5533,15 @@ ], "idempotent": false, "shards": 2 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } } ] @@ -6430,7 +6610,16 @@ ], "shards": 4 }, - "test": "angle_end2end_tests" + "test": "angle_end2end_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -6449,7 +6638,16 @@ } ] }, - "test": "angle_unittests" + "test": "angle_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -6466,7 +6664,16 @@ } ] }, - "test": "angle_white_box_tests" + "test": "angle_white_box_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -6484,7 +6691,16 @@ ], "shards": 4 }, - "test": "dawn_end2end_tests" + "test": "dawn_end2end_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -6501,7 +6717,16 @@ } ] }, - "test": "gl_tests" + "test": "gl_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -6518,7 +6743,16 @@ } ] }, - "test": "gl_unittests" + "test": "gl_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -6534,7 +6768,16 @@ } ] }, - "test": "gles2_conform_test" + "test": "gles2_conform_test", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "swarming": { @@ -6547,7 +6790,16 @@ } ] }, - "test": "swiftshader_unittests" + "test": "swiftshader_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } } ], "isolated_scripts": [ @@ -6574,6 +6826,15 @@ "pool": "Chrome-GPU" } ] + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } } ] @@ -7596,7 +7857,16 @@ ], "shards": 4 }, - "test": "angle_end2end_tests" + "test": "angle_end2end_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -7615,7 +7885,16 @@ } ] }, - "test": "angle_unittests" + "test": "angle_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -7632,7 +7911,16 @@ } ] }, - "test": "angle_white_box_tests" + "test": "angle_white_box_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -7653,7 +7941,16 @@ } ] }, - "test": "browser_tests" + "test": "browser_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -7671,7 +7968,16 @@ ], "shards": 4 }, - "test": "dawn_end2end_tests" + "test": "dawn_end2end_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -7688,7 +7994,16 @@ } ] }, - "test": "gl_tests" + "test": "gl_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -7705,7 +8020,16 @@ } ] }, - "test": "gl_unittests" + "test": "gl_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -7721,7 +8045,16 @@ } ] }, - "test": "gles2_conform_test" + "test": "gles2_conform_test", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "swarming": { @@ -7734,7 +8067,16 @@ } ] }, - "test": "swiftshader_unittests" + "test": "swiftshader_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } } ], "isolated_scripts": [ @@ -7761,6 +8103,15 @@ "pool": "Chrome-GPU" } ] + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -7785,6 +8136,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -7809,6 +8169,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -7833,6 +8202,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -7857,6 +8235,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -7885,6 +8272,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -7916,6 +8312,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -7955,6 +8360,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -7980,6 +8394,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -8004,6 +8427,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -8031,6 +8463,15 @@ ], "idempotent": false, "shards": 20 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -8058,6 +8499,15 @@ ], "idempotent": false, "shards": 20 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -8083,6 +8533,15 @@ ], "idempotent": false, "shards": 2 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -8108,6 +8567,15 @@ ], "idempotent": false, "shards": 2 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } } ] @@ -8156,7 +8624,16 @@ ], "shards": 4 }, - "test": "angle_deqp_egl_tests" + "test": "angle_deqp_egl_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -8176,7 +8653,16 @@ ], "shards": 4 }, - "test": "angle_deqp_gles2_tests" + "test": "angle_deqp_gles2_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -8196,7 +8682,16 @@ ], "shards": 6 }, - "test": "angle_deqp_gles31_tests" + "test": "angle_deqp_gles31_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -8216,7 +8711,16 @@ ], "shards": 12 }, - "test": "angle_deqp_gles3_tests" + "test": "angle_deqp_gles3_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } } ] }, @@ -15200,7 +15704,16 @@ ], "shards": 4 }, - "test": "angle_end2end_tests" + "test": "angle_end2end_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -15217,7 +15730,16 @@ } ] }, - "test": "angle_white_box_tests" + "test": "angle_white_box_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -15235,7 +15757,16 @@ ], "shards": 4 }, - "test": "dawn_end2end_tests" + "test": "dawn_end2end_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -15251,7 +15782,16 @@ } ] }, - "test": "gles2_conform_test" + "test": "gles2_conform_test", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "swarming": { @@ -15264,7 +15804,16 @@ } ] }, - "test": "swiftshader_unittests" + "test": "swiftshader_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } } ], "isolated_scripts": [ @@ -15291,6 +15840,15 @@ "pool": "Chrome-GPU" } ] + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -15319,6 +15877,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -15343,6 +15910,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -15370,6 +15946,15 @@ ], "idempotent": false, "shards": 20 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -15395,6 +15980,15 @@ ], "idempotent": false, "shards": 2 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } } ]
diff --git a/testing/buildbot/chromium.gpu.json b/testing/buildbot/chromium.gpu.json index cab33d5..bd3151e 100644 --- a/testing/buildbot/chromium.gpu.json +++ b/testing/buildbot/chromium.gpu.json
@@ -299,7 +299,16 @@ } ] }, - "test": "angle_unittests" + "test": "angle_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -316,7 +325,16 @@ } ] }, - "test": "gl_tests" + "test": "gl_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -333,7 +351,16 @@ } ] }, - "test": "gl_unittests" + "test": "gl_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } } ], "isolated_scripts": [ @@ -359,6 +386,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -383,6 +419,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -407,6 +452,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -431,6 +485,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -459,6 +522,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -490,6 +562,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -529,6 +610,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -554,6 +644,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -578,6 +677,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -603,6 +711,15 @@ ], "idempotent": false, "shards": 2 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } } ] @@ -626,7 +743,16 @@ } ] }, - "test": "angle_unittests" + "test": "angle_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -647,7 +773,16 @@ } ] }, - "test": "browser_tests" + "test": "browser_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -664,7 +799,16 @@ } ] }, - "test": "gl_tests" + "test": "gl_tests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } }, { "args": [ @@ -681,7 +825,16 @@ } ] }, - "test": "gl_unittests" + "test": "gl_unittests", + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" + } } ], "isolated_scripts": [ @@ -707,6 +860,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -731,6 +893,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -755,6 +926,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -779,6 +959,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -807,6 +996,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -838,6 +1036,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -877,6 +1084,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -902,6 +1118,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -926,6 +1151,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -951,6 +1185,15 @@ ], "idempotent": false, "shards": 2 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } } ]
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index 23309e82..d450cf9 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -695,20 +695,6 @@ }, { "args": [ - "--qemu-require-kvm" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "kvm": "1" - } - ] - }, - "test": "cast_runner_unittests" - }, - { - "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter", "--qemu-require-kvm" ],
diff --git a/testing/buildbot/client.v8.fyi.json b/testing/buildbot/client.v8.fyi.json index d9d699d..bab8378 100644 --- a/testing/buildbot/client.v8.fyi.json +++ b/testing/buildbot/client.v8.fyi.json
@@ -296,6 +296,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -320,6 +329,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -344,6 +362,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -368,6 +395,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -399,6 +435,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -438,6 +483,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -463,6 +517,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -487,6 +550,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -514,6 +586,15 @@ ], "idempotent": false, "shards": 20 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -539,6 +620,15 @@ ], "idempotent": false, "shards": 2 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } } ] @@ -567,6 +657,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -591,6 +690,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -615,6 +723,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -639,6 +756,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -670,6 +796,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -709,6 +844,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -734,6 +878,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -758,6 +911,15 @@ } ], "idempotent": false + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -785,6 +947,15 @@ ], "idempotent": false, "shards": 20 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } }, { @@ -810,6 +981,15 @@ ], "idempotent": false, "shards": 2 + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py" } } ]
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index ded4b8b1..a7210a8 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -22,7 +22,6 @@ data = [ "//testing/buildbot/filters/chromeos.mash.browser_tests.filter", "//testing/buildbot/filters/chromeos.mash.fyi.browser_tests.filter", - "//testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter", "//testing/buildbot/filters/webui_polymer2_browser_tests.filter", "//testing/buildbot/filters/webrtc_functional.browser_tests.filter", ]
diff --git a/testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter deleted file mode 100644 index 798aa2b..0000000 --- a/testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter +++ /dev/null
@@ -1,14 +0,0 @@ -# NOTE: if adding an exclusion for an existing failure (e.g. additional test for -# feature X that is already not working), please add it beside the existing -# failures. Otherwise please reach out to network-service-dev@. - -# This filter contains Chrome OS only test failures (in addition to -# cross-platform failures in mojo.fyi.network_browser_tests.filter). -# See https://crbug.com/881976 - -# Crashing on Mash. https://crbug.com/919108 --ChromeBrowserMainBrowserTest.VariationsServiceStartsRequestOnNetworkChange - -# NOTE: if adding an exclusion for an existing failure (e.g. additional test for -# feature X that is already not working), please add it beside the existing -# failures. Otherwise please reach out to network-service-dev@.
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index bfc4da6..25e996a 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -426,10 +426,6 @@ "label": "//fuchsia/runners:cast_runner_integration_tests", "type": "console_test_launcher", }, - "cast_runner_unittests": { - "label": "//fuchsia/runners:cast_runner_unittests", - "type": "console_test_launcher", - }, "cast_audio_backend_unittests": { "label": "//chromecast/media/cma/backend:cast_audio_backend_unittests", "type": "console_test_launcher",
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 930e5a0..8e4ceee 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -2740,7 +2740,6 @@ 'base_unittests': {}, 'cast_runner_browsertests': {}, 'cast_runner_integration_tests': {}, - 'cast_runner_unittests': {}, 'content_unittests': { 'args': [ '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter', @@ -3893,7 +3892,6 @@ 'network_service_browser_tests': { 'args': [ '--enable-features=NetworkService', - '--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.chromeos.network_browser_tests.filter', ], 'swarming': { 'shards': 10,
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 6b5d1ab..f6395aa 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -1799,6 +1799,14 @@ 'gtest_tests': 'gpu_desktop_gtests', 'gpu_telemetry_tests': 'gpu_common_win_and_linux_telemetry_tests', }, + 'use_multi_dimension_trigger_script': True, + 'alternate_swarming_dimensions': [ + { + 'gpu': '10de:1cb3-410.78', + 'os': 'Ubuntu', + 'pool': 'Chrome-GPU', + }, + ], }, 'Linux Release (NVIDIA)': { 'browser_config': 'release', @@ -1810,6 +1818,14 @@ 'gtest_tests': 'gpu_desktop_gtests', 'gpu_telemetry_tests': 'gpu_common_win_and_linux_telemetry_tests', }, + 'use_multi_dimension_trigger_script': True, + 'alternate_swarming_dimensions': [ + { + 'gpu': '10de:1cb3-410.78', + 'os': 'Ubuntu', + 'pool': 'Chrome-GPU', + }, + ], }, 'Mac Debug (Intel)': { 'browser_config': 'debug', @@ -2182,6 +2198,14 @@ 'test_suites': { 'gtest_tests': 'gpu_dawn_end2end_tests', }, + 'use_multi_dimension_trigger_script': True, + 'alternate_swarming_dimensions': [ + { + 'gpu': '10de:1cb3-410.78', + 'os': 'Ubuntu', + 'pool': 'Chrome-GPU', + }, + ], }, 'Dawn GPU Mac Release (Intel)': { 'os_type': 'mac', @@ -2257,6 +2281,14 @@ 'gtest_tests': 'gpu_fyi_linux_debug_gtests', 'gpu_telemetry_tests': 'gpu_fyi_win_and_linux_telemetry_tests', }, + 'use_multi_dimension_trigger_script': True, + 'alternate_swarming_dimensions': [ + { + 'gpu': '10de:1cb3-410.78', + 'os': 'Ubuntu', + 'pool': 'Chrome-GPU', + }, + ], }, 'Linux FYI Experimental Release (Intel HD 630)': { 'os_type': 'linux', @@ -2294,6 +2326,14 @@ 'gtest_tests': 'gpu_fyi_linux_debug_gtests', 'isolated_scripts': 'gpu_angle_perftests', }, + 'use_multi_dimension_trigger_script': True, + 'alternate_swarming_dimensions': [ + { + 'gpu': '10de:1cb3-410.78', + 'os': 'Ubuntu', + 'pool': 'Chrome-GPU', + }, + ], }, 'Linux FYI Ozone (Intel)': { 'os_type': 'linux', @@ -2343,6 +2383,14 @@ 'isolated_scripts': 'gpu_angle_perftests', 'gpu_telemetry_tests': 'gpu_fyi_linux_intel_and_nvidia_release_telemetry_tests', }, + 'use_multi_dimension_trigger_script': True, + 'alternate_swarming_dimensions': [ + { + 'gpu': '10de:1cb3-410.78', + 'os': 'Ubuntu', + 'pool': 'Chrome-GPU', + }, + ], }, 'Linux FYI dEQP Release (Intel HD 630)': { 'os_type': 'linux', @@ -2363,6 +2411,14 @@ 'test_suites': { 'gtest_tests': 'gpu_angle_deqp_linux_nvidia_gtests', }, + 'use_multi_dimension_trigger_script': True, + 'alternate_swarming_dimensions': [ + { + 'gpu': '10de:1cb3-410.78', + 'os': 'Ubuntu', + 'pool': 'Chrome-GPU', + }, + ], }, 'Mac FYI 10.14 Release (AMD)': { 'os_type': 'mac', @@ -2600,6 +2656,14 @@ 'isolated_scripts': 'gpu_angle_perftests', 'gpu_telemetry_tests': 'gpu_fyi_optional_linux_telemetry_tests', }, + 'use_multi_dimension_trigger_script': True, + 'alternate_swarming_dimensions': [ + { + 'gpu': '10de:1cb3-410.78', + 'os': 'Ubuntu', + 'pool': 'Chrome-GPU', + }, + ], }, 'Optional Mac Release (Intel)': { 'os_type': 'mac', @@ -3678,6 +3742,14 @@ 'test_suites': { 'gpu_telemetry_tests': 'gpu_v8_desktop_telemetry_tests', }, + 'use_multi_dimension_trigger_script': True, + 'alternate_swarming_dimensions': [ + { + 'gpu': '10de:1cb3-410.78', + 'os': 'Ubuntu', + 'pool': 'Chrome-GPU', + }, + ], }, 'Linux V8 FYI Release - pointer compression (NVIDIA)': { 'os_type': 'linux', @@ -3688,6 +3760,14 @@ 'test_suites': { 'gpu_telemetry_tests': 'gpu_v8_desktop_telemetry_tests', }, + 'use_multi_dimension_trigger_script': True, + 'alternate_swarming_dimensions': [ + { + 'gpu': '10de:1cb3-410.78', + 'os': 'Ubuntu', + 'pool': 'Chrome-GPU', + }, + ], }, 'Mac V8 FYI Release (Intel)': { 'browser_config': 'release',
diff --git a/testing/perf/OWNERS b/testing/perf/OWNERS index 6cdde70..731c5c6 100644 --- a/testing/perf/OWNERS +++ b/testing/perf/OWNERS
@@ -1,2 +1 @@ charliea@chromium.org -nednguyen@google.com
diff --git a/testing/scripts/run_performance_tests.py b/testing/scripts/run_performance_tests.py index 61658f0..fdc72a5b 100755 --- a/testing/scripts/run_performance_tests.py +++ b/testing/scripts/run_performance_tests.py
@@ -55,8 +55,6 @@ import common -import run_telemetry_benchmark_as_googletest - CHROMIUM_SRC_DIR = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..')) PERF_DIR = os.path.join(CHROMIUM_SRC_DIR, 'tools', 'perf') @@ -206,7 +204,7 @@ # could be any format (chartjson, legacy, histogram). We just pass these # through, and expose these as results for this task. rc, perf_results, json_test_results, benchmark_log = ( - run_telemetry_benchmark_as_googletest.run_benchmark( + execute_telemetry_benchmark_helper( args, per_benchmark_args, is_histograms)) write_results( @@ -217,6 +215,120 @@ return rc +def execute_telemetry_benchmark_helper(args, rest_args, histogram_results): + """Run benchmark with args. + + Args: + args: the option object resulted from parsing commandline args required for + IsolatedScriptTest contract (see + https://cs.chromium.org/chromium/build/scripts/slave/recipe_modules/chromium_tests/steps.py?rcl=d31f256fb860701e6dc02544f2beffe4e17c9b92&l=1639). + rest_args: the args (list of strings) for running Telemetry benchmark. + histogram_results: a boolean describes whether to output histograms format + for the benchmark. + + Returns: a tuple of (rc, perf_results, json_test_results, benchmark_log) + rc: the return code of benchmark + perf_results: json object contains the perf test results + json_test_results: json object contains the Pass/Fail data of the benchmark. + benchmark_log: string contains the stdout/stderr of the benchmark run. + """ + # TODO(crbug.com/920002): These arguments cannot go into + # run_performance_tests.py because + # run_gtest_perf_tests.py does not yet support them. Note that ideally + # we would use common.BaseIsolatedScriptArgsAdapter, but this will take + # a good deal of refactoring to accomplish. + parser = argparse.ArgumentParser() + parser.add_argument( + '--isolated-script-test-repeat', type=int, required=False) + parser.add_argument( + '--isolated-script-test-launcher-retry-limit', type=int, required=False, + choices=[0]) # Telemetry does not support retries. crbug.com/894254#c21 + parser.add_argument( + '--isolated-script-test-also-run-disabled-tests', + default=False, action='store_true', required=False) + # Parse leftover args not already parsed in run_performance_tests.py or in + # main(). + args, rest_args = parser.parse_known_args(args=rest_args, namespace=args) + + env = os.environ.copy() + env['CHROME_HEADLESS'] = '1' + + # Assume we want to set up the sandbox environment variables all the + # time; doing so is harmless on non-Linux platforms and is needed + # all the time on Linux. + env[CHROME_SANDBOX_ENV] = CHROME_SANDBOX_PATH + tempfile_dir = tempfile.mkdtemp('telemetry') + benchmark_log = '' + stdoutfile = os.path.join(tempfile_dir, 'benchmark_log.txt') + valid = True + num_failures = 0 + perf_results = None + json_test_results = None + + results = None + cmd_args = rest_args + if args.isolated_script_test_filter: + filter_list = common.extract_filter_list(args.isolated_script_test_filter) + # Need to convert this to a valid regex. + filter_regex = '(' + '|'.join(filter_list) + ')' + cmd_args.append('--story-filter=' + filter_regex) + if args.isolated_script_test_repeat: + cmd_args.append('--pageset-repeat=' + str(args.isolated_script_test_repeat)) + if args.isolated_script_test_also_run_disabled_tests: + cmd_args.append('--also-run-disabled-tests') + cmd_args.append('--output-dir=' + tempfile_dir) + cmd_args.append('--output-format=json-test-results') + cmd = [sys.executable] + cmd_args + rc = 1 # Set default returncode in case there is an exception. + try: + if args.xvfb: + rc = xvfb.run_executable(cmd, env=env, stdoutfile=stdoutfile) + else: + rc = test_env.run_command_with_output(cmd, env=env, stdoutfile=stdoutfile) + + with open(stdoutfile) as f: + benchmark_log = f.read() + + # If we have also output chartjson read it in and return it. + # results-chart.json is the file name output by telemetry when the + # chartjson output format is included + tempfile_name = None + if histogram_results: + tempfile_name = os.path.join(tempfile_dir, 'histograms.json') + else: + tempfile_name = os.path.join(tempfile_dir, 'results-chart.json') + + if tempfile_name is not None: + with open(tempfile_name) as f: + perf_results = json.load(f) + + # test-results.json is the file name output by telemetry when the + # json-test-results format is included + tempfile_name = os.path.join(tempfile_dir, 'test-results.json') + with open(tempfile_name) as f: + json_test_results = json.load(f) + num_failures = json_test_results['num_failures_by_type'].get('FAIL', 0) + valid = bool(rc == 0 or num_failures != 0) + + except Exception: + traceback.print_exc() + if results: + print 'results, which possibly caused exception: %s' % json.dumps( + results, indent=2) + valid = False + finally: + # Add ignore_errors=True because otherwise rmtree may fail due to leaky + # processes of tests are still holding opened handles to files under + # |tempfile_dir|. For example, see crbug.com/865896 + shutil.rmtree(tempfile_dir, ignore_errors=True) + + if not valid and num_failures == 0: + if rc == 0: + rc = 1 # Signal an abnormal exit. + + return rc, perf_results, json_test_results, benchmark_log + + def append_output_format(args, rest_args): # We need to determine if the output format is already passed in # or if we need to define it for this benchmark
diff --git a/testing/scripts/run_telemetry_benchmark_as_googletest.py b/testing/scripts/run_telemetry_benchmark_as_googletest.py deleted file mode 100755 index 44ac668..0000000 --- a/testing/scripts/run_telemetry_benchmark_as_googletest.py +++ /dev/null
@@ -1,221 +0,0 @@ -#!/usr/bin/env python -# 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. - -"""Runs an isolate bundled Telemetry benchmark. - -This script attempts to emulate the contract of gtest-style tests -invoked via recipes. The main contract is that the caller passes the -argument: - - --isolated-script-test-output=[FILENAME] - -json is written to that file in the format detailed here: -https://www.chromium.org/developers/the-json-test-results-format - -Optional argument: - - --isolated-script-test-filter=[TEST_NAMES] - -is a double-colon-separated ("::") list of test names, to run just that subset -of tests. This list is parsed by this harness and sent down via the ---story-filter argument. - -This script is intended to be the base command invoked by the isolate, -followed by a subsequent Python script. It could be generalized to -invoke an arbitrary executable. - - -TESTING: -To test changes to this script, please run -cd tools/perf -./run_tests ScriptsSmokeTest.testRunTelemetryBenchmarkAsGoogletest -""" - -import argparse -import json -import os -import shutil -import sys -import tempfile -import traceback - -import common - -# Add src/testing/ into sys.path for importing xvfb. -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) -import xvfb -import test_env - -# Unfortunately we need to copy these variables from ../test_env.py. -# Importing it and using its get_sandbox_env breaks test runs on Linux -# (it seems to unset DISPLAY). -CHROME_SANDBOX_ENV = 'CHROME_DEVEL_SANDBOX' -CHROME_SANDBOX_PATH = '/opt/chromium/chrome_sandbox' - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument( - '--isolated-script-test-output', type=argparse.FileType('w'), - required=True) - parser.add_argument( - '--isolated-script-test-chartjson-output', required=False) - parser.add_argument( - '--isolated-script-test-perf-output', required=False) - parser.add_argument( - '--isolated-script-test-filter', type=str, required=False) - parser.add_argument('--xvfb', help='Start xvfb.', action='store_true') - parser.add_argument('--output-format', action='append') - args, rest_args = parser.parse_known_args() - for output_format in args.output_format: - rest_args.append('--output-format=' + output_format) - - rc, perf_results, json_test_results, _ = run_benchmark(args, rest_args, - 'histograms' in args.output_format) - - if perf_results: - if args.isolated_script_test_perf_output: - filename = args.isolated_script_test_perf_output - elif args.isolated_script_test_chartjson_output: - filename = args.isolated_script_test_chartjson_output - else: - filename = None - - if filename is not None: - with open(filename, 'w') as perf_results_output_file: - json.dump(perf_results, perf_results_output_file) - - json.dump(json_test_results, args.isolated_script_test_output) - - return rc - -def run_benchmark(args, rest_args, histogram_results): - """Run benchmark with args. - - Args: - args: the option object resulted from parsing commandline args required for - IsolatedScriptTest contract (see - https://cs.chromium.org/chromium/build/scripts/slave/recipe_modules/chromium_tests/steps.py?rcl=d31f256fb860701e6dc02544f2beffe4e17c9b92&l=1639). - rest_args: the args (list of strings) for running Telemetry benchmark. - histogram_results: a boolean describes whether to output histograms format - for the benchmark. - - Returns: a tuple of (rc, perf_results, json_test_results, benchmark_log) - rc: the return code of benchmark - perf_results: json object contains the perf test results - json_test_results: json object contains the Pass/Fail data of the benchmark. - benchmark_log: string contains the stdout/stderr of the benchmark run. - """ - # TODO(crbug.com/920002): These arguments cannot go into - # run_performance_tests.py because - # run_gtest_perf_tests.py does not yet support them. Note that ideally - # we would use common.BaseIsolatedScriptArgsAdapter, but this will take - # a good deal of refactoring to accomplish. - parser = argparse.ArgumentParser() - parser.add_argument( - '--isolated-script-test-repeat', type=int, required=False) - parser.add_argument( - '--isolated-script-test-launcher-retry-limit', type=int, required=False, - choices=[0]) # Telemetry does not support retries. crbug.com/894254#c21 - parser.add_argument( - '--isolated-script-test-also-run-disabled-tests', - default=False, action='store_true', required=False) - # Parse leftover args not already parsed in run_performance_tests.py or in - # main(). - args, rest_args = parser.parse_known_args(args=rest_args, namespace=args) - - env = os.environ.copy() - env['CHROME_HEADLESS'] = '1' - - # Assume we want to set up the sandbox environment variables all the - # time; doing so is harmless on non-Linux platforms and is needed - # all the time on Linux. - env[CHROME_SANDBOX_ENV] = CHROME_SANDBOX_PATH - tempfile_dir = tempfile.mkdtemp('telemetry') - benchmark_log = '' - stdoutfile = os.path.join(tempfile_dir, 'benchmark_log.txt') - valid = True - num_failures = 0 - perf_results = None - json_test_results = None - - results = None - cmd_args = rest_args - if args.isolated_script_test_filter: - filter_list = common.extract_filter_list(args.isolated_script_test_filter) - # Need to convert this to a valid regex. - filter_regex = '(' + '|'.join(filter_list) + ')' - cmd_args.append('--story-filter=' + filter_regex) - if args.isolated_script_test_repeat: - cmd_args.append('--pageset-repeat=' + str(args.isolated_script_test_repeat)) - if args.isolated_script_test_also_run_disabled_tests: - cmd_args.append('--also-run-disabled-tests') - cmd_args.append('--output-dir=' + tempfile_dir) - cmd_args.append('--output-format=json-test-results') - cmd = [sys.executable] + cmd_args - rc = 1 # Set default returncode in case there is an exception. - try: - if args.xvfb: - rc = xvfb.run_executable(cmd, env=env, stdoutfile=stdoutfile) - else: - rc = test_env.run_command_with_output(cmd, env=env, stdoutfile=stdoutfile) - - with open(stdoutfile) as f: - benchmark_log = f.read() - - # If we have also output chartjson read it in and return it. - # results-chart.json is the file name output by telemetry when the - # chartjson output format is included - tempfile_name = None - if histogram_results: - tempfile_name = os.path.join(tempfile_dir, 'histograms.json') - else: - tempfile_name = os.path.join(tempfile_dir, 'results-chart.json') - - if tempfile_name is not None: - with open(tempfile_name) as f: - perf_results = json.load(f) - - # test-results.json is the file name output by telemetry when the - # json-test-results format is included - tempfile_name = os.path.join(tempfile_dir, 'test-results.json') - with open(tempfile_name) as f: - json_test_results = json.load(f) - num_failures = json_test_results['num_failures_by_type'].get('FAIL', 0) - valid = bool(rc == 0 or num_failures != 0) - - except Exception: - traceback.print_exc() - if results: - print 'results, which possibly caused exception: %s' % json.dumps( - results, indent=2) - valid = False - finally: - # Add ignore_errors=True because otherwise rmtree may fail due to leaky - # processes of tests are still holding opened handles to files under - # |tempfile_dir|. For example, see crbug.com/865896 - shutil.rmtree(tempfile_dir, ignore_errors=True) - - if not valid and num_failures == 0: - if rc == 0: - rc = 1 # Signal an abnormal exit. - - return rc, perf_results, json_test_results, benchmark_log - - -# This is not really a "script test" so does not need to manually add -# any additional compile targets. -def main_compile_targets(args): - json.dump([], args.output) - - -if __name__ == '__main__': - # Conform minimally to the protocol defined by ScriptTest. - if 'compile_targets' in sys.argv: - funcs = { - 'run': None, - 'compile_targets': main_compile_targets, - } - sys.exit(common.run_script(sys.argv[1:], funcs)) - sys.exit(main())
diff --git a/testing/trigger_scripts/base_test_triggerer.py b/testing/trigger_scripts/base_test_triggerer.py index d66c485..b95c9dc1 100755 --- a/testing/trigger_scripts/base_test_triggerer.py +++ b/testing/trigger_scripts/base_test_triggerer.py
@@ -209,9 +209,16 @@ # Main implementation for base class to determine what # configs to trigger jobs on from self._bot_configs. # Returns a list of indices into the self._bot_configs and - # len(args.shards) == len(selected_indices). + # len(self.indices_to_trigger(args)) == len(selected_indices). pass + def indices_to_trigger(self, args): + """Returns the indices of the swarming shards that should be triggered.""" + if args.shard_index is None: + return range(args.shards) + else: + return [args.shard_index] + def trigger_tasks(self, args, remaining): """Triggers tasks for each bot. @@ -244,7 +251,7 @@ # Choose selected configs for this run of the test suite. selected_configs = self.select_config_indices(args, verbose) - for i in xrange(args.shards): + for i in self.indices_to_trigger(args): # For each shard that we're going to distribute, do the following: # 1. Pick which bot configuration to use. # 2. Insert that bot configuration's dimensions as command line @@ -294,5 +301,8 @@ parser.add_argument('--shards', type=int, default=1, help='How many shards to trigger. Duplicated from the' ' `swarming.py trigger` command.') + parser.add_argument('--shard-index', type=int, default=None, + help='Which shard to trigger. Duplicated from the ' + '`swarming.py trigger` command.') return parser
diff --git a/testing/trigger_scripts/perf_device_trigger.py b/testing/trigger_scripts/perf_device_trigger.py index c58ac07..e890acb 100755 --- a/testing/trigger_scripts/perf_device_trigger.py +++ b/testing/trigger_scripts/perf_device_trigger.py
@@ -118,24 +118,25 @@ # If specific bot ids were passed in, we want to trigger a job for # every valid config regardless of health status since # each config represents exactly one bot in the perf swarming pool. - return range(args.shards) + return range(len(self.indices_to_trigger(args))) return self._select_config_indices_with_soft_affinity(args, verbose) def _select_config_indices_with_soft_affinity(self, args, verbose): + trigger_count = len(self.indices_to_trigger(args)) # First make sure the number of shards doesn't exceed the # number of eligible bots. This means there is a config error somewhere. - if args.shards > len(self._eligible_bots_by_ids): + if trigger_count > len(self._eligible_bots_by_ids): if verbose: self._print_device_affinity_info({}, {}, - self._eligible_bots_by_ids, args.shards) + self._eligible_bots_by_ids, trigger_count) raise ValueError('Not enough available machines exist in in swarming' 'pool. Shards requested (%d) exceeds available bots ' '(%d).' % ( - args.shards, len(self._eligible_bots_by_ids))) + trigger_count, len(self._eligible_bots_by_ids))) shard_to_bot_assignment_map = {} unallocated_bots_by_ids = copy.deepcopy(self._eligible_bots_by_ids) - for shard_index in xrange(args.shards): + for shard_index in self.indices_to_trigger(args): bot_id = self._query_swarming_for_last_shard_id(shard_index) if bot_id and bot_id in unallocated_bots_by_ids: bot = unallocated_bots_by_ids[bot_id] @@ -174,14 +175,14 @@ # Now populate the indices into the bot_configs array selected_configs = [] - for shard_index in xrange(args.shards): + for shard_index in self.indices_to_trigger(args): selected_configs.append(self._find_bot_config_index( shard_to_bot_assignment_map[shard_index].id())) if verbose: self._print_device_affinity_info( shard_to_bot_assignment_map, existing_shard_bot_to_shard_map, - self._eligible_bots_by_ids, args.shards) + self._eligible_bots_by_ids, trigger_count) return selected_configs
diff --git a/testing/trigger_scripts/perf_device_trigger_unittest.py b/testing/trigger_scripts/perf_device_trigger_unittest.py index 4ba1e2b..9ea923c 100755 --- a/testing/trigger_scripts/perf_device_trigger_unittest.py +++ b/testing/trigger_scripts/perf_device_trigger_unittest.py
@@ -12,6 +12,7 @@ class Args(object): def __init__(self): self.shards = 1 + self.shard_index = None self.dump_json = '' self.multiple_trigger_configs = None self.multiple_dimension_script_verbose = False
diff --git a/testing/trigger_scripts/trigger_multiple_dimensions.py b/testing/trigger_scripts/trigger_multiple_dimensions.py index a73e4c4..4fd765a 100755 --- a/testing/trigger_scripts/trigger_multiple_dimensions.py +++ b/testing/trigger_scripts/trigger_multiple_dimensions.py
@@ -113,7 +113,7 @@ def select_config_indices(self, args, verbose): selected_indices = [] - for _ in xrange(args.shards): + for _ in self.indices_to_trigger(args): selected_indices.append(self.pick_bot_configuration(verbose)) return selected_indices
diff --git a/testing/trigger_scripts/trigger_multiple_dimensions_unittest.py b/testing/trigger_scripts/trigger_multiple_dimensions_unittest.py index c7530aef..9a29cd39 100755 --- a/testing/trigger_scripts/trigger_multiple_dimensions_unittest.py +++ b/testing/trigger_scripts/trigger_multiple_dimensions_unittest.py
@@ -12,6 +12,7 @@ class Args(object): def __init__(self): self.shards = 1 + self.shard_index = None self.dump_json = '' self.multiple_trigger_configs = [] self.multiple_dimension_script_verbose = False
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index bf934ac..6e6cf504 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1491,7 +1491,8 @@ "android", "android_webview", "chromeos", - "mac" + "mac", + "windows" ], "experiments": [ { @@ -2097,6 +2098,22 @@ ] } ], + "HardwareMediaKeyHandling": [ + { + "platforms": [ + "windows", + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "HardwareMediaKeyHandling" + ] + } + ] + } + ], "HomePageButtonForceEnabled": [ { "platforms": [
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 4d934bda..c47eea98 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -144,10 +144,10 @@ "platform/modules/mediastream/media_stream_audio_source.h", "platform/modules/mediastream/media_stream_audio_track.h", "platform/modules/mediastream/media_stream_types.h", - "platform/modules/mediastream/platform_media_stream_source.h", "platform/modules/mediastream/secure_display_link_tracker.h", "platform/modules/mediastream/web_media_stream_audio_sink.h", "platform/modules/mediastream/web_media_stream_sink.h", + "platform/modules/mediastream/web_platform_media_stream_source.h", "platform/modules/mediastream/web_platform_media_stream_track.h", "platform/modules/notifications/web_notification_action.h", "platform/modules/notifications/web_notification_constants.h",
diff --git a/third_party/blink/public/mojom/portal/portal.mojom b/third_party/blink/public/mojom/portal/portal.mojom index d30fb83..3902465 100644 --- a/third_party/blink/public/mojom/portal/portal.mojom +++ b/third_party/blink/public/mojom/portal/portal.mojom
@@ -7,18 +7,11 @@ import "mojo/public/mojom/base/unguessable_token.mojom"; import "url/mojom/url.mojom"; -enum PortalActivationStatus { - // Portal has been successfully activated. - kSuccess, - // Operation is not supported by the embedder. - kNotSupported, -}; - // The Portal interface is used by the renderer to interact with the Portal. interface Portal { // Navigates the portal to |url|. Navigate(url.mojom.Url url); // When a portal is activated, it'll replace the current tab with the portal. - Activate() => (PortalActivationStatus result); + Activate() => (); };
diff --git a/third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h b/third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h index 4ec1c65..4cfa28e 100644 --- a/third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h +++ b/third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h
@@ -13,7 +13,7 @@ #include "base/memory/weak_ptr.h" #include "media/base/limits.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_deliverer.h" -#include "third_party/blink/public/platform/modules/mediastream/platform_media_stream_source.h" +#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h" #include "third_party/blink/public/platform/web_common.h" #include "third_party/blink/public/platform/web_media_stream_source.h" #include "third_party/blink/public/platform/web_media_stream_track.h"
diff --git a/third_party/blink/public/platform/modules/mediastream/platform_media_stream_source.h b/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h similarity index 93% rename from third_party/blink/public/platform/modules/mediastream/platform_media_stream_source.h rename to third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h index 44b2882e..5dcf040 100644 --- a/third_party/blink/public/platform/modules/mediastream/platform_media_stream_source.h +++ b/third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.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 THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_PLATFORM_MEDIA_STREAM_SOURCE_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_PLATFORM_MEDIA_STREAM_SOURCE_H_ +#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_WEB_PLATFORM_MEDIA_STREAM_SOURCE_H_ +#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_WEB_PLATFORM_MEDIA_STREAM_SOURCE_H_ #include "base/callback.h" #include "third_party/blink/public/common/mediastream/media_stream_request.h" @@ -98,4 +98,4 @@ } // namespace blink -#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_PLATFORM_MEDIA_STREAM_SOURCE_H_ +#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIASTREAM_WEB_PLATFORM_MEDIA_STREAM_SOURCE_H_
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h index bfc4a95f..95b87461 100644 --- a/third_party/blink/public/platform/platform.h +++ b/third_party/blink/public/platform/platform.h
@@ -429,18 +429,6 @@ // DEPRECATED: Use Thread::CreateThread() instead. std::unique_ptr<Thread> CreateThread(const ThreadCreationParams&); - // DEPRECATED: Use Thread::CreateWebAudioThread() instead. - std::unique_ptr<Thread> CreateWebAudioThread(); - - // DEPRECATED: Use Thread::Current() instead. - Thread* CurrentThread(); - - // DEPRECATED: Use Thread::MainThread() instead. - Thread* MainThread(); - - // DEPRECATED: Use Thread::CompositorThread() instead. - Thread* CompositorThread(); - // The two compositor-related functions below are called by the embedder. // TODO(yutak): Perhaps we should move these to somewhere else?
diff --git a/third_party/blink/public/platform/web_media_stream_source.h b/third_party/blink/public/platform/web_media_stream_source.h index 773fc1c6..9ebf4aa7 100644 --- a/third_party/blink/public/platform/web_media_stream_source.h +++ b/third_party/blink/public/platform/web_media_stream_source.h
@@ -94,9 +94,6 @@ BLINK_PLATFORM_EXPORT void Initialize(const WebString& id, Type, - const WebString& name); // DEPRECATED - BLINK_PLATFORM_EXPORT void Initialize(const WebString& id, - Type, const WebString& name, bool remote); BLINK_PLATFORM_EXPORT void Reset();
diff --git a/third_party/blink/renderer/core/css/parser/css_variable_parser.cc b/third_party/blink/renderer/core/css/parser/css_variable_parser.cc index 0ebe89d..4e76b1d0 100644 --- a/third_party/blink/renderer/core/css/parser/css_variable_parser.cc +++ b/third_party/blink/renderer/core/css/parser/css_variable_parser.cc
@@ -13,12 +13,10 @@ namespace { -bool IsValidVariableReference(CSSParserTokenRange, bool); -bool IsValidEnvVariableReference(CSSParserTokenRange, bool); +bool IsValidVariableReference(CSSParserTokenRange); +bool IsValidEnvVariableReference(CSSParserTokenRange); -bool ClassifyBlock(CSSParserTokenRange range, - bool& has_references, - bool skip_variables) { +bool ClassifyBlock(CSSParserTokenRange range, bool& has_references) { size_t block_stack_size = 0; while (!range.AtEnd()) { @@ -31,13 +29,12 @@ // and used as fallbacks. switch (token.FunctionId()) { case CSSValueVar: - if (!IsValidVariableReference(range.ConsumeBlock(), skip_variables)) + if (!IsValidVariableReference(range.ConsumeBlock())) return false; // Invalid reference. has_references = true; continue; case CSSValueEnv: - if (!IsValidEnvVariableReference(range.ConsumeBlock(), - skip_variables)) + if (!IsValidEnvVariableReference(range.ConsumeBlock())) return false; // Invalid reference. has_references = true; continue; @@ -48,12 +45,6 @@ const CSSParserToken& token = range.Consume(); if (token.GetBlockType() == CSSParserToken::kBlockStart) { - // If we are an invalid function then we should skip over any variables - // this function contains. - if (token.GetType() == CSSParserTokenType::kFunctionToken && - token.FunctionId() == CSSValueInvalid) { - skip_variables = true; - } ++block_stack_size; } else if (token.GetBlockType() == CSSParserToken::kBlockEnd) { --block_stack_size; @@ -82,10 +73,8 @@ return true; } -bool IsValidVariableReference(CSSParserTokenRange range, bool skip_variables) { +bool IsValidVariableReference(CSSParserTokenRange range) { range.ConsumeWhitespace(); - if (skip_variables) - return false; if (!CSSVariableParser::IsValidVariableName( range.ConsumeIncludingWhitespace())) return false; @@ -98,14 +87,11 @@ return false; bool has_references = false; - return ClassifyBlock(range, has_references, skip_variables); + return ClassifyBlock(range, has_references); } -bool IsValidEnvVariableReference(CSSParserTokenRange range, - bool skip_variables) { +bool IsValidEnvVariableReference(CSSParserTokenRange range) { range.ConsumeWhitespace(); - if (skip_variables) - return false; if (range.ConsumeIncludingWhitespace().GetType() != CSSParserTokenType::kIdentToken) return false; @@ -118,7 +104,7 @@ return false; bool has_references = false; - return ClassifyBlock(range, has_references, skip_variables); + return ClassifyBlock(range, has_references); } CSSValueID ClassifyVariableRange(CSSParserTokenRange range, @@ -133,7 +119,7 @@ return id; } - if (ClassifyBlock(range, has_references, false /* skip_variables */)) + if (ClassifyBlock(range, has_references)) return CSSValueInternalVariableValue; return CSSValueInvalid; }
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 62a0b124..a63a29d 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -7921,6 +7921,18 @@ javascript_url_task_handle_.Cancel(); } +bool Document::IsInWebAppScope() const { + if (!GetSettings()) + return false; + + const String& web_app_scope = GetSettings()->GetWebAppScope(); + if (web_app_scope.IsNull() || web_app_scope.IsEmpty()) + return false; + + DCHECK_EQ(KURL(web_app_scope).GetString(), web_app_scope); + return Url().GetString().StartsWith(web_app_scope); +} + void Document::SendViolationReport( mojom::blink::CSPViolationParamsPtr violation_params) { std::unique_ptr<SourceLocation> source_location = SourceLocation::Create(
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index b4d0984..03078d84 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -1524,6 +1524,11 @@ void RemoveLockedDisplayLock(); int LockedDisplayLockCount() const; + // Returns whether the document is inside the scope specified in the Web App + // Manifest. If the document doesn't run in a context of a Web App or has no + // associated Web App Manifest, it will return false. + bool IsInWebAppScope() const; + protected: void DidUpdateSecurityOrigin() final;
diff --git a/third_party/blink/renderer/core/frame/ad_tracker.cc b/third_party/blink/renderer/core/frame/ad_tracker.cc index 41c3968..37ecdf7 100644 --- a/third_party/blink/renderer/core/frame/ad_tracker.cc +++ b/third_party/blink/renderer/core/frame/ad_tracker.cc
@@ -108,28 +108,25 @@ DidExecuteScript(); } -void AdTracker::WillSendRequest(ExecutionContext* execution_context, - unsigned long identifier, - DocumentLoader* loader, - ResourceRequest& request, - const ResourceResponse& redirect_response, - const FetchInitiatorInfo& initiator_info, - ResourceType resource_type) { - // If the resource is not already marked as an ad, check if the document - // loading the resource is an ad or if any executing script is an ad. - if (!request.IsAdResource() && - (IsKnownAdExecutionContext(execution_context) || IsAdScriptInStack())) { - request.SetIsAdResource(); - } +bool AdTracker::CalculateIfAdSubresource(ExecutionContext* execution_context, + const ResourceRequest& request, + ResourceType resource_type, + bool known_ad) { + // Check if the document loading the resource is an ad or if any executing + // script is an ad. + known_ad = known_ad || IsKnownAdExecutionContext(execution_context) || + IsAdScriptInStack(); // If it is a script marked as an ad and it's not in an ad context, append it // to the known ad script set. We don't need to keep track of ad scripts in ad // contexts, because any script executed inside an ad context is considered an // ad script by IsKnownAdScript. - if (resource_type == ResourceType::kScript && request.IsAdResource() && + if (resource_type == ResourceType::kScript && known_ad && !IsKnownAdExecutionContext(execution_context)) { AppendToKnownAdScripts(*execution_context, request.Url().GetString()); } + + return known_ad; } bool AdTracker::IsAdScriptInStack() {
diff --git a/third_party/blink/renderer/core/frame/ad_tracker.h b/third_party/blink/renderer/core/frame/ad_tracker.h index 544605c..b88ff12 100644 --- a/third_party/blink/renderer/core/frame/ad_tracker.h +++ b/third_party/blink/renderer/core/frame/ad_tracker.h
@@ -16,11 +16,8 @@ namespace blink { class ExecutionContext; -class DocumentLoader; class ResourceRequest; -class ResourceResponse; enum class ResourceType : uint8_t; -struct FetchInitiatorInfo; namespace probe { class CallFunction; @@ -40,19 +37,16 @@ void Will(const probe::CallFunction&); void Did(const probe::CallFunction&); - // Called when a resource request is about to be sent. This will do the - // following: - // - Mark a resource request as an ad if any executing scripts contain an ad. - // - If the marked resource is a script, also save it to keep track of all - // those script resources that have been identified as ads. + // Called when a subresource request is about to be sent or is redirected. + // Returns true if: + // - If the resource is loaded in an ad iframe + // - If ad script is in the v8 stack + // - |known_ad| is true // Virtual for testing. - virtual void WillSendRequest(ExecutionContext*, - unsigned long identifier, - DocumentLoader*, - ResourceRequest&, - const ResourceResponse& redirect_response, - const FetchInitiatorInfo&, - ResourceType); + virtual bool CalculateIfAdSubresource(ExecutionContext* execution_context, + const ResourceRequest& request, + ResourceType resource_type, + bool known_ad); // Returns true if any script in the pseudo call stack has previously been // identified as an ad resource.
diff --git a/third_party/blink/renderer/core/frame/ad_tracker_test.cc b/third_party/blink/renderer/core/frame/ad_tracker_test.cc index 8983435..d8630bf 100644 --- a/third_party/blink/renderer/core/frame/ad_tracker_test.cc +++ b/third_party/blink/renderer/core/frame/ad_tracker_test.cc
@@ -54,22 +54,20 @@ return execution_context_; } - void WillSendRequest(ExecutionContext* execution_context, - unsigned long identifier, - DocumentLoader* document_loader, - ResourceRequest& resource_request, - const ResourceResponse& redirect_response, - const FetchInitiatorInfo& fetch_initiator_info, - ResourceType resource_type) override { + bool CalculateIfAdSubresource(ExecutionContext* execution_context, + const ResourceRequest& resource_request, + ResourceType resource_type, + bool ad_request) override { if (!ad_suffix_.IsEmpty() && resource_request.Url().GetString().EndsWith(ad_suffix_)) { - resource_request.SetIsAdResource(); + ad_request = true; } - AdTracker::WillSendRequest(execution_context, identifier, document_loader, - resource_request, redirect_response, - fetch_initiator_info, resource_type); - is_ad_.insert(resource_request.Url().GetString(), - resource_request.IsAdResource()); + + ad_request = AdTracker::CalculateIfAdSubresource( + execution_context, resource_request, resource_type, ad_request); + + is_ad_.insert(resource_request.Url().GetString(), ad_request); + return ad_request; } private: @@ -385,8 +383,10 @@ TEST_F(AdTrackerSimTest, FrameLoadedWhileExecutingAdScript) { const char kAdUrl[] = "https://example.com/ad_script.js"; const char kVanillaUrl[] = "https://example.com/vanilla_page.html"; + const char kVanillaImgUrl[] = "https://example.com/vanilla_img.jpg"; SimSubresourceRequest ad_resource(kAdUrl, "text/javascript"); SimRequest vanilla_page(kVanillaUrl, "text/html"); + SimSubresourceRequest vanilla_image(kVanillaImgUrl, "image/jpeg"); ad_tracker_->SetAdSuffix("ad_script.js"); @@ -397,12 +397,14 @@ iframe.src = "vanilla_page.html"; document.body.appendChild(iframe); )SCRIPT"); - vanilla_page.Complete(""); + vanilla_page.Complete("<img src=vanilla_img.jpg></img>"); + vanilla_image.Complete(""); EXPECT_TRUE(IsKnownAdScript(&GetDocument(), kAdUrl)); EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kAdUrl)); Frame* child_frame = GetDocument().GetFrame()->Tree().FirstChild(); EXPECT_TRUE(ToLocalFrame(child_frame)->IsAdSubframe()); + EXPECT_TRUE(ad_tracker_->RequestWithUrlTaggedAsAd(kVanillaImgUrl)); } // A script tagged as an ad in one frame shouldn't cause it to be considered
diff --git a/third_party/blink/renderer/core/html/link_style.cc b/third_party/blink/renderer/core/html/link_style.cc index 4998764e..5231bd7 100644 --- a/third_party/blink/renderer/core/html/link_style.cc +++ b/third_party/blink/renderer/core/html/link_style.cc
@@ -45,7 +45,6 @@ disabled_state_(kUnset), pending_sheet_type_(kNone), loading_(false), - fired_load_(false), loaded_sheet_(false) {} LinkStyle::~LinkStyle() = default; @@ -145,12 +144,9 @@ void LinkStyle::NotifyLoadedSheetAndAllCriticalSubresources( Node::LoadedSheetErrorStatus error_status) { - if (fired_load_) - return; loaded_sheet_ = (error_status == Node::kNoErrorLoadingSubresource); if (owner_) owner_->ScheduleEvent(); - fired_load_ = true; } void LinkStyle::StartLoadingDynamicSheet() {
diff --git a/third_party/blink/renderer/core/html/link_style.h b/third_party/blink/renderer/core/html/link_style.h index 22e838ca..f8ba8b8 100644 --- a/third_party/blink/renderer/core/html/link_style.h +++ b/third_party/blink/renderer/core/html/link_style.h
@@ -79,7 +79,6 @@ PendingSheetType pending_sheet_type_; StyleEngineContext style_engine_context_; bool loading_; - bool fired_load_; bool loaded_sheet_; };
diff --git a/third_party/blink/renderer/core/html/media/autoplay_policy.cc b/third_party/blink/renderer/core/html/media/autoplay_policy.cc index 9153dd2..41583e78 100644 --- a/third_party/blink/renderer/core/html/media/autoplay_policy.cc +++ b/third_party/blink/renderer/core/html/media/autoplay_policy.cc
@@ -38,20 +38,6 @@ const char kErrorAutoplayFuncMobile[] = "play() can only be initiated by a user gesture."; -// Returns whether |document| is whitelisted for autoplay. If true, the user -// gesture lock will be initilized as false, indicating that the element is -// allowed to autoplay unmuted without user gesture. -bool IsDocumentWhitelisted(const Document& document) { - DCHECK(document.GetSettings()); - - const String& web_app_scope = document.GetSettings()->GetWebAppScope(); - if (web_app_scope.IsNull() || web_app_scope.IsEmpty()) - return false; - - DCHECK_EQ(KURL(web_app_scope).GetString(), web_app_scope); - return document.Url().GetString().StartsWith(web_app_scope); -} - // Return true if and only if the document settings specifies media playback // requires user gesture on the element. bool ComputeLockPendingUserGestureRequired(const Document& document) { @@ -79,7 +65,7 @@ if (!document.GetSettings()) return Type::kNoUserGestureRequired; - if (IsDocumentWhitelisted(document)) + if (document.IsInWebAppScope()) return Type::kNoUserGestureRequired; if (DocumentHasUserExceptionFlag(document))
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.cc b/third_party/blink/renderer/core/html/portal/html_portal_element.cc index 87081ef..ef7b239 100644 --- a/third_party/blink/renderer/core/html/portal/html_portal_element.cc +++ b/third_party/blink/renderer/core/html/portal/html_portal_element.cc
@@ -53,25 +53,15 @@ ScriptPromise promise = resolver->Promise(); if (portal_ptr_) { - portal_ptr_->Activate(WTF::Bind( - [](HTMLPortalElement* portal, ScriptPromiseResolver* resolver, - mojom::blink::PortalActivationStatus result) { - switch (result) { - case mojom::blink::PortalActivationStatus::kNotSupported: - resolver->Reject( - DOMException::Create(DOMExceptionCode::kNotSupportedError, - "Portal activation is not supported.")); - break; - - case mojom::blink::PortalActivationStatus::kSuccess: - resolver->Resolve(); - break; - - default: - NOTREACHED(); - } - }, - WrapPersistent(this), WrapPersistent(resolver))); + // The HTMLPortalElement is bound as a persistent so that it won't get + // garbage collected while there is a pending callback. This is necessary + // because the HTMLPortalElement owns the mojo interface, so if it were + // garbage collected the callback would never be called and the promise + // would never be resolved. + portal_ptr_->Activate( + WTF::Bind([](HTMLPortalElement* portal, + ScriptPromiseResolver* resolver) { resolver->Resolve(); }, + WrapPersistent(this), WrapPersistent(resolver))); } else { resolver->Reject(DOMException::Create( DOMExceptionCode::kInvalidStateError, @@ -134,4 +124,11 @@ return new LayoutIFrame(this); } +void HTMLPortalElement::AttachLayoutTree(AttachContext& context) { + HTMLFrameOwnerElement::AttachLayoutTree(context); + + if (GetLayoutEmbeddedContent() && ContentFrame()) + SetEmbeddedContentView(ContentFrame()->View()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.h b/third_party/blink/renderer/core/html/portal/html_portal_element.h index d1ac773..c08b655a 100644 --- a/third_party/blink/renderer/core/html/portal/html_portal_element.h +++ b/third_party/blink/renderer/core/html/portal/html_portal_element.h
@@ -61,6 +61,7 @@ ParsedFeaturePolicy ConstructContainerPolicy(Vector<String>*) const override { return ParsedFeaturePolicy(); } + void AttachLayoutTree(AttachContext& context) override; // Uniquely identifies the portal, this token is used by the browser process // to reference this portal when communicating with the renderer.
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 592726f..2f0d5ca 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -301,21 +301,6 @@ } } - // Our opaqueness might have changed without triggering layout. - if (diff.NeedsFullPaintInvalidation()) { - // Invalidate self. - InvalidateBackgroundObscurationStatus(); - LayoutObject* parent_to_invalidate = Parent(); - // Also invalidate up to kBackgroundObscurationTestMaxDepth parents. - // This constant corresponds to a descendant walk of the same depth; - // see ComputeBackgroundIsKnownToBeObscured. - for (unsigned i = 0; - i < kBackgroundObscurationTestMaxDepth && parent_to_invalidate; ++i) { - parent_to_invalidate->InvalidateBackgroundObscurationStatus(); - parent_to_invalidate = parent_to_invalidate->Parent(); - } - } - UpdateShapeOutsideInfoAfterStyleChange(*Style(), old_style); UpdateGridPositionAfterStyleChange(old_style); @@ -752,8 +737,6 @@ } void LayoutBox::UpdateAfterLayout() { - InvalidateBackgroundObscurationStatus(); - // Transform-origin depends on box size, so we need to update the layer // transform after layout. if (HasLayer()) { @@ -1892,7 +1875,6 @@ for (const FillLayer* layer = &StyleRef().BackgroundLayers(); layer; layer = layer->Next()) { if (layer->GetImage() && image == layer->GetImage()->Data()) { - InvalidateBackgroundObscurationStatus(); bool maybe_animated = layer->GetImage()->CachedImage() && layer->GetImage()->CachedImage()->GetImage() && @@ -1977,6 +1959,12 @@ void LayoutBox::EnsureIsReadyForPaintInvalidation() { LayoutBoxModelObject::EnsureIsReadyForPaintInvalidation(); + bool new_obscured = ComputeBackgroundIsKnownToBeObscured(); + if (BackgroundIsKnownToBeObscured() != new_obscured) { + SetBackgroundIsKnownToBeObscured(new_obscured); + SetBackgroundNeedsFullPaintInvalidation(); + } + if (MayNeedPaintInvalidationAnimatedBackgroundImage() && !BackgroundIsKnownToBeObscured()) { SetBackgroundNeedsFullPaintInvalidation();
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index d4252aa2..0d1df0c5 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -1562,6 +1562,9 @@ LayoutUnit& min_logical_width, LayoutUnit& max_logical_width) const; + // Make it public. + using LayoutObject::BackgroundIsKnownToBeObscured; + protected: ~LayoutBox() override; @@ -1590,13 +1593,11 @@ // Returns false if it could not cheaply compute the extent (e.g. fixed // background), in which case the returned rect may be incorrect. - // FIXME: make this a const method once the LayoutBox reference in BoxPainter - // is const. bool GetBackgroundPaintedExtent(LayoutRect&) const; virtual bool ForegroundIsKnownToBeOpaqueInRect( const LayoutRect& local_rect, unsigned max_depth_to_test) const; - bool ComputeBackgroundIsKnownToBeObscured() const override; + virtual bool ComputeBackgroundIsKnownToBeObscured() const; virtual void ComputePositionedLogicalWidth( LogicalExtentComputedValues&) const;
diff --git a/third_party/blink/renderer/core/layout/layout_box_test.cc b/third_party/blink/renderer/core/layout/layout_box_test.cc index 13af1a91..f9cc589 100644 --- a/third_party/blink/renderer/core/layout/layout_box_test.cc +++ b/third_party/blink/renderer/core/layout/layout_box_test.cc
@@ -39,9 +39,8 @@ <div class='column'> <div> <div id='target' class='white-background'> <div class='black-background'></div> </div> </div> </div> )HTML"); - LayoutObject* layout_object = GetLayoutObjectByElementId("target"); - ASSERT_TRUE(layout_object); - ASSERT_TRUE(layout_object->BackgroundIsKnownToBeObscured()); + const auto* target = GetLayoutBoxByElementId("target"); + EXPECT_TRUE(target->BackgroundIsKnownToBeObscured()); } TEST_P(LayoutBoxTest, BackgroundNotObscuredWithCssClippedChild) { @@ -66,10 +65,10 @@ <div id="child"></div> </div> )HTML"); - auto* child = GetLayoutObjectByElementId("child"); + auto* child = GetLayoutBoxByElementId("child"); EXPECT_FALSE(child->BackgroundIsKnownToBeObscured()); - auto* parent = GetLayoutObjectByElementId("parent"); + auto* parent = GetLayoutBoxByElementId("parent"); EXPECT_FALSE(parent->BackgroundIsKnownToBeObscured()); } @@ -102,13 +101,13 @@ </div> </div> )HTML"); - auto* grandchild = GetLayoutObjectByElementId("grandchild"); + auto* grandchild = GetLayoutBoxByElementId("grandchild"); EXPECT_FALSE(grandchild->BackgroundIsKnownToBeObscured()); - auto* child = GetLayoutObjectByElementId("child"); + auto* child = GetLayoutBoxByElementId("child"); EXPECT_FALSE(child->BackgroundIsKnownToBeObscured()); - auto* parent = GetLayoutObjectByElementId("parent"); + auto* parent = GetLayoutBoxByElementId("parent"); EXPECT_FALSE(parent->BackgroundIsKnownToBeObscured()); }
diff --git a/third_party/blink/renderer/core/layout/layout_image.cc b/third_party/blink/renderer/core/layout/layout_image.cc index 23fab7d45..4448000a8 100644 --- a/third_party/blink/renderer/core/layout/layout_image.cc +++ b/third_party/blink/renderer/core/layout/layout_image.cc
@@ -278,8 +278,6 @@ if (DocumentBeingDestroyed()) return; - InvalidateBackgroundObscurationStatus(); - // Check for optimized image policies. if (IsHTMLImageElement(GetNode())) ValidateImagePolicies();
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index 6128199..29f9392 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -901,8 +901,6 @@ return bitfields_.HasBoxDecorationBackground(); } - bool BackgroundIsKnownToBeObscured() const; - bool NeedsLayout() const { return bitfields_.SelfNeedsLayout() || bitfields_.NormalChildNeedsLayout() || @@ -1208,14 +1206,6 @@ void SetHasBoxDecorationBackground(bool); - enum BackgroundObscurationState { - kBackgroundObscurationStatusInvalid, - kBackgroundKnownToBeObscured, - kBackgroundMayBeVisible, - }; - void InvalidateBackgroundObscurationStatus(); - virtual bool ComputeBackgroundIsKnownToBeObscured() const { return false; } - void SetIsText() { bitfields_.SetIsText(true); } void SetIsBox() { bitfields_.SetIsBox(true); } void SetIsAtomicInlineLevel(bool is_atomic_inline_level) { @@ -2018,9 +2008,6 @@ layout_object_.fragment_.SetSelectionVisualRect(r); } - void SetPreviousBackgroundObscured(bool b) { - layout_object_.bitfields_.SetPreviousBackgroundObscured(b); - } void SetPreviousBackgroundPaintLocation(BackgroundPaintLocation location) { layout_object_.bitfields_.SetPreviousBackgroundPaintLocation(location); } @@ -2134,9 +2121,6 @@ bool CompositedScrollsWithRespectTo( const LayoutBoxModelObject& paint_invalidation_container) const; - bool PreviousBackgroundObscured() const { - return bitfields_.PreviousBackgroundObscured(); - } BackgroundPaintLocation PreviousBackgroundPaintLocation() const { return bitfields_.PreviousBackgroundPaintLocation(); } @@ -2401,6 +2385,17 @@ return ToElement(GetNode())->GetDisplayLockContext(); } + bool BackgroundIsKnownToBeObscured() const { + DCHECK_GE(GetDocument().Lifecycle().GetState(), + DocumentLifecycle::kInPrePaint); + return bitfields_.BackgroundIsKnownToBeObscured(); + } + void SetBackgroundIsKnownToBeObscured(bool b) { + DCHECK_EQ(GetDocument().Lifecycle().GetState(), + DocumentLifecycle::kInPrePaint); + bitfields_.SetBackgroundIsKnownToBeObscured(b); + } + private: // Used only by applyFirstLineChanges to get a first line style based off of a // given new style, without accessing the cache. @@ -2588,7 +2583,7 @@ children_inline_(false), contains_inline_with_outline_and_continuation_(false), always_create_line_boxes_for_layout_inline_(false), - previous_background_obscured_(false), + background_is_known_to_be_obscured_(false), is_background_attachment_fixed_object_(false), is_scroll_anchor_object_(false), scroll_anchor_disabling_style_changed_(false), @@ -2605,7 +2600,6 @@ pending_update_first_line_image_observers_(false), positioned_state_(kIsStaticallyPositioned), selection_state_(static_cast<unsigned>(SelectionState::kNone)), - background_obscuration_state_(kBackgroundObscurationStatusInvalid), subtree_paint_property_update_reasons_( static_cast<unsigned>(SubtreePaintPropertyUpdateReason::kNone)), previous_background_paint_location_(0) {} @@ -2783,9 +2777,10 @@ ADD_BOOLEAN_BITFIELD(always_create_line_boxes_for_layout_inline_, AlwaysCreateLineBoxesForLayoutInline); - // Background obscuration status of the previous frame. - ADD_BOOLEAN_BITFIELD(previous_background_obscured_, - PreviousBackgroundObscured); + // For LayoutBox to cache the result of LayoutBox:: + // ComputeBackgroundIsKnownToBeObscured(). It's updated during PrePaint. + ADD_BOOLEAN_BITFIELD(background_is_known_to_be_obscured_, + BackgroundIsKnownToBeObscured); ADD_BOOLEAN_BITFIELD(is_background_attachment_fixed_object_, IsBackgroundAttachmentFixedObject); @@ -2850,9 +2845,6 @@ // (see ComputedStyle::position). unsigned positioned_state_ : 2; // PositionedState unsigned selection_state_ : 3; // SelectionState - // Mutable for getter which lazily update this field. - mutable unsigned - background_obscuration_state_ : 2; // BackgroundObscurationState // Reasons for the full subtree invalidation. unsigned subtree_paint_property_update_reasons_ @@ -2926,16 +2918,6 @@ static_cast<unsigned>(SubtreePaintPropertyUpdateReason::kNone); } - ALWAYS_INLINE BackgroundObscurationState - GetBackgroundObscurationState() const { - return static_cast<BackgroundObscurationState>( - background_obscuration_state_); - } - ALWAYS_INLINE void SetBackgroundObscurationState( - BackgroundObscurationState s) const { - background_obscuration_state_ = s; - } - ALWAYS_INLINE BackgroundPaintLocation PreviousBackgroundPaintLocation() const { return static_cast<BackgroundPaintLocation>( @@ -3098,24 +3080,6 @@ return; bitfields_.SetHasBoxDecorationBackground(b); - InvalidateBackgroundObscurationStatus(); -} - -inline void LayoutObject::InvalidateBackgroundObscurationStatus() { - bitfields_.SetBackgroundObscurationState(kBackgroundObscurationStatusInvalid); -} - -DISABLE_CFI_PERF -inline bool LayoutObject::BackgroundIsKnownToBeObscured() const { - if (bitfields_.GetBackgroundObscurationState() == - kBackgroundObscurationStatusInvalid) { - BackgroundObscurationState state = ComputeBackgroundIsKnownToBeObscured() - ? kBackgroundKnownToBeObscured - : kBackgroundMayBeVisible; - bitfields_.SetBackgroundObscurationState(state); - } - return bitfields_.GetBackgroundObscurationState() == - kBackgroundKnownToBeObscured; } inline void MakeMatrixRenderable(TransformationMatrix& matrix,
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context.cc b/third_party/blink/renderer/core/loader/base_fetch_context.cc index 8eb50a3..5a7fa1cb 100644 --- a/third_party/blink/renderer/core/loader/base_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/base_fetch_context.cc
@@ -181,17 +181,15 @@ return blocked_reason; } -bool BaseFetchContext::IsAdResource( - const KURL& resource_url, - ResourceType type, - mojom::RequestContextType request_context) const { +bool BaseFetchContext::CalculateIfAdSubresource(const ResourceRequest& request, + ResourceType type) { + // A base class should override this is they have more signals than just the + // SubresourceFilter. SubresourceFilter* filter = GetSubresourceFilter(); - // We do not need main document tagging currently so skipping main resources. - if (filter) - return filter->IsAdResource(resource_url, request_context); - - return false; + return request.IsAdResource() || + (filter && + filter->IsAdResource(request.Url(), request.GetRequestContext())); } void BaseFetchContext::PrintAccessDeniedMessage(const KURL& url) const {
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context.h b/third_party/blink/renderer/core/loader/base_fetch_context.h index 4e69f48..39b9cd6 100644 --- a/third_party/blink/renderer/core/loader/base_fetch_context.h +++ b/third_party/blink/renderer/core/loader/base_fetch_context.h
@@ -54,9 +54,8 @@ virtual std::unique_ptr<WebSocketHandshakeThrottle> CreateWebSocketHandshakeThrottle() = 0; - bool IsAdResource(const KURL&, - ResourceType, - mojom::RequestContextType) const override; + bool CalculateIfAdSubresource(const ResourceRequest& resource_request, + ResourceType type) override; protected: BaseFetchContext() = default;
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc index ed513ac..1eca168 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -55,6 +55,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/fileapi/public_url_manager.h" +#include "third_party/blink/renderer/core/frame/ad_tracker.h" #include "third_party/blink/renderer/core/frame/deprecation.h" #include "third_party/blink/renderer/core/frame/frame_console.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" @@ -1254,6 +1255,24 @@ return ResourceLoadPriority::kLowest; } +bool FrameFetchContext::CalculateIfAdSubresource( + const ResourceRequest& resource_request, + ResourceType type) { + // Mark the resource as an Ad if the SubresourceFilter thinks it's an ad. + bool known_ad = + BaseFetchContext::CalculateIfAdSubresource(resource_request, type); + if (GetResourceFetcherProperties().IsDetached() || + !GetFrame()->GetAdTracker()) { + return known_ad; + } + + // The AdTracker needs to know about the request as well, and may also mark it + // as an ad. + return GetFrame()->GetAdTracker()->CalculateIfAdSubresource( + frame_or_imported_document_->GetDocument(), resource_request, type, + known_ad); +} + void FrameFetchContext::DispatchNetworkQuiet() { if (WebServiceWorkerNetworkProvider* service_worker_network_provider = MasterDocumentLoader()->GetServiceWorkerNetworkProvider()) {
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.h b/third_party/blink/renderer/core/loader/frame_fetch_context.h index 550402e..93a0759 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.h +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.h
@@ -146,6 +146,10 @@ ResourceLoadPriority ModifyPriorityForExperiments( ResourceLoadPriority) const override; + + bool CalculateIfAdSubresource(const ResourceRequest& resource_request, + ResourceType type) override; + void DispatchNetworkQuiet() override; private:
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc index 6ed04e5..b82a96a4 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
@@ -228,10 +228,9 @@ bool expect_is_ad) { base::Optional<ResourceRequestBlockedReason> reason = CanRequestInternal(SecurityViolationReportingPolicy::kReport); - const KURL url("http://example.com/"); - EXPECT_EQ(expect_is_ad, GetFetchContext()->IsAdResource( - url, ResourceType::kMock, - mojom::RequestContextType::UNSPECIFIED)); + ResourceRequest request(KURL("http://example.com/")); + EXPECT_EQ(expect_is_ad, GetFetchContext()->CalculateIfAdSubresource( + request, ResourceType::kMock)); return reason; }
diff --git a/third_party/blink/renderer/core/paint/object_paint_invalidator.cc b/third_party/blink/renderer/core/paint/object_paint_invalidator.cc index e5cff41..b65003b 100644 --- a/third_party/blink/renderer/core/paint/object_paint_invalidator.cc +++ b/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
@@ -218,21 +218,12 @@ ObjectPaintInvalidatorWithContext::ComputePaintInvalidationReason() { // This is before any early return to ensure the background obscuration status // is saved. - bool background_obscuration_changed = false; - bool background_obscured = object_.BackgroundIsKnownToBeObscured(); - if (background_obscured != object_.PreviousBackgroundObscured()) { - object_.GetMutableForPainting().SetPreviousBackgroundObscured( - background_obscured); - background_obscuration_changed = true; - } - if (!object_.ShouldCheckForPaintInvalidation() && (!context_.subtree_flags || context_.subtree_flags == PaintInvalidatorContext::kSubtreeVisualRectUpdate)) { // No paint invalidation flag, or just kSubtreeVisualRectUpdate (which has // been handled in PaintInvalidator). No paint invalidation is needed. - DCHECK(!background_obscuration_changed); return PaintInvalidationReason::kNone; } @@ -249,9 +240,6 @@ context_.fragment_data->VisualRect().IsEmpty()) return PaintInvalidationReason::kNone; - if (background_obscuration_changed) - return PaintInvalidationReason::kBackground; - if (object_.PaintedOutputOfObjectHasNoEffectRegardlessOfSize()) return PaintInvalidationReason::kNone;
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 2ea7bcc1..53f6548f 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -1034,7 +1034,9 @@ if (&fragment_data_ != &object_.FirstFragment()) { // All fragments share the same LinkHighlightEffect node. DCHECK(object_.FirstFragment().PaintProperties()); - DCHECK(object_.FirstFragment().PaintProperties()->LinkHighlightEffect()); + // TODO(crbug.com/923729): Temporary CHECK to debug the referenced bug. This + // should become a DCHECK once the bug is resolved. + CHECK(object_.FirstFragment().PaintProperties()->LinkHighlightEffect()); properties_->SetLinkHighlightEffect( object_.FirstFragment().PaintProperties()->LinkHighlightEffect()); return;
diff --git a/third_party/blink/renderer/core/probe/core_probes.json5 b/third_party/blink/renderer/core/probe/core_probes.json5 index 56e4adf..b76043c 100644 --- a/third_party/blink/renderer/core/probe/core_probes.json5 +++ b/third_party/blink/renderer/core/probe/core_probes.json5
@@ -20,7 +20,6 @@ probes: [ "CallFunction", "ExecuteScript", - "willSendRequest", ] }, InspectorAnimationAgent: {
diff --git a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc index f5d29f9b..3039b1c 100644 --- a/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc +++ b/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc
@@ -242,7 +242,6 @@ DCHECK(GetSupplementable()); // Auto Picture-in-Picture is allowed only in a PWA window. - // TODO(crbug.com/922884) It should apply in the scope of the manifest. if (!GetSupplementable()->GetFrame() || !GetSupplementable()->GetFrame()->View() || GetSupplementable()->GetFrame()->View()->DisplayMode() == @@ -250,6 +249,10 @@ return; } + // Auto Picture-in-Picture is allowed only in the scope of a PWA. + if (!GetSupplementable()->IsInWebAppScope()) + return; + // If page becomes visible and Picture-in-Picture element has entered // automatically Picture-in-Picture and is still eligible to Auto // Picture-in-Picture, exit Picture-in-Picture.
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 09f9eea..ee98ccd2 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -505,10 +505,11 @@ "drag_image.h", "exported/file_path_conversion.cc", "exported/interface_registry.cc", - "exported/media_stream_audio_source.cc", - "exported/media_stream_audio_track.cc", + "exported/mediastream/media_stream_audio_source.cc", + "exported/mediastream/media_stream_audio_track.cc", + "exported/mediastream/web_platform_media_stream_source.cc", + "exported/mediastream/web_platform_media_stream_track.cc", "exported/platform.cc", - "exported/platform_media_stream_source.cc", "exported/service_registry.cc", "exported/url_conversion.cc", "exported/web_audio_bus.cc", @@ -554,7 +555,6 @@ "exported/web_memory_coordinator.cc", "exported/web_mixed_content.cc", "exported/web_network_state_notifier.cc", - "exported/web_platform_media_stream_track.cc", "exported/web_prerender.cc", "exported/web_prerendering_support.cc", "exported/web_rtc_answer_options.cc",
diff --git a/third_party/blink/renderer/platform/exported/DEPS b/third_party/blink/renderer/platform/exported/DEPS index 3ab3617..53f699c 100644 --- a/third_party/blink/renderer/platform/exported/DEPS +++ b/third_party/blink/renderer/platform/exported/DEPS
@@ -1,6 +1,5 @@ include_rules = [ - "+media/base/audio_bus.h", "+net/cookies/canonical_cookie.h", "+net/cookies/cookie_constants.h", ]
diff --git a/third_party/blink/renderer/platform/exported/mediastream/DEPS b/third_party/blink/renderer/platform/exported/mediastream/DEPS new file mode 100644 index 0000000..36f8289a --- /dev/null +++ b/third_party/blink/renderer/platform/exported/mediastream/DEPS
@@ -0,0 +1,4 @@ + +include_rules = [ + "+media/base/audio_bus.h", +]
diff --git a/third_party/blink/renderer/platform/exported/media_stream_audio_source.cc b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc similarity index 100% rename from third_party/blink/renderer/platform/exported/media_stream_audio_source.cc rename to third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc
diff --git a/third_party/blink/renderer/platform/exported/media_stream_audio_track.cc b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_track.cc similarity index 100% rename from third_party/blink/renderer/platform/exported/media_stream_audio_track.cc rename to third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_track.cc
diff --git a/third_party/blink/renderer/platform/exported/platform_media_stream_source.cc b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc similarity index 98% rename from third_party/blink/renderer/platform/exported/platform_media_stream_source.cc rename to third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc index 343a7a8..817da4ff 100644 --- a/third_party/blink/renderer/platform/exported/platform_media_stream_source.cc +++ b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.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 "third_party/blink/public/platform/modules/mediastream/platform_media_stream_source.h" +#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
diff --git a/third_party/blink/renderer/platform/exported/web_platform_media_stream_track.cc b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_track.cc similarity index 100% rename from third_party/blink/renderer/platform/exported/web_platform_media_stream_track.cc rename to third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_track.cc
diff --git a/third_party/blink/renderer/platform/exported/platform.cc b/third_party/blink/renderer/platform/exported/platform.cc index 63703db..20b35af 100644 --- a/third_party/blink/renderer/platform/exported/platform.cc +++ b/third_party/blink/renderer/platform/exported/platform.cc
@@ -250,14 +250,6 @@ return g_platform; } -Thread* Platform::MainThread() { - return Thread::MainThread(); -} - -Thread* Platform::CurrentThread() { - return Thread::Current(); -} - service_manager::Connector* Platform::GetConnector() { DEFINE_STATIC_LOCAL(DefaultConnector, connector, ()); return connector.Get(); @@ -281,21 +273,13 @@ return Thread::CreateThread(params); } -std::unique_ptr<Thread> Platform::CreateWebAudioThread() { - return Thread::CreateWebAudioThread(); -} - void Platform::CreateAndSetCompositorThread() { Thread::CreateAndSetCompositorThread(); } -Thread* Platform::CompositorThread() { - return Thread::CompositorThread(); -} - scoped_refptr<base::SingleThreadTaskRunner> Platform::CompositorThreadTaskRunner() { - if (Thread* compositor_thread = CompositorThread()) + if (Thread* compositor_thread = Thread::CompositorThread()) return compositor_thread->GetTaskRunner(); return nullptr; }
diff --git a/third_party/blink/renderer/platform/exported/web_media_stream_source.cc b/third_party/blink/renderer/platform/exported/web_media_stream_source.cc index d45ddd5f..396ba52 100644 --- a/third_party/blink/renderer/platform/exported/web_media_stream_source.cc +++ b/third_party/blink/renderer/platform/exported/web_media_stream_source.cc
@@ -67,13 +67,6 @@ void WebMediaStreamSource::Initialize(const WebString& id, Type type, - const WebString& name) { - private_ = MediaStreamSource::Create( - id, static_cast<MediaStreamSource::StreamType>(type), name, false); -} - -void WebMediaStreamSource::Initialize(const WebString& id, - Type type, const WebString& name, bool remote) { private_ = MediaStreamSource::Create(
diff --git a/third_party/blink/renderer/platform/fonts/font_global_context.cc b/third_party/blink/renderer/platform/fonts/font_global_context.cc index ae6358c..20f6dd7 100644 --- a/third_party/blink/renderer/platform/fonts/font_global_context.cc +++ b/third_party/blink/renderer/platform/fonts/font_global_context.cc
@@ -38,9 +38,4 @@ GetFontCache().Invalidate(); } -void FontGlobalContext::ClearForTesting() { - FontGlobalContext* ctx = Get(); - ctx->font_cache_.Invalidate(); -} - } // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/font_global_context.h b/third_party/blink/renderer/platform/fonts/font_global_context.h index 4dcb928..7cd6a0b 100644 --- a/third_party/blink/renderer/platform/fonts/font_global_context.h +++ b/third_party/blink/renderer/platform/fonts/font_global_context.h
@@ -46,8 +46,6 @@ // Called by MemoryCoordinator to clear memory. static void ClearMemory(); - static void ClearForTesting(); - private: friend class WTF::ThreadSpecific<FontGlobalContext>;
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc b/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc index c6db1e5..e86ae5b 100644 --- a/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc +++ b/third_party/blink/renderer/platform/graphics/paint/paint_chunker.cc
@@ -28,6 +28,17 @@ void PaintChunker::UpdateCurrentPaintChunkProperties( const base::Optional<PaintChunk::Id>& chunk_id, const PropertyTreeState& properties) { + // TODO(crbug.com/923729): This is a temporary set of checks to determine the + // cause of the referenced bug. At this point we should have all of the + // properties given to us. Note that scoped objects that restore previous + // properties might put us back into uninitialized properties state, but if + // we're not being set to uninitialized then we must have all properties set. + if (properties != UninitializedProperties()) { + CHECK(properties.Transform()); + CHECK(properties.Clip()); + CHECK(properties.Effect()); + } + // If properties are the same, continue to use the previously set // |next_chunk_id_| because the id of the outer painting is likely to be // more stable to reduce invalidation because of chunk id changes.
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc index 07cd4f3..f070dd5 100644 --- a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc +++ b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
@@ -15,6 +15,7 @@ #include "media/base/video_frame.h" #include "media/base/video_types.h" #include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h" +#include "services/viz/public/interfaces/hit_test/hit_test_region_list.mojom-blink.h" #include "services/ws/public/cpp/gpu/context_provider_command_buffer.h" #include "third_party/blink/public/platform/interface_provider.h" #include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.h"
diff --git a/third_party/blink/renderer/platform/loader/fetch/fetch_context.h b/third_party/blink/renderer/platform/loader/fetch/fetch_context.h index 4f2fa79..3fe67b4 100644 --- a/third_party/blink/renderer/platform/loader/fetch/fetch_context.h +++ b/third_party/blink/renderer/platform/loader/fetch/fetch_context.h
@@ -226,10 +226,10 @@ return priority; } - // Returns if the |resource_url| is identified as ad. - virtual bool IsAdResource(const KURL& resource_url, - ResourceType type, - mojom::RequestContextType request_context) const { + // Determine if the request is on behalf of an advertisement. If so, return + // true. + virtual bool CalculateIfAdSubresource(const ResourceRequest& resource_request, + ResourceType type) { return false; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index 0957ba4..4e16af2 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -819,10 +819,8 @@ reporting_policy, resource_request.GetRedirectStatus()); - if (Context().IsAdResource(url, resource_type, - resource_request.GetRequestContext())) { + if (Context().CalculateIfAdSubresource(resource_request, resource_type)) resource_request.SetIsAdResource(); - } if (blocked_reason) return blocked_reason;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 27c3a1b..0253184e 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -639,10 +639,8 @@ resource_type, *new_request, new_url, options, reporting_policy, ResourceRequest::RedirectStatus::kFollowedRedirect); - if (Context().IsAdResource(new_url, resource_type, - new_request->GetRequestContext())) { + if (Context().CalculateIfAdSubresource(*new_request, resource_type)) new_request->SetIsAdResource(); - } if (blocked_reason) { CancelForRedirectAccessCheckError(new_url, blocked_reason.value());
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_source.h b/third_party/blink/renderer/platform/mediastream/media_stream_source.h index e48d994..5071f3a 100644 --- a/third_party/blink/renderer/platform/mediastream/media_stream_source.h +++ b/third_party/blink/renderer/platform/mediastream/media_stream_source.h
@@ -36,7 +36,7 @@ #include <utility> #include "base/optional.h" -#include "third_party/blink/public/platform/modules/mediastream/platform_media_stream_source.h" +#include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h" #include "third_party/blink/public/platform/web_media_constraints.h" #include "third_party/blink/public/platform/web_media_stream_source.h" #include "third_party/blink/public/platform/web_media_stream_track.h"
diff --git a/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc b/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc index 3f8852f..f32cb5a 100644 --- a/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc +++ b/third_party/blink/renderer/platform/transforms/rotate_transform_operation.cc
@@ -48,9 +48,6 @@ const TransformOperation* from, double progress, bool blend_to_identity) { - if (from && !from->IsSameType(*this)) - return this; - if (blend_to_identity) return RotateTransformOperation::Create( Rotation(Axis(), Angle() * (1 - progress)), type_); @@ -60,17 +57,18 @@ return RotateTransformOperation::Create( Rotation(Axis(), Angle() * progress), type_); + // Apply spherical linear interpolation. Rotate around a common axis if + // possible. Otherwise, convert rotations to 4x4 matrix representations and + // interpolate the matrix decompositions. The 'from' and 'to' transforms can + // be of different types (based on axis), but must both have equivalent + // rotate3d representations. + DCHECK(from->PrimitiveType() == OperationType::kRotate3D); + OperationType type = + from->IsSameType(*this) ? type_ : OperationType::kRotate3D; const RotateTransformOperation& from_rotate = ToRotateTransformOperation(*from); - if (GetType() == kRotate3D) { - return RotateTransformOperation::Create( - Rotation::Slerp(from_rotate.rotation_, rotation_, progress), kRotate3D); - } - - DCHECK(Axis() == from_rotate.Axis()); return RotateTransformOperation::Create( - Rotation(Axis(), blink::Blend(from_rotate.Angle(), Angle(), progress)), - type_); + Rotation::Slerp(from_rotate.rotation_, rotation_, progress), type); } bool RotateTransformOperation::CanBlendWith(
diff --git a/third_party/blink/renderer/platform/transforms/transform_operations.cc b/third_party/blink/renderer/platform/transforms/transform_operations.cc index 7149321..b511af3 100644 --- a/third_party/blink/renderer/platform/transforms/transform_operations.cc +++ b/third_party/blink/renderer/platform/transforms/transform_operations.cc
@@ -202,7 +202,7 @@ if (axis.Dot(to_transform.Axis()) < 0) to_degrees *= -1; - from_degrees = Blend(from_degrees, to_transform.Angle(), min_progress); + from_degrees = Blend(from_degrees, to_degrees, min_progress); to_degrees = Blend(to_degrees, from_transform.Angle(), 1.0 - max_progress); if (from_degrees > to_degrees) std::swap(from_degrees, to_degrees);
diff --git a/third_party/blink/renderer/platform/transforms/transform_operations_test.cc b/third_party/blink/renderer/platform/transforms/transform_operations_test.cc index 288d83c..95c6800 100644 --- a/third_party/blink/renderer/platform/transforms/transform_operations_test.cc +++ b/third_party/blink/renderer/platform/transforms/transform_operations_test.cc
@@ -297,7 +297,7 @@ }; TEST(TransformOperationsTest, AbsoluteAnimatedProblematicAxisRotationBounds) { - // Zeros in the components of the axis osf rotation turned out to be tricky to + // Zeros in the components of the axis of rotation turned out to be tricky to // deal with in practice. This function tests some potentially problematic // axes to ensure sane behavior.
diff --git a/third_party/blink/renderer/platform/wtf/std_lib_extras.h b/third_party/blink/renderer/platform/wtf/std_lib_extras.h index 94f9924f..4c5bf0e 100644 --- a/third_party/blink/renderer/platform/wtf/std_lib_extras.h +++ b/third_party/blink/renderer/platform/wtf/std_lib_extras.h
@@ -96,7 +96,7 @@ #if DCHECK_IS_ON() , safely_initialized_(WTF::IsBeforeThreadCreated()), - thread_(WTF::internal::CurrentThreadSyscall()) + thread_(WTF::CurrentThread()) #endif { static_assert(!WTF::IsGarbageCollectedType<Type>::value, @@ -122,7 +122,7 @@ // keeps being called on the same thread if cross-thread // use is not permitted. return allow_cross_thread_use || safely_initialized_ || - thread_ == WTF::internal::CurrentThreadSyscall(); + thread_ == WTF::CurrentThread(); } #endif template <typename T, bool is_small = sizeof(T) <= 32>
diff --git a/third_party/blink/renderer/platform/wtf/threading.cc b/third_party/blink/renderer/platform/wtf/threading.cc index 4728e5e..51dd1b47 100644 --- a/third_party/blink/renderer/platform/wtf/threading.cc +++ b/third_party/blink/renderer/platform/wtf/threading.cc
@@ -5,102 +5,12 @@ #include "third_party/blink/renderer/platform/wtf/threading.h" #include "build/build_config.h" -#include "third_party/blink/renderer/platform/wtf/date_math.h" -#include "third_party/blink/renderer/platform/wtf/dtoa/double-conversion.h" -#include "third_party/blink/renderer/platform/wtf/wtf_thread_data.h" - -#if defined(OS_WIN) -#include <windows.h> -#elif defined(OS_POSIX) || defined(OS_FUCHSIA) -#include <pthread.h> -#else -#error Blink does not support threading on your platform. -#endif - -#if defined(OS_LINUX) -#include <sys/syscall.h> -#elif defined(OS_ANDROID) -#include <sys/types.h> -#endif namespace WTF { -// Current thread identity - -namespace internal { - -ThreadIdentifier CurrentThreadSyscall() { -#if defined(OS_WIN) - return static_cast<ThreadIdentifier>(GetCurrentThreadId()); -#elif defined(OS_MACOSX) - return pthread_mach_thread_np(pthread_self()); -#elif defined(OS_LINUX) - return syscall(__NR_gettid); -#elif defined(OS_ANDROID) - return gettid(); -#else - return reinterpret_cast<uintptr_t>(pthread_self()); -#endif -} - -} // namespace internal - -namespace { -bool g_current_thread_key_initialized = false; - -#if defined(OS_WIN) -DWORD g_current_thread_key; -void RawCurrentThreadInit() { - g_current_thread_key = ::TlsAlloc(); - CHECK_NE(g_current_thread_key, TLS_OUT_OF_INDEXES); -} -void* RawCurrentThreadGet() { - return ::TlsGetValue(g_current_thread_key); -} -void RawCurrentThreadSet(void* value) { - ::TlsSetValue(g_current_thread_key, value); -} -#elif defined(OS_POSIX) || defined(OS_FUCHSIA) -pthread_key_t g_current_thread_key; -void RawCurrentThreadInit() { - int error = pthread_key_create(&g_current_thread_key, nullptr); - CHECK(!error); -} -void* RawCurrentThreadGet() { - return pthread_getspecific(g_current_thread_key); -} -void RawCurrentThreadSet(void* value) { - pthread_setspecific(g_current_thread_key, value); -} -#endif -} // namespace - -void InitializeCurrentThread() { - DCHECK(!g_current_thread_key_initialized); - RawCurrentThreadInit(); - g_current_thread_key_initialized = true; -} - ThreadIdentifier CurrentThread() { - // This doesn't use WTF::ThreadSpecific (e.g. WTFThreadData) because - // ThreadSpecific now depends on currentThread. It is necessary to avoid this - // or a similar loop: - // - // CurrentThread - // -> WtfThreadData - // -> ThreadSpecific::operator* - // -> IsMainThread - // -> CurrentThread - static_assert(sizeof(ThreadIdentifier) <= sizeof(void*), - "ThreadIdentifier must fit in a void*."); - DCHECK(g_current_thread_key_initialized); - void* value = RawCurrentThreadGet(); - if (UNLIKELY(!value)) { - value = reinterpret_cast<void*>(internal::CurrentThreadSyscall()); - DCHECK(value); - RawCurrentThreadSet(value); - } - return reinterpret_cast<ThreadIdentifier>(value); + thread_local ThreadIdentifier g_id = base::PlatformThread::CurrentId(); + return g_id; } // For debugging only -- whether a non-main thread has been created.
diff --git a/third_party/blink/renderer/platform/wtf/threading.h b/third_party/blink/renderer/platform/wtf/threading.h index 61ca3d30..4f7aedac 100644 --- a/third_party/blink/renderer/platform/wtf/threading.h +++ b/third_party/blink/renderer/platform/wtf/threading.h
@@ -33,21 +33,14 @@ #include <stdint.h> #include "base/logging.h" +#include "base/threading/platform_thread.h" #include "build/build_config.h" #include "third_party/blink/renderer/platform/wtf/type_traits.h" #include "third_party/blink/renderer/platform/wtf/wtf_export.h" namespace WTF { -#if defined(OS_WIN) -typedef uint32_t ThreadIdentifier; -#else -typedef intptr_t ThreadIdentifier; -#endif - -namespace internal { -WTF_EXPORT ThreadIdentifier CurrentThreadSyscall(); -} // namespace internal +using ThreadIdentifier = base::PlatformThreadId; // Initializes global state required by |currentThread|. // Needs to be called once during program execution, before |currentThread|.
diff --git a/third_party/blink/renderer/platform/wtf/wtf.cc b/third_party/blink/renderer/platform/wtf/wtf.cc index 26f42da5..1d85de8b 100644 --- a/third_party/blink/renderer/platform/wtf/wtf.cc +++ b/third_party/blink/renderer/platform/wtf/wtf.cc
@@ -73,7 +73,6 @@ CHECK(!g_initialized); g_initialized = true; g_is_main_thread = true; - InitializeCurrentThread(); g_main_thread_identifier = CurrentThread(); WTFThreadData::Initialize();
diff --git a/third_party/blink/renderer/platform/wtf/wtf_thread_data.cc b/third_party/blink/renderer/platform/wtf/wtf_thread_data.cc index 91bdf2e..60ff8e2 100644 --- a/third_party/blink/renderer/platform/wtf/wtf_thread_data.cc +++ b/third_party/blink/renderer/platform/wtf/wtf_thread_data.cc
@@ -37,7 +37,7 @@ WTFThreadData::WTFThreadData() : atomic_string_table_(new AtomicStringTable), cached_converter_icu_(new ICUConverterWrapper), - thread_id_(internal::CurrentThreadSyscall()) {} + thread_id_(WTF::CurrentThread()) {} WTFThreadData::~WTFThreadData() = default;
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 6cde269..c9303fd 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -2174,8 +2174,8 @@ Bug(none) external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.sub.html [ WontFix ] Bug(none) virtual/sharedarraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.sub.html [ WontFix ] Bug(none) virtual/sharedarraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.sub.html [ WontFix ] -Bug(none) external/wpt/wasm/serialization/window-domain-success.sub.html [ WontFix ] -Bug(none) external/wpt/wasm/serialization/window-similar-but-cross-origin-success.sub.html [ WontFix ] +Bug(none) external/wpt/wasm/serialization/module/window-domain-success.sub.html [ WontFix ] +Bug(none) external/wpt/wasm/serialization/module/window-similar-but-cross-origin-success.sub.html [ WontFix ] # Code cache isolation tests only make sense if either # 1) site isolation is disabled or
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 766dc5a1..fbaee64 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -142,6 +142,7 @@ crbug.com/771003 http/tests/security/mixedContent/insecure-iframe-in-main-frame.html [ Failure ] crbug.com/771003 virtual/outofblink-cors-ns/http/tests/security/mixedContent/insecure-iframe-in-main-frame.html [ Failure ] crbug.com/771003 virtual/outofblink-cors/http/tests/security/mixedContent/insecure-iframe-in-main-frame.html [ Failure ] +crbug.com/771003 virtual/feature-policy-for-sandbox/http/tests/security/mixedContent/insecure-iframe-in-main-frame.html [ Failure ] # Tests temporarily disabled with Site Isolation - known differences in product # behavior (either accepted for the long-term, or for the short-term): @@ -153,6 +154,7 @@ crbug.com/669083 http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html [ Failure ] crbug.com/669083 virtual/outofblink-cors-ns/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html [ Failure ] crbug.com/669083 virtual/outofblink-cors/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html [ Failure ] +crbug.com/669083 virtual/feature-policy-for-sandbox/http/tests/security/frameNavigation/xss-DENIED-top-navigation-without-user-gesture.html [ Failure ] crbug.com/886588 external/wpt/dom/events/EventListener-addEventListener.sub.window.html [ Failure ] # Tests temporarily disabled with Site Isolation - uninvestigated bugs: @@ -168,6 +170,7 @@ crbug.com/793127 http/tests/security/upgrade-insecure-requests/iframe-upgrade.https.html [ Crash ] crbug.com/793127 virtual/outofblink-cors-ns/http/tests/security/upgrade-insecure-requests/iframe-upgrade.https.html [ Crash ] crbug.com/793127 virtual/outofblink-cors/http/tests/security/upgrade-insecure-requests/iframe-upgrade.https.html [ Crash ] +crbug.com/793127 virtual/feature-policy-for-sandbox/http/tests/security/upgrade-insecure-requests/iframe-upgrade.https.html [ Crash ] crbug.com/801992 http/tests/misc/iframe-script-modify-attr.html [ Pass Crash ] crbug.com/807675 http/tests/images/image-decode-in-frame.html [ Crash Failure ] crbug.com/819800 external/wpt/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html [ Failure ] @@ -2054,6 +2057,7 @@ crbug.com/518883 crbug.com/390452 http/tests/security/isolatedWorld/media-query-wrapper-leaks.html [ Failure Pass Timeout ] crbug.com/518883 crbug.com/390452 virtual/outofblink-cors/http/tests/security/isolatedWorld/media-query-wrapper-leaks.html [ Failure Pass Timeout ] crbug.com/518883 crbug.com/390452 virtual/outofblink-cors-ns/http/tests/security/isolatedWorld/media-query-wrapper-leaks.html [ Failure Pass Timeout ] +crbug.com/518883 crbug.com/390452 virtual/feature-policy-for-sandbox/http/tests/security/isolatedWorld/media-query-wrapper-leaks.html [ Failure Pass Timeout ] crbug.com/518987 http/tests/xmlhttprequest/navigation-abort-detaches-frame.html [ Pass Timeout ] crbug.com/518987 virtual/outofblink-cors/http/tests/xmlhttprequest/navigation-abort-detaches-frame.html [ Pass Timeout ] crbug.com/518987 virtual/outofblink-cors-ns/http/tests/xmlhttprequest/navigation-abort-detaches-frame.html [ Pass Timeout ] @@ -2455,6 +2459,10 @@ crbug.com/528062 [ Win ] virtual/outofblink-cors-ns/http/tests/security/contentSecurityPolicy/cached-frame-csp.html [ Failure ] crbug.com/528062 [ Win ] virtual/outofblink-cors-ns/http/tests/security/xssAuditor/cached-frame.html [ Failure ] crbug.com/528062 [ Win ] virtual/outofblink-cors-ns/http/tests/security/xssAuditor/chunked-big-script.html [ Failure ] +crbug.com/528062 [ Win ] virtual/feature-policy-for-sandbox/http/tests/security/XFrameOptions/x-frame-options-cached.html [ Failure ] +crbug.com/528062 [ Win ] virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/cached-frame-csp.html [ Failure ] +crbug.com/528062 [ Win ] virtual/feature-policy-for-sandbox/http/tests/security/xssAuditor/cached-frame.html [ Failure ] +crbug.com/528062 [ Win ] virtual/feature-policy-for-sandbox/http/tests/security/xssAuditor/chunked-big-script.html [ Failure ] # When drawing subpixel smoothed glyphs, CoreGraphics will fake bold the glyphs. # In this configuration, the pixel smoothed glyphs will be created from subpixel smoothed glyphs. @@ -2736,6 +2744,7 @@ crbug.com/501659 http/tests/security/xss-DENIED-xml-external-entity.xhtml [ Failure ] crbug.com/501659 virtual/outofblink-cors/http/tests/security/xss-DENIED-xml-external-entity.xhtml [ Failure ] crbug.com/501659 virtual/outofblink-cors-ns/http/tests/security/xss-DENIED-xml-external-entity.xhtml [ Failure ] +crbug.com/501659 virtual/feature-policy-for-sandbox/http/tests/security/xss-DENIED-xml-external-entity.xhtml [ Failure ] crbug.com/501659 fast/css/stylesheet-candidate-nodes-crash.xhtml [ Failure ] crbug.com/545140 [ Mac ] fast/encoding/denormalised-voiced-japanese-chars.html [ Failure ] @@ -2860,6 +2869,7 @@ crbug.com/763830 http/tests/security/cors-rfc1918/ [ Skip ] crbug.com/763830 virtual/outofblink-cors/http/tests/security/cors-rfc1918/ [ Skip ] crbug.com/763830 virtual/outofblink-cors-ns/http/tests/security/cors-rfc1918/ [ Skip ] +crbug.com/763830 virtual/feature-policy-for-sandbox/http/tests/security/cors-rfc1918/ [ Skip ] crbug.com/831729 external/wpt/event-timing/event-timing-crossiframe.html [ Timeout ] crbug.com/831729 external/wpt/event-timing/event-timing-observer-manual.html [ Skip ] @@ -4383,6 +4393,7 @@ crbug.com/610835 http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure Pass ] crbug.com/610835 virtual/outofblink-cors/http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure Pass ] crbug.com/610835 virtual/outofblink-cors-ns/http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure Pass ] +crbug.com/610835 virtual/feature-policy-for-sandbox/http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure Pass ] # Added 2016-12-12 crbug.com/673539 [ Linux ] css3/filters/effect-contrast-hw.html [ Pass Failure ] @@ -4527,11 +4538,11 @@ crbug.com/874302 virtual/sharedarraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success-and-failure.html [ Timeout ] crbug.com/874302 virtual/sharedarraybuffer/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/broadcastchannel-success.html [ Timeout ] -crbug.com/874302 external/wpt/wasm/serialization/broadcastchannel-success-and-failure.html [ Timeout ] -crbug.com/874302 external/wpt/wasm/serialization/broadcastchannel-success.html [ Timeout ] +crbug.com/874302 external/wpt/wasm/serialization/module/broadcastchannel-success-and-failure.html [ Timeout ] +crbug.com/874302 external/wpt/wasm/serialization/module/broadcastchannel-success.html [ Timeout ] -crbug.com/877286 external/wpt/wasm/serialization/no-transferring.html [ Failure ] -crbug.com/877296 external/wpt/wasm/serialization/window-serviceworker-failure.https.html [ Failure ] +crbug.com/877286 external/wpt/wasm/serialization/module/no-transferring.html [ Failure ] +crbug.com/877296 external/wpt/wasm/serialization/module/window-serviceworker-failure.https.html [ Failure ] crbug.com/831509 external/wpt/service-workers/service-worker/skip-waiting-installed.https.html [ Failure Pass ] crbug.com/831509 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/skip-waiting-installed.https.html [ Failure Pass ] @@ -4560,6 +4571,8 @@ crbug.com/724027 virtual/outofblink-cors/http/tests/security/contentSecurityPolicy/source-list-parsing-04.html [ Skip ] crbug.com/724027 virtual/outofblink-cors-ns/http/tests/security/contentSecurityPolicy/directive-parsing-03.html [ Skip ] crbug.com/724027 virtual/outofblink-cors-ns/http/tests/security/contentSecurityPolicy/source-list-parsing-04.html [ Skip ] +crbug.com/724027 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/directive-parsing-03.html [ Skip ] +crbug.com/724027 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/source-list-parsing-04.html [ Skip ] # Sheriff failures 2017-05-16 crbug.com/722212 fast/events/pointerevents/mouse-pointer-event-properties.html [ Failure Timeout Pass ] @@ -4659,6 +4672,7 @@ crbug.com/708994 http/tests/security/cross-frame-mouse-source-capabilities.html [ Timeout Pass ] crbug.com/708994 virtual/outofblink-cors/http/tests/security/cross-frame-mouse-source-capabilities.html [ Timeout Pass ] crbug.com/708994 virtual/outofblink-cors-ns/http/tests/security/cross-frame-mouse-source-capabilities.html [ Timeout Pass ] +crbug.com/708994 virtual/feature-policy-for-sandbox/http/tests/security/cross-frame-mouse-source-capabilities.html [ Timeout Pass ] crbug.com/745887 [ Mac ] fast/frames/sandboxed-iframe-plugins.html [ Failure Pass ] crbug.com/745887 [ Win ] fast/frames/sandboxed-iframe-plugins.html [ Failure Pass ] @@ -5889,13 +5903,18 @@ crbug.com/921719 virtual/prefer_compositing_to_lcd_text/scrollbars/mock-scrollbars.html [ Skip ] crbug.com/921719 virtual/threaded/printing/offscreencanvas-2d-printing.html [ Skip ] crbug.com/921719 virtual/threaded/printing/offscreencanvas-webgl-printing.html [ Skip ] +crbug.com/922951 animations/direction-and-fill/fill-mode-iteration-count-non-integer.html [ Skip ] +crbug.com/922951 animations/direction-and-fill/fill-mode-missing-from-to-keyframes.html [ Skip ] crbug.com/922951 animations/direction-and-fill/fill-mode-transform.html [ Skip ] crbug.com/922951 animations/direction-and-fill/fill-mode.html [ Skip ] crbug.com/922951 compositing/overflow/overflow-scroll-with-local-background.html [ Skip ] +crbug.com/922951 external/wpt/longtask-timing/longtask-in-sibling-iframe-crossorigin.html [ Skip ] crbug.com/922951 external/wpt/pointerevents/pointerevent_capture_mouse.html [ Skip ] crbug.com/922951 external/wpt/pointerevents/pointerevent_releasepointercapture_invalid_pointerid.html [ Skip ] crbug.com/922951 external/wpt/pointerevents/pointerevent_setpointercapture_disconnected.html [ Skip ] crbug.com/922951 external/wpt/pointerevents/pointerevent_setpointercapture_invalid_pointerid.html [ Skip ] +crbug.com/922951 fast/canvas/OffscreenCanvas-placeholder-createImageBitmap.html [ Skip ] +crbug.com/922951 fast/css/pseudo-hover-active-display-none.html [ Skip ] crbug.com/922951 fast/dom/shadow/move-marquee-crossing-treescope-crash.html [ Skip ] crbug.com/922951 fast/forms/number/number-input-event-composed.html [ Skip ] crbug.com/922951 fast/loader/detach-while-printing.html [ Skip ] @@ -5903,10 +5922,13 @@ crbug.com/922951 fast/scroll-snap/snaps-after-keyboard-scrolling.html [ Skip ] crbug.com/922951 fast/scroll-snap/snaps-for-different-key-granularity.html [ Skip ] crbug.com/922951 fast/text/international/inline-plaintext-relayout-with-leading-neutrals.html [ Skip ] +crbug.com/922951 http/tests/cache/subresource-fragment-identifier.html [ Skip ] crbug.com/922951 http/tests/devtools/audits2/audits2-successful-run.js [ Skip ] +crbug.com/922951 http/tests/devtools/isolated-code-cache/same-origin-test.js [ Skip ] crbug.com/922951 http/tests/devtools/tracing-session-id.js [ Skip ] crbug.com/922951 http/tests/devtools/tracing/console-timeline.js [ Skip ] crbug.com/922951 http/tests/devtools/tracing/timeline-network-received-data.js [ Skip ] +crbug.com/922951 http/tests/history/back-to-post.html [ Skip ] crbug.com/922951 http/tests/images/feature-policy-unoptimized-images-cached-image.html [ Skip ] crbug.com/922951 http/tests/security/offscreencanvas-placeholder-read-blocked-no-crossorigin.html [ Skip ] crbug.com/922951 http/tests/webaudio/autoplay-crossorigin.html [ Skip ] @@ -5914,11 +5936,30 @@ crbug.com/922951 media/controls/overflow-menu-hide-on-click-outside-stoppropagation.html [ Skip ] crbug.com/922951 media/controls/overflow-menu-hide-on-click-outside.html [ Skip ] crbug.com/922951 media/controls/overflow-menu-toggle-class-for-animation.html [ Skip ] +crbug.com/922951 scrollbars/resize-scales-with-dpi-150.html [ Skip ] crbug.com/922951 svg/animations/dynamic-modify-transform-without-baseval.html [ Skip ] crbug.com/922951 svg/animations/target-condition-crash.html [ Skip ] crbug.com/922951 svg/as-object/embedded-svg-immediate-offsetWidth-query.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-auto-auto-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-auto-auto-no-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-auto-fixed-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-auto-fixed-no-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-auto-percentage-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-auto-percentage-no-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-fixed-auto-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-fixed-auto-no-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-fixed-fixed-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-fixed-fixed-no-intrinsic-ratio.html [ Skip ] crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-fixed-percentage-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-fixed-percentage-no-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-percentage-auto-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-percentage-auto-no-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-percentage-fixed-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-percentage-fixed-no-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-percentage-percentage-intrinsic-ratio.html [ Skip ] +crbug.com/922951 svg/as-object/sizing/svg-in-object-placeholder-percentage-percentage-no-intrinsic-ratio.html [ Skip ] crbug.com/922951 svg/custom/object-sizing-zero-intrinsic-width-height.html [ Skip ] +crbug.com/922951 virtual/gpu/fast/canvas/OffscreenCanvas-MessageChannel-transfer.html [ Skip ] crbug.com/922951 virtual/gpu/fast/canvas/OffscreenCanvas-placeholder-createImageBitmap.html [ Skip ] crbug.com/922951 virtual/gpu/fast/canvas/color-space/canvas-drawImage-offscreenCanvas.html [ Skip ] crbug.com/922951 virtual/mouseevent_fractional/fast/events/synthetic-events/tap-on-scaled-screen.html [ Skip ] @@ -5929,6 +5970,7 @@ crbug.com/922951 virtual/new-remote-playback-pipeline/media/controls/overflow-menu-toggle-class-for-animation.html [ Skip ] crbug.com/922951 virtual/outofblink-cors-ns/http/tests/security/offscreencanvas-placeholder-read-blocked-no-crossorigin.html [ Skip ] crbug.com/922951 virtual/outofblink-cors/http/tests/security/offscreencanvas-placeholder-read-blocked-no-crossorigin.html [ Skip ] +crbug.com/922951 virtual/prefer_compositing_to_lcd_text/scrollbars/resize-scales-with-dpi-150.html [ Skip ] crbug.com/922951 virtual/scalefactor150/fast/events/synthetic-events/tap-on-scaled-screen.html [ Skip ] crbug.com/922951 virtual/stable/compositing/overflow/overflow-scroll-with-local-background.html [ Skip ] crbug.com/922951 virtual/threaded/animations/direction-and-fill/fill-mode-iteration-count-non-integer.html [ Skip ] @@ -5971,6 +6013,19 @@ # WebXR feature policy feature name in Chrome doesn't match spec. crbug.com/924670 external/wpt/webvr/webvr-supported-by-feature-policy.html [ Failure ] +# Feature Policy for Sandbox currently causes these tests to fail. +crbug.com/926245 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/sandbox-empty-subframe.html [ Failure ] +crbug.com/926245 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/sandbox-empty.html [ Failure ] +crbug.com/926245 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/sandbox-in-http-header-control.html [ Failure ] +crbug.com/926245 virtual/feature-policy-for-sandbox/http/tests/security/contentSecurityPolicy/sandbox-invalid-header.html [ Failure ] +crbug.com/926247 virtual/feature-policy-for-sandbox/http/tests/navigation/new-window-sandboxed-iframe.html [ Failure ] +crbug.com/926247 virtual/feature-policy-for-sandbox/http/tests/security/popup-allowed-by-sandbox-is-sandboxed.html [ Failure ] +crbug.com/926248 virtual/feature-policy-for-sandbox/mhtml/page_with_css_and_js_ie.mht [ Failure ] +crbug.com/926248 virtual/feature-policy-for-sandbox/mhtml/page_with_css_and_js_unmht.mht [ Failure ] +crbug.com/926248 virtual/feature-policy-for-sandbox/mhtml/page_with_javascript.mht [ Failure ] +crbug.com/926248 virtual/feature-policy-for-sandbox/mhtml/transfer_encoding_8bit.mht [ Failure ] +crbug.com/926249 virtual/feature-policy-for-sandbox/http/tests/security/sandbox-iframe-blocks-modals.php [ Failure ] + # Sheriff 2019-01-25 crbug.com/925325 [ Mac ] storage/indexeddb/index-population.html [ Pass Failure ] @@ -5985,3 +6040,5 @@ crbug.com/v8/8319 external/wpt/wasm/jsapi/module/customSections.any.worker.html [ Pass Failure ] crbug.com/927296 virtual/wasm-site-isolated-code-cache/http/tests/devtools/wasm-isolated-code-cache/wasm-cache-test.js [ Pass Failure ] + +crbug.com/927334 [ Win ] fast/dom/document-contentType-data-uri.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 77893f7..d3e1231 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -881,12 +881,12 @@ }, { "prefix": "not-site-per-process", - "base": "external/wpt/wasm/serialization/window-domain-success.sub.html", + "base": "external/wpt/wasm/serialization/module/window-domain-success.sub.html", "args": ["--disable-site-isolation-trials"] }, { "prefix": "not-site-per-process", - "base": "external/wpt/wasm/serialization/window-similar-but-cross-origin-success.sub.html", + "base": "external/wpt/wasm/serialization/module/window-similar-but-cross-origin-success.sub.html", "args": ["--disable-site-isolation-trials"] }, { @@ -1013,5 +1013,20 @@ "prefix": "bidi-caret-affinity", "base": "editing/selection/modify_move", "args": ["--enable-blink-features=BidiCaretAffinity,EditingNG"] + }, + { + "prefix": "feature-policy-for-sandbox", + "base": "http/tests/navigation", + "args": ["--enable-blink-features=FeaturePolicyForSandbox"] + }, + { + "prefix": "feature-policy-for-sandbox", + "base": "http/tests/security", + "args": ["--enable-blink-features=FeaturePolicyForSandbox"] + }, + { + "prefix": "feature-policy-for-sandbox", + "base": "mhtml", + "args": ["--enable-blink-features=FeaturePolicyForSandbox"] } ]
diff --git a/third_party/blink/web_tests/animations/interpolation/transform-interpolation-001.html b/third_party/blink/web_tests/animations/interpolation/transform-interpolation-001.html index 6bfcfbf..c77204f 100644 --- a/third_party/blink/web_tests/animations/interpolation/transform-interpolation-001.html +++ b/third_party/blink/web_tests/animations/interpolation/transform-interpolation-001.html
@@ -117,6 +117,32 @@ {at: 1, is: 'rotateZ(900deg)'}, {at: 2, is: 'rotateZ(1800deg)'}, ]); +// Interpolation is about a common axis if either endpoint has a rotation angle +// of zero. +assertInterpolation({ + property: 'transform', + from: 'rotateX(0deg)', + to: 'rotateY(900deg)' +}, [ + {at: -1, is: 'rotateY(-900deg)'}, + {at: 0, is: 'rotateY(0deg)'}, + {at: 0.25, is: 'rotateY(225deg)'}, + {at: 0.75, is: 'rotateY(675deg)'}, + {at: 1, is: 'rotateY(900deg)'}, + {at: 2, is: 'rotateY(1800deg)'}, +]); +assertInterpolation({ + property: 'transform', + from: 'rotateY(900deg)', + to: 'rotateZ(0deg)' +}, [ + {at: -1, is: 'rotateY(1800deg)'}, + {at: 0, is: 'rotateY(900deg)'}, + {at: 0.25, is: 'rotateY(675deg)'}, + {at: 0.75, is: 'rotateY(225deg)'}, + {at: 1, is: 'rotateY(0deg)'}, + {at: 2, is: 'rotateY(-900deg)'}, +]); assertInterpolation({ property: 'transform', from: 'rotate3d(7, 8, 9, 100deg)', @@ -153,6 +179,19 @@ {at: 1, is: 'rotate3d(0, 1, 0, 450deg)'}, {at: 2, is: 'rotate3d(0, 1, 0, 900deg)'}, ]); +// Rotation is about a common axis if the axes are colinear. +assertInterpolation({ + property: 'transform', + from: 'rotate3d(0, 1, 0, 0deg)', + to: 'rotate3d(0, 2, 0, 450deg)' +}, [ + {at: -1, is: 'rotate3d(0, 1, 0, -450deg)'}, + {at: 0, is: 'rotate3d(0, 1, 0, 0deg)'}, + {at: 0.25, is: 'rotate3d(0, 1, 0, 112.5deg)'}, + {at: 0.75, is: 'rotate3d(0, 1, 0, 337.5deg)'}, + {at: 1, is: 'rotate3d(0, 1, 0, 450deg)'}, + {at: 2, is: 'rotate3d(0, 1, 0, 900deg)'}, +]); assertInterpolation({ property: 'transform', from: 'rotate3d(1, 1, 0, 90deg)',
diff --git a/third_party/blink/web_tests/css-parser/variables-invalid-functions.html b/third_party/blink/web_tests/css-parser/variables-invalid-functions.html deleted file mode 100644 index 5f9ed691..0000000 --- a/third_party/blink/web_tests/css-parser/variables-invalid-functions.html +++ /dev/null
@@ -1,94 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <link rel="help" href="https://drafts.csswg.org/css-env-1/"> - <title>Test env() and var() throw syntax errors if used with invalid functions</title> - <script src="../resources/testharness.js"></script> - <script src="../resources/testharnessreport.js"></script> - <style> - div { - --a: 0px; - margin-left: 10px; - } - </style> - </head> - <body> - <script> - // This value is expected if the syntax is valid. - const workingValue = "0px"; - - // This value is expected if the syntax is invalid. - const pageDefaultValue = "10px"; - - // This value is expected if the calc() syntax is valid. - const workingCalcValue = "20px"; - - const testCases = [ - { style: "", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: env(safe-area-inset-left)", expectedPropertyValue: workingValue }, - - // min and max() are not supported. - { style: "margin-left: min(env(safe-area-inset-left))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(env(safe-area-inset-left), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(env(safe-area-inset-left, 1px))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(env(safe-area-inset-left, 1px), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(env(test))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(env(test), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(env(test, 1px))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(env(test, 1px), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(env(safe-area-inset-left))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(env(safe-area-inset-left), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(env(safe-area-inset-left, 1px))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(env(safe-area-inset-left, 1px), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(env(test))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(env(test), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(env(test, 1px))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(env(test, 1px), 1px)", expectedPropertyValue: pageDefaultValue }, - - // calc() should work. - { style: "margin-left: calc(env(safe-area-inset-left) + 20px)", expectedPropertyValue: workingCalcValue }, - { style: "margin-left: calc(env(safe-area-inset-left, 0px) + 20px)", expectedPropertyValue: workingCalcValue }, - { style: "margin-left: calc(env(safe-area-inset-left, 0) + 20px)", expectedPropertyValue: workingCalcValue }, - { style: "margin-left: calc(env(test) + 20px)", expectedPropertyValue: "0px" }, - { style: "margin-left: calc(env(test, 1px) + 20px)", expectedPropertyValue: "21px" }, - - // min and max() are not supported. - { style: "margin-left: min(var(--a))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(var(--a), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(var(--a, 1px))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(var(--a, 1px), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(var(--b))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(var(--b), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(var(--b, 1px))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: min(var(--b, 1px), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(var(--a))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(var(--a), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(var(--a, 1px))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(var(--a, 1px), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(var(--b))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(var(--b), 1px)", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(var(--b, 1px))", expectedPropertyValue: pageDefaultValue }, - { style: "margin-left: max(var(--b, 1px), 1px)", expectedPropertyValue: pageDefaultValue }, - - // calc() should work. - { style: "margin-left: calc(var(--a) + 20px)", expectedPropertyValue: workingCalcValue }, - { style: "margin-left: calc(var(--a, 0px) + 20px)", expectedPropertyValue: workingCalcValue }, - { style: "margin-left: calc(var(--a, 0) + 20px)", expectedPropertyValue: workingCalcValue }, - { style: "margin-left: calc(var(--b) + 20px)", expectedPropertyValue: "0px" }, - { style: "margin-left: calc(var(--b, 1px) + 20px)", expectedPropertyValue: "21px" }, - ]; - - testCases.forEach((testcase) => { - test(() => { - const elem = document.createElement("div"); - const style = window.getComputedStyle(elem); - - document.body.appendChild(elem); - elem.style.cssText = testcase.style; - - assert_equals(style.getPropertyValue("margin-left"), testcase.expectedPropertyValue); - }, testcase.style + " " + testcase.expectedPropertyValue); - }); - </script> - </body> -</html>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json index 936e25b..7aa93ae 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -172949,6 +172949,11 @@ {} ] ], + "infrastructure/metadata/infrastructure/reftest/size.html.ini": [ + [ + {} + ] + ], "infrastructure/metadata/infrastructure/server/context.any.js.ini": [ [ {} @@ -172959,6 +172964,11 @@ {} ] ], + "infrastructure/metadata/infrastructure/server/order-of-metas.window.js.ini": [ + [ + {} + ] + ], "infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini": [ [ {} @@ -172994,6 +173004,11 @@ {} ] ], + "infrastructure/metadata/infrastructure/testdriver/file_upload.sub.html.ini": [ + [ + {} + ] + ], "infrastructure/reftest-wait-ref.html": [ [ {} @@ -263824,6 +263839,12 @@ {} ] ], + "portals/portals-activate-no-browsing-context.html": [ + [ + "/portals/portals-activate-no-browsing-context.html", + {} + ] + ], "portals/portals-host-null.html": [ [ "/portals/portals-host-null.html", @@ -381774,7 +381795,7 @@ "testharness" ], "css/geometry/interfaces-expected.txt": [ - "9b73550b32d8e2a205c845edb04bbdfb42a32145", + "d9727cdf97c2590fb795b7c9f107f446f2e1b2de", "support" ], "css/geometry/interfaces.html": [ @@ -417774,11 +417795,11 @@ "testharness" ], "infrastructure/metadata/infrastructure/assumptions/allowed-to-play.html.ini": [ - "c9fbabede6d695cd3795e4390b35da0454ffcc34", + "f9be6a64bdfd7ca033fda2a9cd1bdb105836df20", "support" ], "infrastructure/metadata/infrastructure/assumptions/html-elements.html.ini": [ - "b7303c645fce287ae4e2bb34dbb1999e6e27e147", + "5bb1bf554ccbc73a605f4364c59b91aa59a7ee87", "support" ], "infrastructure/metadata/infrastructure/expected-fail/failing-test.html.ini": [ @@ -417813,20 +417834,28 @@ "0d1b9bade95d7b101c8dbf51547ffbaec2260c27", "support" ], + "infrastructure/metadata/infrastructure/reftest/size.html.ini": [ + "1c6cd9eff891b315fcbe4bfcded859259d50e509", + "support" + ], "infrastructure/metadata/infrastructure/server/context.any.js.ini": [ - "f985548b2f0987992331415d1661a2fdfb48ed99", + "ff57a138029ca49e7e63d9dd27e25288709c61f3", "support" ], "infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini": [ - "b29646288b23b7e1603bcae7927e61c9d9adc241", + "e4a96de0e8f60fbbd48676deb59bd8ba85f99133", + "support" + ], + "infrastructure/metadata/infrastructure/server/order-of-metas.window.js.ini": [ + "20e4cbad939b92111c17bdf0d5fdb58d379cf8df", "support" ], "infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini": [ - "272935af1ecad7ea785a716948aec8f0a4139330", + "f483bca13f6b372774e1494c75455cd075ba0313", "support" ], "infrastructure/metadata/infrastructure/server/title.any.js.ini": [ - "6852b8033d8ebf2b15786af1286a1ced98c793fb", + "cbae6b15410e13433c4a9fadd8c2a8cc5fbc4fdc", "support" ], "infrastructure/metadata/infrastructure/testdriver/actions/elementPosition.html.ini": [ @@ -417849,6 +417878,10 @@ "7ceec9f531bfe3ede763a41726590f3effdbac29", "support" ], + "infrastructure/metadata/infrastructure/testdriver/file_upload.sub.html.ini": [ + "42c98117c58bbe7b9201d1883e0c1649898b5570", + "support" + ], "infrastructure/reftest-wait-ref.html": [ "6772c2c460e79993979688ddf46e2045b14f7d71", "support" @@ -420322,7 +420355,7 @@ "testharness" ], "mediacapture-streams/idlharness.https.window-expected.txt": [ - "b0be4a5647ace311ffc0e90d4c880069079524c6", + "2720255440e5406c8144308f6b93c579c39a266b", "support" ], "mediacapture-streams/idlharness.https.window.js": [ @@ -430950,7 +430983,7 @@ "testharness" ], "performance-timeline/idlharness.any-expected.txt": [ - "0b65efbd20ed67e8fa96eb7400a1ef5c47ddc350", + "7d03cc1c92e43122223b32d6e059dbbef3ad7df8", "support" ], "performance-timeline/idlharness.any.js": [ @@ -430958,15 +430991,15 @@ "testharness" ], "performance-timeline/idlharness.any.serviceworker-expected.txt": [ - "0b65efbd20ed67e8fa96eb7400a1ef5c47ddc350", + "7d03cc1c92e43122223b32d6e059dbbef3ad7df8", "support" ], "performance-timeline/idlharness.any.sharedworker-expected.txt": [ - "0b65efbd20ed67e8fa96eb7400a1ef5c47ddc350", + "7d03cc1c92e43122223b32d6e059dbbef3ad7df8", "support" ], "performance-timeline/idlharness.any.worker-expected.txt": [ - "0b65efbd20ed67e8fa96eb7400a1ef5c47ddc350", + "7d03cc1c92e43122223b32d6e059dbbef3ad7df8", "support" ], "performance-timeline/performanceentry-tojson.any.js": [ @@ -431573,6 +431606,10 @@ "ac1505d2a5b2fe1df083eae75893483e025a2ad7", "testharness" ], + "portals/portals-activate-no-browsing-context.html": [ + "9a822e9238a938e48c5c1bc6d76669d48962ee65", + "testharness" + ], "portals/portals-host-null.html": [ "e0f1d63743c54c687d62f86abe278873fa823430", "testharness" @@ -441870,7 +441907,7 @@ "support" ], "resources/idlharness.js": [ - "8b7a1e2d98ea3167793f6996d56211ebb2cf0f41", + "b765d1f6199fc8c13dcd74b534bbae9e729f225b", "support" ], "resources/idlharness.js.headers": [ @@ -454082,11 +454119,11 @@ "testharness" ], "webrtc/RTCRtpParameters-encodings-expected.txt": [ - "3ce1fdd644b7bf4b094d0cb965399a592cb2c200", + "ce30e4583cded08a3e54fc2228f98e9bd54ce232", "support" ], "webrtc/RTCRtpParameters-encodings.html": [ - "b8ae4e4c187ce0ccea70421a248c900aae844af6", + "23cb76919c021f43d804fa9e213b16f79c341755", "testharness" ], "webrtc/RTCRtpParameters-headerExtensions.html": [ @@ -454262,7 +454299,7 @@ "testharness" ], "webrtc/idlharness.https.window-expected.txt": [ - "12913bcb81ebcc8dcccedfe5573b9937700111a2", + "a55770611b4412d120939d29495bf5fabe01b68d", "support" ], "webrtc/idlharness.https.window.js": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/child-move-reveals-parent-background-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/child-move-reveals-parent-background-ref.html new file mode 100644 index 0000000..1032496 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/child-move-reveals-parent-background-ref.html
@@ -0,0 +1,10 @@ +<!DOCTYPE html> +<style> + #parent { + width: 150px; + height: 150px; + background-color: green; + } +</style> +<p>There should be a green square below.</p> +<div id="parent"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/child-move-reveals-parent-background.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/child-move-reveals-parent-background.html new file mode 100644 index 0000000..e369eccd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/child-move-reveals-parent-background.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>Child moves and reveals previously obscured background of the parent</title> +<link rel="match" href="child-move-reveals-parent-background-ref.html"> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds"> +<script src="/common/reftest-wait.js"></script> +<style> + #parent { + width: 150px; + height: 150px; + background-color: green; + } + #child { + width: 150px; + height: 150px; + background-color: white; + position: relative; + } +</style> +<p>There should be a green square below.</p> +<div id="parent"> + <div id="child"></div> +</div> +<script> + requestAnimationFrame(() => requestAnimationFrame(() => { + child.style.left = '150px'; + takeScreenshot(); + })); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-env/supports-script.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-env/supports-script.tentative.html index ec9b6d0d..7ab4db2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-env/supports-script.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-env/supports-script.tentative.html
@@ -11,6 +11,8 @@ test(() => { assert_true(CSS.supports("background: env(test)")); assert_true(CSS.supports("background", "env(test)")); + assert_true(CSS.supports("background", "env(test, 10px)")); + assert_true(CSS.supports("background", "foobar(env(test))")); assert_false(CSS.supports("background", "env()")); assert_false(CSS.supports("background", "env(test,)")); });
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-loose.html index cf7c5a44..def6adf 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-loose.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-loose.html
@@ -89,17 +89,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may appear at line start if ja and loose'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may appear at line start if ja and loose'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-normal.html index 7c701c85..bc204f5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-normal.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-normal.html
@@ -89,17 +89,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may appear at line start if ja and normal'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may appear at line start if ja and normal'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-strict.html index 9fe1804..cdb8398 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-strict.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-strict.html
@@ -89,17 +89,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>æ–‡&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may NOT appear at line start if ja and strict'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may NOT appear at line start if ja and strict'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-loose.html index 6120e62..c932cb4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-loose.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-loose.html
@@ -48,17 +48,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may appear at line start if ja and loose'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may appear at line start if ja and loose'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-normal.html index 1e1d4bb..7816fb5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-normal.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-normal.html
@@ -48,17 +48,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>æ–‡&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may NOT appear at line start if ja and normal'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may NOT appear at line start if ja and normal'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-strict.html index ddf3c2c..833e45e 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-strict.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-strict.html
@@ -48,17 +48,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>æ–‡&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may NOT appear at line start if ja and strict'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may NOT appear at line start if ja and strict'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-loose.html index 647bfc8..fbb13ec 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-loose.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-loose.html
@@ -42,17 +42,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may appear at line start if ja and loose'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may appear at line start if ja and loose'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-normal.html index 5e22458..dc22d616 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-normal.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-normal.html
@@ -42,17 +42,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may appear at line start if ja and normal'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may appear at line start if ja and normal'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html index 3db8bb8..cd5d5aa93 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html
@@ -42,17 +42,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>æ–‡&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may NOT appear at line start if ja and strict'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may NOT appear at line start if ja and strict'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose.html index 09c5758..235d381 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose.html
@@ -43,17 +43,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may appear at line start if ja and loose'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may appear at line start if ja and loose'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-normal.html index 8bf3aa9..7bdedd5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-normal.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-normal.html
@@ -43,17 +43,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>æ–‡&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may NOT appear at line start if ja and normal'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may NOT appear at line start if ja and normal'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-strict.html index 3c14e18..58c05bb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-strict.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-strict.html
@@ -43,17 +43,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>æ–‡&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may NOT appear at line start if ja and strict'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may NOT appear at line start if ja and strict'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-loose.html index dbf77a0f..49f51f4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-loose.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-loose.html
@@ -44,17 +44,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may appear at line start if ja and loose'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may appear at line start if ja and loose'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-normal.html index ecdcdc3..55f54ea8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-normal.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-normal.html
@@ -44,17 +44,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>æ–‡&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may NOT appear at line start if ja and normal'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may NOT appear at line start if ja and normal'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-strict.html index 3b2a2ee..1c2cd9a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-strict.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-strict.html
@@ -44,17 +44,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>æ–‡&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may NOT appear at line start if ja and strict'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may NOT appear at line start if ja and strict'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-loose.html index 795cb02..4d79a12 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-loose.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-loose.html
@@ -48,17 +48,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may appear at line start if ja and loose'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may appear at line start if ja and loose'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-normal.html index 7c591eb..eb3003c 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-normal.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-normal.html
@@ -48,17 +48,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>æ–‡&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may NOT appear at line start if ja and normal'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may NOT appear at line start if ja and normal'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-strict.html index c41ea73..08e16f26 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-strict.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-strict.html
@@ -48,17 +48,26 @@ '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>æ–‡&#x'+hex+';å—<span id="refSpan'+i+'">å—</span></div>' + '</div>' } +function spansNearEnough(counter) { + return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left + - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1; +} + document.querySelector('body').innerHTML = out -// hide successful tests -for (i=0;i<lines.length;i++) { - if (document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft) document.getElementById('test'+i).parentNode.style.display = 'none' - } -// run the test framework - for (i=0;i<lines.length;i++) { - test(function() { - assert_true(document.getElementById('testSpan'+i).offsetLeft === document.getElementById('refSpan'+i).offsetLeft); - }, lines[i]+' may NOT appear at line start if ja and strict'); - } +setup({explicit_done: true}); + +document.fonts.ready.then(validate); + +function validate() { + for (i=0;i<lines.length;i++) { + test(function() { + assert_true(spansNearEnough(i)); + }, lines[i]+' may NOT appear at line start if ja and strict'); + // Hide successful tests. + if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none' + } + done(); +} </script> <!--Notes: The test creates a box with room for 6 characters, causing wrapping to occur either between the 6th and the 7th character, or before the 6th if the breaks after the 6th or before the 7th are prohibited.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/list-interpolation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/list-interpolation-expected.txt index 7d67a78..55e208a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/list-interpolation-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/list-interpolation-expected.txt
@@ -14,9 +14,13 @@ PASS Matches on primitives: "translateX(100px) scaleX(3) translate(500px) scale(2)" and "translateY(200px) scale(5) translateX(100px) scaleY(3)" are valid transform values PASS Matches on primitives: Animation between "translateX(100px) scaleX(3) translate(500px) scale(2)" and "translateY(200px) scale(5) translateX(100px) scaleY(3)" at progress 0.25 PASS Match on rotation vector: "rotateX(90deg) translateX(100px)" and "rotate3d(50, 0, 0, 180deg) translateY(200px)" are valid transform values -FAIL Match on rotation vector: Animation between "rotateX(90deg) translateX(100px)" and "rotate3d(50, 0, 0, 180deg) translateY(200px)" at progress 0.25 assert_equals: expected "matrix3d(1, 0, 0, 0, 0, -0.382683, 0.92388, 0, 0, -0.92388, -0.382683, 0, 75, -19.1342, 46.194, 1)" but got "matrix3d(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 75, -50, 0, 1)" +PASS Match on rotation vector: Animation between "rotateX(90deg) translateX(100px)" and "rotate3d(50, 0, 0, 180deg) translateY(200px)" at progress 0.25 PASS Match on rotation due to 0deg angle: "rotateX(90deg) translateX(100px)" and "rotateY(0deg) translateY(200px)" are valid transform values -FAIL Match on rotation due to 0deg angle: Animation between "rotateX(90deg) translateX(100px)" and "rotateY(0deg) translateY(200px)" at progress 0.25 assert_equals: expected "matrix3d(1, 0, 0, 0, 0, 0.382683, 0.92388, 0, 0, -0.92388, 0.382683, 0, 75, 19.1342, 46.194, 1)" but got "matrix(1, 0, 0, 1, 75, 50)" +PASS Match on rotation due to 0deg angle: Animation between "rotateX(90deg) translateX(100px)" and "rotateY(0deg) translateY(200px)" at progress 0.25 +PASS Match on rotation using collinear rotation axes: "rotate3d(1, 1, 1, -60deg) translateX(100px)" and "rotate3d(2, 2, 2, 60deg) translateY(200px)" are valid transform values +PASS Match on rotation using collinear rotation axes: Animation between "rotate3d(1, 1, 1, -60deg) translateX(100px)" and "rotate3d(2, 2, 2, 60deg) translateY(200px)" at progress 0.25 +PASS Match on rotation with spherical interpolation: "rotate3d(1, 0, 0, 360deg) translateX(100px)" and "rotate3d(0, 1, 0, -720deg) translateY(200px)" are valid transform values +PASS Match on rotation with spherical interpolation: Animation between "rotate3d(1, 0, 0, 360deg) translateX(100px)" and "rotate3d(0, 1, 0, -720deg) translateY(200px)" at progress 0.25 PASS Common prefix: "rotate(0deg) translate(100px)" and "rotate(720deg) scale(2) translate(200px)" are valid transform values PASS Common prefix: Animation between "rotate(0deg) translate(100px)" and "rotate(720deg) scale(2) translate(200px)" at progress 0.25 PASS Complete mismatch (except length): "scale(2) rotate(0deg) translate(100px)" and "rotate(720deg) scale(2) translate(200px)" are valid transform values
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/list-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/list-interpolation.html index af221e5f..4755279 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/list-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/list-interpolation.html
@@ -109,6 +109,24 @@ test_interpolation( { property: 'transform', + from: 'rotate3d(1, 1, 1, -60deg) translateX(100px)', + to: 'rotate3d(2, 2, 2, 60deg) translateY(200px)', + }, [{ at: 0.25, expect: 'rotate3d(1, 1, 1, -30deg) translate(75px, 50px)' }], + 'Match on rotation using collinear rotation axes' +); + +test_interpolation( + { + property: 'transform', + from: 'rotate3d(1, 0, 0, 360deg) translateX(100px)', + to: 'rotate3d(0, 1, 0, -720deg) translateY(200px)', + }, [{ at: 0.25, expect: 'rotate3d(0, 0, 1, 0deg) translate(75px, 50px)' }], + 'Match on rotation with spherical interpolation' +); + +test_interpolation( + { + property: 'transform', from: 'rotate(0deg) translate(100px)', to: 'rotate(720deg) scale(2) translate(200px)', },
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/matrix-interpolation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/matrix-interpolation-expected.txt deleted file mode 100644 index eb3376c..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/matrix-interpolation-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -PASS "rotateY(360deg)" and "rotateX(720deg)" are valid transform values -FAIL Animation between "rotateY(360deg)" and "rotateX(720deg)" at progress 0.5 assert_equals: expected "matrix(1, 0, 0, 1, 0, 0)" but got "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/CSS.html b/third_party/blink/web_tests/external/wpt/css/cssom/CSS.html index 7d558f0..ba048c5 100644 --- a/third_party/blink/web_tests/external/wpt/css/cssom/CSS.html +++ b/third_party/blink/web_tests/external/wpt/css/cssom/CSS.html
@@ -26,6 +26,8 @@ assert_equals(CSS.supports("color: red"), true, "CSS.supports: Single-argument form allows for declarations without enclosing parentheses"); assert_equals(CSS.supports("(color: red) and (color: blue)"), true, "CSS.supports: Complex conditions allowed"); assert_equals(CSS.supports("not (foobar)"), true, "CSS.supports: general_enclosed still parses"); + assert_equals(CSS.supports("color: something-pointless var(--foo)"), true, "Variable references always parse"); + assert_equals(CSS.supports("color: something-pointless(var(--foo))"), true, "Variable references in an unknown function always parse"); }, "CSS.supports, one argument form"); test(function () { // https://drafts.csswg.org/css-conditional/#dom-css-supports
diff --git a/third_party/blink/web_tests/external/wpt/css/geometry/interfaces-expected.txt b/third_party/blink/web_tests/external/wpt/css/geometry/interfaces-expected.txt index 9b73550..d9727cd 100644 --- a/third_party/blink/web_tests/external/wpt/css/geometry/interfaces-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/geometry/interfaces-expected.txt
@@ -25,7 +25,7 @@ PASS DOMPointReadOnly interface: new DOMPointReadOnly() must inherit property "matrixTransform(DOMMatrixInit)" with the proper type PASS DOMPointReadOnly interface: calling matrixTransform(DOMMatrixInit) on new DOMPointReadOnly() with too few arguments must throw TypeError PASS DOMPointReadOnly interface: new DOMPointReadOnly() must inherit property "toJSON()" with the proper type -PASS Test default toJSON operation of DOMPointReadOnly +PASS DOMPointReadOnly interface: default toJSON operation on new DOMPointReadOnly() PASS DOMPoint interface: existence and properties of interface object PASS DOMPoint interface object length PASS DOMPoint interface object name @@ -55,7 +55,7 @@ PASS DOMPointReadOnly interface: new DOMPoint() must inherit property "matrixTransform(DOMMatrixInit)" with the proper type PASS DOMPointReadOnly interface: calling matrixTransform(DOMMatrixInit) on new DOMPoint() with too few arguments must throw TypeError PASS DOMPointReadOnly interface: new DOMPoint() must inherit property "toJSON()" with the proper type -PASS Test default toJSON operation of DOMPoint +PASS DOMPointReadOnly interface: default toJSON operation on new DOMPoint() PASS DOMRectReadOnly interface: existence and properties of interface object PASS DOMRectReadOnly interface object length PASS DOMRectReadOnly interface object name @@ -85,7 +85,7 @@ PASS DOMRectReadOnly interface: new DOMRectReadOnly() must inherit property "bottom" with the proper type PASS DOMRectReadOnly interface: new DOMRectReadOnly() must inherit property "left" with the proper type PASS DOMRectReadOnly interface: new DOMRectReadOnly() must inherit property "toJSON()" with the proper type -PASS Test default toJSON operation of DOMRectReadOnly +PASS DOMRectReadOnly interface: default toJSON operation on new DOMRectReadOnly() PASS DOMRect interface: existence and properties of interface object PASS DOMRect interface object length PASS DOMRect interface object name @@ -117,7 +117,7 @@ PASS DOMRectReadOnly interface: new DOMRect() must inherit property "bottom" with the proper type PASS DOMRectReadOnly interface: new DOMRect() must inherit property "left" with the proper type PASS DOMRectReadOnly interface: new DOMRect() must inherit property "toJSON()" with the proper type -PASS Test default toJSON operation of DOMRect +PASS DOMRectReadOnly interface: default toJSON operation on new DOMRect() PASS DOMRectList interface: existence and properties of interface object PASS DOMRectList interface object length PASS DOMRectList interface object name @@ -157,7 +157,7 @@ PASS DOMQuad interface: new DOMQuad() must inherit property "p4" with the proper type PASS DOMQuad interface: new DOMQuad() must inherit property "getBounds()" with the proper type PASS DOMQuad interface: new DOMQuad() must inherit property "toJSON()" with the proper type -PASS Test default toJSON operation of DOMQuad +PASS DOMQuad interface: default toJSON operation on new DOMQuad() PASS DOMMatrixReadOnly interface: existence and properties of interface object PASS DOMMatrixReadOnly interface object length PASS DOMMatrixReadOnly interface object name @@ -269,7 +269,7 @@ PASS DOMMatrixReadOnly interface: new DOMMatrixReadOnly() must inherit property "toFloat32Array()" with the proper type PASS DOMMatrixReadOnly interface: new DOMMatrixReadOnly() must inherit property "toFloat64Array()" with the proper type PASS DOMMatrixReadOnly interface: new DOMMatrixReadOnly() must inherit property "toJSON()" with the proper type -PASS Test default toJSON operation of DOMMatrixReadOnly +PASS DOMMatrixReadOnly interface: default toJSON operation on new DOMMatrixReadOnly() PASS DOMMatrixReadOnly must be primary interface of DOMMatrixReadOnly.fromMatrix({is2D: false}) PASS Stringification of DOMMatrixReadOnly.fromMatrix({is2D: false}) PASS DOMMatrix interface: existence and properties of interface object
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/document-metadata/the-link-element/link-multiple-error-events.html b/third_party/blink/web_tests/external/wpt/html/semantics/document-metadata/the-link-element/link-multiple-error-events.html new file mode 100644 index 0000000..ea7e496 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/document-metadata/the-link-element/link-multiple-error-events.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<link rel="author" title="Dom Farolino" href="mailto:dom@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-link-element"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<link id=link rel=stylesheet id=style_test + onload="t.unreached_func('Sheet should fail to load')"> +<script> + var t = async_test("Check if the <link>'s error event fires for each style " + + "sheet it fails to load"); + + link.onerror = t.step_func(() => { + link.onerror = t.step_func_done(() => {}); + link.href = 'nonexistent.css?second'; + }); + + link.href = 'nonexistent.css?first'; +</script> + +</head> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/document-metadata/the-link-element/link-multiple-load-events.html b/third_party/blink/web_tests/external/wpt/html/semantics/document-metadata/the-link-element/link-multiple-load-events.html new file mode 100644 index 0000000..24cd5ba --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/document-metadata/the-link-element/link-multiple-load-events.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<link rel="author" title="Dom Farolino" href="mailto:dom@chromium.org"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-link-element"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<link id=link rel=stylesheet id=style_test + onerror="t.unreached_func('Sheet should load successfully')"> +<script> + var t = async_test("Check if the <link>'s load event fires for each style " + + "sheet it loads"); + + link.onload = t.step_func(() => { + link.onload = t.step_func_done(() => {}); + link.href = 'style.css?second'; + }); + + link.href = 'style.css?first'; +</script> + +</head> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/assumptions/allowed-to-play.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/assumptions/allowed-to-play.html.ini index c9fbabe..f9be6a6 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/assumptions/allowed-to-play.html.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/assumptions/allowed-to-play.html.ini
@@ -1,8 +1,10 @@ [allowed-to-play.html] expected: + if product == "edge_webdriver": TIMEOUT if product == "safari": ERROR # https://bugs.webkit.org/show_bug.cgi?id=190775 [<audio> autoplay] expected: + if product == "edge_webdriver": TIMEOUT if product == "safari": FAIL # https://bugs.webkit.org/show_bug.cgi?id=190775
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/assumptions/html-elements.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/assumptions/html-elements.html.ini index b7303c6..5bb1bf5 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/assumptions/html-elements.html.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/assumptions/html-elements.html.ini
@@ -1,4 +1,9 @@ [html-elements.html] + [(pre-req for comparison tests) all CSS short-hand supported] + expected: + if product == "edge_webdriver": FAIL + + [Compare CSS span definitions (only valid if pre-reqs pass)] expected: if product == "safari": FAIL # https://webkit.org/show_bug.cgi?id=187052
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/reftest/size.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/reftest/size.html.ini new file mode 100644 index 0000000..1c6cd9e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/reftest/size.html.ini
@@ -0,0 +1,4 @@ +[size.html] + type: reftest + expected: + if product == "edge_webdriver": FAIL # https://github.com/web-platform-tests/wpt/issues/15159
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/context.any.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/context.any.js.ini index f985548..ff57a13 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/context.any.js.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/context.any.js.ini
@@ -1,4 +1,5 @@ [context.any.sharedworker.html] [context] expected: + if product == "edge_webdriver": FAIL if product == "safari": FAIL # https://bugs.webkit.org/show_bug.cgi?id=149850
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini index b296462..e4a96de 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini
@@ -1,4 +1,27 @@ +[order-of-metas.any.worker.html] + expected: + if product == "edge_webdriver": TIMEOUT + + +[order-of-metas.any.html] + [<meta name=timeout> exists] + expected: + if product == "edge_webdriver": FAIL + + [order-of-metas.any.sharedworker.html] + [foo\n] + expected: + if product == "edge_webdriver": FAIL + + [foo] expected: + if product == "edge_webdriver": FAIL if product == "safari": FAIL # https://bugs.webkit.org/show_bug.cgi?id=149850 + + +[order-of-metas.window.html] + [<meta name=timeout> exists] + expected: + if product == "edge_webdriver": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.window.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.window.js.ini new file mode 100644 index 0000000..20e4cbad --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.window.js.ini
@@ -0,0 +1,4 @@ +[order-of-metas.window.html] + [<meta name=timeout> exists] + expected: + if product == "edge_webdriver": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini index 272935a..f483bca 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini
@@ -1,4 +1,5 @@ [secure-context.https.any.sharedworker.html] [secure-context] expected: + if product == "edge_webdriver": FAIL if product == "safari": FAIL # https://bugs.webkit.org/show_bug.cgi?id=149850
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/title.any.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/title.any.js.ini index 6852b8033..cbae6b15 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/title.any.js.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/title.any.js.ini
@@ -1,4 +1,20 @@ +[title.any.html] + [foobar\n] + expected: + if product == "edge_webdriver": FAIL + + [title.any.sharedworker.html] + [foobar\n] + expected: + if product == "edge_webdriver": FAIL + + [foobar] expected: if product == "safari": FAIL # https://bugs.webkit.org/show_bug.cgi?id=149850 + + +[title.any.worker.html] + expected: + if product == "edge_webdriver": TIMEOUT
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/file_upload.sub.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/file_upload.sub.html.ini new file mode 100644 index 0000000..42c9811 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/testdriver/file_upload.sub.html.ini
@@ -0,0 +1,3 @@ +[file_upload.sub.html] + expected: + if product == "edge_webdriver": ERROR
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/mediacapture-streams/idlharness.https.window-expected.txt index b0be4a5..2720255 100644 --- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/idlharness.https.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/mediacapture-streams/idlharness.https.window-expected.txt
@@ -157,7 +157,7 @@ PASS MediaDeviceInfo interface: [object InputDeviceInfo] must inherit property "label" with the proper type PASS MediaDeviceInfo interface: [object InputDeviceInfo] must inherit property "groupId" with the proper type PASS MediaDeviceInfo interface: [object InputDeviceInfo] must inherit property "toJSON()" with the proper type -PASS Test default toJSON operation of InputDeviceInfo +PASS MediaDeviceInfo interface: default toJSON operation on [object InputDeviceInfo] PASS Navigator interface: attribute mediaDevices PASS Navigator interface: operation getUserMedia(MediaStreamConstraints, NavigatorUserMediaSuccessCallback, NavigatorUserMediaErrorCallback) PASS Navigator interface: navigator must inherit property "mediaDevices" with the proper type
diff --git a/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any-expected.txt b/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any-expected.txt index 0b65efbd..7d03cc1 100644 --- a/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any-expected.txt
@@ -70,6 +70,6 @@ PASS PerformanceEntry interface: mark must inherit property "startTime" with the proper type PASS PerformanceEntry interface: mark must inherit property "duration" with the proper type PASS PerformanceEntry interface: mark must inherit property "toJSON()" with the proper type -PASS Test default toJSON operation of PerformanceMark +PASS PerformanceEntry interface: default toJSON operation on mark Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any.serviceworker-expected.txt index 0b65efbd..7d03cc1 100644 --- a/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any.serviceworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any.serviceworker-expected.txt
@@ -70,6 +70,6 @@ PASS PerformanceEntry interface: mark must inherit property "startTime" with the proper type PASS PerformanceEntry interface: mark must inherit property "duration" with the proper type PASS PerformanceEntry interface: mark must inherit property "toJSON()" with the proper type -PASS Test default toJSON operation of PerformanceMark +PASS PerformanceEntry interface: default toJSON operation on mark Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any.sharedworker-expected.txt index 0b65efbd..7d03cc1 100644 --- a/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any.sharedworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any.sharedworker-expected.txt
@@ -70,6 +70,6 @@ PASS PerformanceEntry interface: mark must inherit property "startTime" with the proper type PASS PerformanceEntry interface: mark must inherit property "duration" with the proper type PASS PerformanceEntry interface: mark must inherit property "toJSON()" with the proper type -PASS Test default toJSON operation of PerformanceMark +PASS PerformanceEntry interface: default toJSON operation on mark Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any.worker-expected.txt index 0b65efbd..7d03cc1 100644 --- a/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/performance-timeline/idlharness.any.worker-expected.txt
@@ -70,6 +70,6 @@ PASS PerformanceEntry interface: mark must inherit property "startTime" with the proper type PASS PerformanceEntry interface: mark must inherit property "duration" with the proper type PASS PerformanceEntry interface: mark must inherit property "toJSON()" with the proper type -PASS Test default toJSON operation of PerformanceMark +PASS PerformanceEntry interface: default toJSON operation on mark Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/resources/idlharness.js b/third_party/blink/web_tests/external/wpt/resources/idlharness.js index 8b7a1e2..b765d1f 100644 --- a/third_party/blink/web_tests/external/wpt/resources/idlharness.js +++ b/third_party/blink/web_tests/external/wpt/resources/idlharness.js
@@ -2309,7 +2309,7 @@ } } -IdlInterface.prototype.test_to_json_operation = function(memberHolderObject, member) { +IdlInterface.prototype.test_to_json_operation = function(desc, memberHolderObject, member) { var instanceName = memberHolderObject && memberHolderObject.constructor.name || member.name + " object"; if (member.has_extended_attribute("Default")) { @@ -2325,12 +2325,12 @@ this.array.assert_type_is(json[k], type); delete json[k]; }, this); - }.bind(this), "Test default toJSON operation of " + instanceName); + }.bind(this), this.name + " interface: default toJSON operation on " + desc); } else { subsetTestByKey(this.name, test, function() { assert_true(this.array.is_json_type(member.idlType), JSON.stringify(member.idlType) + " is not an appropriate return value for the toJSON operation of " + instanceName); this.array.assert_type_is(memberHolderObject.toJSON(), member.idlType); - }.bind(this), "Test toJSON operation of " + instanceName); + }.bind(this), this.name + " interface: toJSON operation on " + desc); } }; @@ -2722,7 +2722,7 @@ } if (member.is_to_json_regular_operation()) { - this.test_to_json_operation(obj, member); + this.test_to_json_operation(desc, obj, member); } } };
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/broadcastchannel-success-and-failure.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/broadcastchannel-success-and-failure.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/broadcastchannel-success-and-failure.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/broadcastchannel-success-and-failure.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/broadcastchannel-success.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/broadcastchannel-success.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/broadcastchannel-success.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/broadcastchannel-success.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/identity-not-preserved.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/identity-not-preserved.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/identity-not-preserved.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/identity-not-preserved.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/incrementer.wasm b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/incrementer.wasm similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/incrementer.wasm rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/incrementer.wasm Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/nested-worker-success-sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/nested-worker-success-sharedworker-expected.txt similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/nested-worker-success-sharedworker-expected.txt rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/nested-worker-success-sharedworker-expected.txt
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/nested-worker-success.any.js b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/nested-worker-success.any.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/nested-worker-success.any.js rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/nested-worker-success.any.js
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/nested-worker-success.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/nested-worker-success.any.sharedworker-expected.txt similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/nested-worker-success.any.sharedworker-expected.txt rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/nested-worker-success.any.sharedworker-expected.txt
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/no-transferring.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/no-transferring.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/no-transferring.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/no-transferring.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/blank.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/blank.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/blank.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/blank.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/broadcastchannel-iframe.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/broadcastchannel-iframe.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/broadcastchannel-iframe.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/broadcastchannel-iframe.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/broadcastchannel-sharedworker.js b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/broadcastchannel-sharedworker.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/broadcastchannel-sharedworker.js rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/broadcastchannel-sharedworker.js
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/broadcastchannel-worker.js b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/broadcastchannel-worker.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/broadcastchannel-worker.js rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/broadcastchannel-worker.js
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/create-empty-wasm-module.js b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/create-empty-wasm-module.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/create-empty-wasm-module.js rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/create-empty-wasm-module.js
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/echo-iframe.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/echo-iframe.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/echo-iframe.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/echo-iframe.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/echo-worker.js b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/echo-worker.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/echo-worker.js rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/echo-worker.js
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/incrementer-iframe-domain.sub.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/incrementer-iframe-domain.sub.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/incrementer-iframe-domain.sub.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/incrementer-iframe-domain.sub.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/incrementer-iframe.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/incrementer-iframe.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/incrementer-iframe.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/incrementer-iframe.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/incrementer-popup.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/incrementer-popup.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/incrementer-popup.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/incrementer-popup.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/incrementer-worker-with-channel.js b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/incrementer-worker-with-channel.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/incrementer-worker-with-channel.js rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/incrementer-worker-with-channel.js
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/incrementer-worker.js b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/incrementer-worker.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/incrementer-worker.js rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/incrementer-worker.js
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/incrementer.wasm b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/incrementer.wasm similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/incrementer.wasm rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/incrementer.wasm Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/nested-iframe-1.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/nested-iframe-1.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/nested-iframe-1.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/nested-iframe-1.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/nested-iframe-2.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/nested-iframe-2.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/nested-iframe-2.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/nested-iframe-2.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/nested-iframe-3.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/nested-iframe-3.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/nested-iframe-3.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/nested-iframe-3.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/nested-iframe-4-incrementer.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/nested-iframe-4-incrementer.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/nested-iframe-4-incrementer.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/nested-iframe-4-incrementer.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/serviceworker-failure.js b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/serviceworker-failure.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/serviceworker-failure.js rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/serviceworker-failure.js
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/sharedworker-failure.js b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/sharedworker-failure.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/sharedworker-failure.js rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/sharedworker-failure.js
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/resources/test-incrementer.js b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/test-incrementer.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/resources/test-incrementer.js rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/resources/test-incrementer.js
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/serialization-via-history.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/serialization-via-history.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/serialization-via-history.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/serialization-via-history.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/serialization-via-idb.any.js b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/serialization-via-idb.any.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/serialization-via-idb.any.js rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/serialization-via-idb.any.js
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/serialization-via-notifications-api.any.js b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/serialization-via-notifications-api.any.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/serialization-via-notifications-api.any.js rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/serialization-via-notifications-api.any.js
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/window-domain-success.sub.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-domain-success.sub.html similarity index 93% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/window-domain-success.sub.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-domain-success.sub.html index 51d4c5c..07360d82 100644 --- a/third_party/blink/web_tests/external/wpt/wasm/serialization/window-domain-success.sub.html +++ b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-domain-success.sub.html
@@ -18,7 +18,7 @@ iframe.onload = t.step_func(() => { resolve(testSharingViaIncrementerScript(t, window, "window", iframe.contentWindow, "iframe", "*")); }); - iframe.src = "//{{domains[www1]}}:{{location[port]}}/wasm/serialization/resources/incrementer-iframe-domain.sub.html"; + iframe.src = "//{{domains[www1]}}:{{location[port]}}/wasm/serialization/module/resources/incrementer-iframe-domain.sub.html"; document.body.appendChild(iframe); }); }, "postMessaging to a same-origin-domain (but not same-origin) iframe allows them to instantiate");
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/window-messagechannel-success.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-messagechannel-success.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/window-messagechannel-success.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-messagechannel-success.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/window-serviceworker-failure.https.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-serviceworker-failure.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/window-serviceworker-failure.https.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-serviceworker-failure.https.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/window-sharedworker-failure.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-sharedworker-failure.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/window-sharedworker-failure.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-sharedworker-failure.html
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/window-similar-but-cross-origin-success.sub.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-similar-but-cross-origin-success.sub.html similarity index 94% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/window-similar-but-cross-origin-success.sub.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-similar-but-cross-origin-success.sub.html index 070cf0a..a615547 100644 --- a/third_party/blink/web_tests/external/wpt/wasm/serialization/window-similar-but-cross-origin-success.sub.html +++ b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-similar-but-cross-origin-success.sub.html
@@ -18,7 +18,7 @@ iframe.onload = t.step_func(() => { resolve(testSharingViaIncrementerScript(t, window, "window", iframe.contentWindow, "iframe", "*")); }); - iframe.src = "//{{domains[www1]}}:{{location[port]}}/wasm/serialization/resources/incrementer-iframe.html"; + iframe.src = "//{{domains[www1]}}:{{location[port]}}/wasm/serialization/module/resources/incrementer-iframe.html"; document.body.appendChild(iframe); }); }, "postMessaging to a not same-origin-domain, but similar origin, iframe allows them to instantiate");
diff --git a/third_party/blink/web_tests/external/wpt/wasm/serialization/window-simple-success.html b/third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-simple-success.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/wasm/serialization/window-simple-success.html rename to third_party/blink/web_tests/external/wpt/wasm/serialization/module/window-simple-success.html
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/idlharness.https.window-expected.txt index 12913bcb8..a557706 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc/idlharness.https.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webrtc/idlharness.https.window-expected.txt
@@ -140,7 +140,7 @@ PASS RTCSessionDescription interface: new RTCSessionDescription({ type: 'offer' }) must inherit property "type" with the proper type FAIL RTCSessionDescription interface: new RTCSessionDescription({ type: 'offer' }) must inherit property "sdp" with the proper type assert_equals: expected "string" but got "object" PASS RTCSessionDescription interface: new RTCSessionDescription({ type: 'offer' }) must inherit property "toJSON()" with the proper type -FAIL Test default toJSON operation of RTCSessionDescription assert_equals: expected "string" but got "object" +FAIL RTCSessionDescription interface: default toJSON operation on new RTCSessionDescription({ type: 'offer' }) assert_equals: expected "string" but got "object" PASS RTCIceCandidate interface: existence and properties of interface object PASS RTCIceCandidate interface object length PASS RTCIceCandidate interface object name @@ -179,7 +179,7 @@ FAIL RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "relatedPort" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeMismatchError: Failed to construct 'RTCIceCandidate': The 'candidate' property is not a string, or is empty." FAIL RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "usernameFragment" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeMismatchError: Failed to construct 'RTCIceCandidate': The 'candidate' property is not a string, or is empty." FAIL RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "toJSON()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeMismatchError: Failed to construct 'RTCIceCandidate': The 'candidate' property is not a string, or is empty." -FAIL Test toJSON operation of toJSON object Cannot read property 'toJSON' of undefined +FAIL RTCIceCandidate interface: toJSON operation on new RTCIceCandidate({ sdpMid: 1 }) Cannot read property 'toJSON' of undefined PASS RTCPeerConnectionIceEvent interface: existence and properties of interface object PASS RTCPeerConnectionIceEvent interface object length PASS RTCPeerConnectionIceEvent interface object name
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-loose-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-loose-expected.txt deleted file mode 100644 index 0009750..0000000 --- a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-loose-expected.txt +++ /dev/null
@@ -1,13 +0,0 @@ -This is a testharness.js-based test. -PASS 30FB KATAKANA MIDDLE DOT may appear at line start if ja and loose -PASS FF1A FULLWIDTH COLON may appear at line start if ja and loose -PASS FF1B FULLWIDTH SEMICOLON may appear at line start if ja and loose -FAIL FF65 HALFWIDTH KATAKANA MIDDLE DOT may appear at line start if ja and loose assert_true: expected true got false -PASS 203C DOUBLE EXCLAMATION MARK may appear at line start if ja and loose -FAIL 2047 DOUBLE QUESTION MARK may appear at line start if ja and loose assert_true: expected true got false -FAIL 2048 QUESTION EXCLAMATION MARK may appear at line start if ja and loose assert_true: expected true got false -PASS 2049 EXCLAMATION QUESTION MARK may appear at line start if ja and loose -PASS FF01 FULLWIDTH EXCLAMATION MARK may appear at line start if ja and loose -PASS FF1F FULLWIDTH QUESTION MARK may appear at line start if ja and loose -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-loose-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-loose-expected.txt deleted file mode 100644 index f3d9c85..0000000 --- a/third_party/blink/web_tests/platform/win7/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-loose-expected.txt +++ /dev/null
@@ -1,13 +0,0 @@ -This is a testharness.js-based test. -PASS 00B0 DEGREE SIGN may appear at line start if ja and loose -PASS 2030 PER MILLE SIGN may appear at line start if ja and loose -PASS 2032 PRIME may appear at line start if ja and loose -PASS 2033 DOUBLE PRIME may appear at line start if ja and loose -PASS 2035 REVERSED PRIME may appear at line start if ja and loose -FAIL 2103 DEGREE CELSIUS may appear at line start if ja and loose assert_true: expected true got false -FAIL 2109 DEGREE FAHRENHEIT may appear at line start if ja and loose assert_true: expected true got false -PASS FE6A SMALL PERCENT SIGN may appear at line start if ja and loose -PASS FF05 FULLWIDTH PERCENT SIGN may appear at line start if ja and loose -PASS FFE0 FULLWIDTH CENT SIGN may appear at line start if ja and loose -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/http/tests/navigation/README.txt b/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/http/tests/navigation/README.txt new file mode 100644 index 0000000..2ff197f5 --- /dev/null +++ b/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/http/tests/navigation/README.txt
@@ -0,0 +1,2 @@ +This directory is for running navigation tests with the FeaturePolicyForSandbox +runtime flag.
diff --git a/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/http/tests/security/README.txt b/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/http/tests/security/README.txt new file mode 100644 index 0000000..b71a013 --- /dev/null +++ b/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/http/tests/security/README.txt
@@ -0,0 +1,2 @@ +This directory is for running tests with the FeaturePolicyForSandbox +runtime flag.
diff --git a/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/mhtml/README.txt b/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/mhtml/README.txt new file mode 100644 index 0000000..b71a013 --- /dev/null +++ b/third_party/blink/web_tests/virtual/feature-policy-for-sandbox/mhtml/README.txt
@@ -0,0 +1,2 @@ +This directory is for running tests with the FeaturePolicyForSandbox +runtime flag.
diff --git a/third_party/blink/web_tests/virtual/not-site-per-process/README.md b/third_party/blink/web_tests/virtual/not-site-per-process/README.md index 6fc09489..2c70610a 100644 --- a/third_party/blink/web_tests/virtual/not-site-per-process/README.md +++ b/third_party/blink/web_tests/virtual/not-site-per-process/README.md
@@ -42,8 +42,8 @@ - external/wpt/html/browsers/the-windowproxy-exotic-object/windowproxy-prototype-setting-same-origin-domain.sub.html - external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-domain-success.sub.html - external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-similar-but-cross-origin-success.sub.html -- external/wpt/wasm/serialization/window-domain-success.sub.html -- external/wpt/wasm/serialization/window-similar-but-cross-origin-success.sub.html +- external/wpt/wasm/serialization/module/window-domain-success.sub.html +- external/wpt/wasm/serialization/module/window-similar-but-cross-origin-success.sub.html ## Tests that need further investigation and/or decisions
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt index b4d15e8..7416e921 100644 --- a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt +++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/idlharness.https.window-expected.txt
@@ -140,7 +140,7 @@ PASS RTCSessionDescription interface: new RTCSessionDescription({ type: 'offer' }) must inherit property "type" with the proper type FAIL RTCSessionDescription interface: new RTCSessionDescription({ type: 'offer' }) must inherit property "sdp" with the proper type assert_equals: expected "string" but got "object" PASS RTCSessionDescription interface: new RTCSessionDescription({ type: 'offer' }) must inherit property "toJSON()" with the proper type -FAIL Test default toJSON operation of RTCSessionDescription assert_equals: expected "string" but got "object" +FAIL RTCSessionDescription interface: default toJSON operation on new RTCSessionDescription({ type: 'offer' }) assert_equals: expected "string" but got "object" PASS RTCIceCandidate interface: existence and properties of interface object PASS RTCIceCandidate interface object length PASS RTCIceCandidate interface object name @@ -179,7 +179,7 @@ FAIL RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "relatedPort" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeMismatchError: Failed to construct 'RTCIceCandidate': The 'candidate' property is not a string, or is empty." FAIL RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "usernameFragment" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeMismatchError: Failed to construct 'RTCIceCandidate': The 'candidate' property is not a string, or is empty." FAIL RTCIceCandidate interface: new RTCIceCandidate({ sdpMid: 1 }) must inherit property "toJSON()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeMismatchError: Failed to construct 'RTCIceCandidate': The 'candidate' property is not a string, or is empty." -FAIL Test toJSON operation of toJSON object Cannot read property 'toJSON' of undefined +FAIL RTCIceCandidate interface: toJSON operation on new RTCIceCandidate({ sdpMid: 1 }) Cannot read property 'toJSON' of undefined PASS RTCPeerConnectionIceEvent interface: existence and properties of interface object PASS RTCPeerConnectionIceEvent interface object length PASS RTCPeerConnectionIceEvent interface object name
diff --git a/third_party/zlib/BUILD.gn b/third_party/zlib/BUILD.gn index 51d477a..9f7897a 100644 --- a/third_party/zlib/BUILD.gn +++ b/third_party/zlib/BUILD.gn
@@ -120,6 +120,9 @@ if (use_arm_neon_optimizations) { defines = [ "INFLATE_CHUNK_SIMD_NEON" ] + if (current_cpu == "arm64") { + defines += [ "INFLATE_CHUNK_READ_64LE" ] + } } }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 32390d5e..cb09cb6 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -1210,6 +1210,12 @@ </int> </enum> +<enum name="AndroidSmsFcmMessageType"> + <int value="0" label="Start"/> + <int value="1" label="Resume"/> + <int value="2" label="Stop"/> +</enum> + <enum name="AndroidTabCloseUndoToastEvent"> <int value="0" label="Undo Shown (Cold)"/> <int value="1" label="Undo Shown (Warm)"/> @@ -51257,6 +51263,22 @@ <int value="3" label="Disabled"/> </enum> +<enum name="SyncGetUpdatesOrigin"> + <summary> + Equivalent to proto SyncEnums.GetUpdatesOrigin: represents a reason for a + client to issue a GetUpdates request to the sync server. + </summary> + <int value="0" label="UNKNOWN_ORIGIN"/> + <int value="4" label="PERIODIC"/> + <int value="7" label="NEWLY_SUPPORTED_DATATYPE"/> + <int value="8" label="MIGRATION"/> + <int value="9" label="NEW_CLIENT"/> + <int value="10" label="RECONFIGURATION"/> + <int value="12" label="GU_TRIGGER"/> + <int value="13" label="RETRY"/> + <int value="14" label="PROGRAMMATIC"/> +</enum> + <enum name="SyncGetUpdatesToken"> <int value="0" label="New token"/> <int value="1" label="Same token"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index ca0e5bf..2132b39 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -3040,6 +3040,36 @@ </summary> </histogram> +<histogram name="AndroidSms.FcmMessageDispatchFailure" + enum="AndroidSmsFcmMessageType"> + <owner>azeemarshad@chromium.org</owner> + <summary> + Records message types for which all retry attempts failed when dispatching + to Android Messages for Web Service-Worker. This is recorded when using FCM + web push for background notificaitons. + </summary> +</histogram> + +<histogram name="AndroidSms.FcmMessageDispatchRetry" + enum="AndroidSmsFcmMessageType"> + <owner>azeemarshad@chromium.org</owner> + <summary> + Records message types for which a retry was attempted when dispatching to + Android Messages for Web Service-Worker. This is recorded when using FCM web + push for background notificaitons. + </summary> +</histogram> + +<histogram name="AndroidSms.FcmMessageDispatchSuccess" + enum="AndroidSmsFcmMessageType"> + <owner>azeemarshad@chromium.org</owner> + <summary> + Records message types for which dispatching to Android Messages for Web + Service-Worker succeeded. This is recorded when using FCM web push for + background notificaitons. + </summary> +</histogram> + <histogram name="AndroidSms.MultiDeviceFeatureState" enum="MultiDevice_FeatureState"> <owner>jlklein@chromium.org</owner> @@ -113733,6 +113763,7 @@ </histogram> <histogram base="true" name="Sync.E2ELatency" units="ms" expires_after="M75"> + <owner>mastiz@chromium.org</owner> <owner>melandory@chromium.org</owner> <summary> Recorded for a subset of users (Finch-controlled) per sync reflection, that @@ -114413,6 +114444,18 @@ </summary> </histogram> +<histogram name="Sync.NonReflectionUpdateFreshnessPossiblySkewed" units="ms"> + <owner>mastiz@chromium.org</owner> + <owner>melandory@chromium.org</owner> + <summary> + Freshness of the sync data per received sync entity update, excluding + reflections. The time represents the clock difference from the model being + modified (usually on another device) until the change is processing by this + instance of the browser. Beware of potential clock skew due to two clients + being involved. + </summary> +</histogram> + <histogram name="Sync.PageRevisitBookmarksDuration" units="ms"> <obsolete> Deprecated in M66. @@ -114675,6 +114718,15 @@ </summary> </histogram> +<histogram name="Sync.PostedGetUpdatesOrigin" enum="SyncGetUpdatesOrigin"> + <owner>mastiz@chromium.org</owner> + <owner>jkrcal@chromium.org</owner> + <summary> + Emitted per network GetUpdates() request to the sync server, it represents + the reason for sending such GetUpdates() request. + </summary> +</histogram> + <histogram name="Sync.PreferenceAssociationTime" units="ms"> <obsolete> Deprecated in M53. @@ -139915,6 +139967,14 @@ <affected-histogram name="PasswordManager.TotalAccountsHiRes.WithScheme"/> </histogram_suffixes> +<histogram_suffixes name="PasswordSecurityOrigin" separator="."> + <suffix name="InsecureOrigin" + label="The recording took place on an insecure origin."/> + <suffix name="SecureOrigin" + label="The recording took place on a secure origin."/> + <affected-histogram name="PasswordManager.FillingAssistance"/> +</histogram_suffixes> + <histogram_suffixes name="PaymentRequestOutcome" separator="."> <suffix name="Completed" label="The Payment Request was completed"/> <suffix name="OtherAborted" @@ -143195,6 +143255,7 @@ </affected-histogram> <affected-histogram name="Sync.ModelTypeEntityChange3"/> <affected-histogram name="Sync.ModelTypeMemoryKB"/> + <affected-histogram name="Sync.NonReflectionUpdateFreshnessPossiblySkewed"/> <affected-histogram name="Sync.ReceivedDataTypeGetUpdatesResponseWithToken"/> <affected-histogram name="Sync.USSMigrationEntityCount"/> </histogram_suffixes> @@ -143395,6 +143456,16 @@ <affected-histogram name="Tabs.UsedInInterval.Count"/> </histogram_suffixes> +<histogram_suffixes name="TaskSchedulerCancelledDelayedTasks" separator="."> + <suffix name="Browser" label="TaskScheduler for the browser process."/> + <suffix name="ContentChild" + label="TaskSchedulers for various instantiations of + content::ChildProcess."/> + <suffix name="Renderer" label="TaskSchedulers for renderer processes."/> + <affected-histogram name="TaskScheduler.NumCancelledDelayedTasks"/> + <affected-histogram name="TaskScheduler.PercentCancelledDelayedTasks"/> +</histogram_suffixes> + <histogram_suffixes name="TaskSchedulerMayBlock" separator="."> <obsolete> Deprecated 1/2018. Merged with TaskSchedulerTaskPriority into @@ -143437,12 +143508,10 @@ <affected-histogram name="TaskScheduler.DetachDuration"/> <affected-histogram name="TaskScheduler.HeartbeatLatencyMicroseconds"/> <affected-histogram name="TaskScheduler.NumActiveWorkers"/> - <affected-histogram name="TaskScheduler.NumCancelledDelayedTasks"/> <affected-histogram name="TaskScheduler.NumTasksBeforeDetach"/> <affected-histogram name="TaskScheduler.NumTasksBetweenWaits"/> <affected-histogram name="TaskScheduler.NumTasksRunWhileQueuing"/> <affected-histogram name="TaskScheduler.NumWorkers"/> - <affected-histogram name="TaskScheduler.PercentCancelledDelayedTasks"/> <affected-histogram name="TaskScheduler.TaskLatencyMicroseconds"/> </histogram_suffixes>
diff --git a/tools/perf/OWNERS b/tools/perf/OWNERS index 21aa6c8..48cdce1 100644 --- a/tools/perf/OWNERS +++ b/tools/perf/OWNERS
@@ -2,7 +2,6 @@ crouleau@chromium.org eyaich@chromium.org sullivan@chromium.org -nednguyen@google.com # For changes related to ChromeOS. achuith@chromium.org
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index f5721c6..f734db9 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -18,8 +18,8 @@ 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.noisy_benchmark_1,nednguyen@google.com,Speed>Telemetry,, -dummy_benchmark.stable_benchmark_1,nednguyen@google.com,Speed>Telemetry,, +dummy_benchmark.noisy_benchmark_1,crouleau@chromium.org,Speed>Telemetry,, +dummy_benchmark.stable_benchmark_1,crouleau@chromium.org,Speed>Telemetry,, gpu_perftests,"reveman@chromium.org, chrome-gpu-perf-owners@chromium.org",Internals>GPU,, jetstream,hablich@chromium.org,Blink>JavaScript,, kraken,hablich@chromium.org,Blink>JavaScript,,
diff --git a/tools/perf/benchmarks/dummy_benchmark.py b/tools/perf/benchmarks/dummy_benchmark.py index 64d02403..8c15c56 100644 --- a/tools/perf/benchmarks/dummy_benchmark.py +++ b/tools/perf/benchmarks/dummy_benchmark.py
@@ -39,7 +39,7 @@ page_set = dummy_story_set.DummyStorySet -@benchmark.Info(emails=['nednguyen@google.com'], component='Speed>Telemetry') +@benchmark.Info(emails=['crouleau@chromium.org'], component='Speed>Telemetry') class DummyBenchmarkOne(_DummyBenchmark): """A low noise benchmark with mean=100 & std=1.""" @@ -51,7 +51,7 @@ return 'dummy_benchmark.stable_benchmark_1' -@benchmark.Info(emails=['nednguyen@google.com'], component='Speed>Telemetry') +@benchmark.Info(emails=['crouleau@chromium.org'], component='Speed>Telemetry') class DummyBenchmarkTwo(_DummyBenchmark): """A noisy benchmark with mean=50 & std=20."""
diff --git a/tools/perf/contrib/blink_perf_cmdline/OWNERS b/tools/perf/contrib/blink_perf_cmdline/OWNERS index 93a9996c..33952d7 100644 --- a/tools/perf/contrib/blink_perf_cmdline/OWNERS +++ b/tools/perf/contrib/blink_perf_cmdline/OWNERS
@@ -1,3 +1,2 @@ charliea@chromium.org -nednguyen@google.com wangxianzhu@chromium.org
diff --git a/tools/perf/contrib/tracing/OWNERS b/tools/perf/contrib/tracing/OWNERS index 63ef69a..6f75aa01 100644 --- a/tools/perf/contrib/tracing/OWNERS +++ b/tools/perf/contrib/tracing/OWNERS
@@ -1,3 +1,2 @@ -nednguyen@google.com oysteine@chromium.org zhenw@chromium.org
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index 94f1443..a85661fa 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -230,6 +230,7 @@ crbug.com/874935 [ Nexus_5 ] rendering.mobile/yahoo_news_2018 [ Skip ] crbug.com/910207 [ Nexus_5X ] rendering.mobile/yahoo_news_2018 [ Skip ] crbug.com/901526 [ All ] rendering.mobile/microsoft_fireflies [ Skip ] +crbug.com/924400 [ Nexus6_Webview ] rendering.mobile/canvas_animation_no_clear [ Skip ] # Benchmark: rasterize_and_record_micro.top_25 crbug.com/764543 [ All ] rasterize_and_record_micro.top_25/file://static_top_25/wikipedia.html [ Skip ] @@ -256,6 +257,8 @@ crbug.com/911214 [ Win_10 ] system_health.common_desktop/multitab:misc:typical24 [ Skip ] crbug.com/923106 [ Linux ] system_health.common_desktop/browse:media:tumblr [ Skip ] crbug.com/923106 [ Win ] system_health.common_desktop/browse:media:tumblr [ Skip ] +crbug.com/927409 [ Win ] system_health.common_desktop/browse:social:tumblr_infinite_scroll:2018 [ Skip ] +crbug.com/927409 [ Linux ] system_health.common_desktop/browse:social:tumblr_infinite_scroll:2018 [ Skip ] # Benchmark: system_health.common_mobile crbug.com/914390 [ Nexus_5 ] system_health.common_mobile/browse:chrome:newtab [ Skip ] @@ -376,6 +379,9 @@ crbug.com/906654 [ All ] v8.browsing_desktop-future/browse:social:twitter_infinite_scroll [ Skip ] crbug.com/906654 [ All ] v8.browsing_desktop-future/browse:social:twitter [ Skip ] crbug.com/906654 [ All ] v8.browsing_desktop-future/browse:tech:discourse_infinite_scroll [ Skip ] +crbug.com/927409 [ Linux ] v8.browsing_desktop-future/browse:social:tumblr_infinite_scroll:2018 [ Skip ] +crbug.com/927409 [ Win ] v8.browsing_desktop-future/browse:social:tumblr_infinite_scroll:2018 [ Skip ] + # Benchmark: v8.browsing_mobile crbug.com/714650 [ Android ] v8.browsing_mobile/browse:news:globo [ Skip ]
diff --git a/tools/perf/scripts_smoke_unittest.py b/tools/perf/scripts_smoke_unittest.py index f2b130f..09ca602 100644 --- a/tools/perf/scripts_smoke_unittest.py +++ b/tools/perf/scripts_smoke_unittest.py
@@ -4,8 +4,10 @@ import json import os +import shutil import subprocess import sys +import tempfile import unittest from telemetry import decorators @@ -60,30 +62,34 @@ def testRunTelemetryBenchmarkAsGoogletest(self): options = options_for_unittests.GetCopy() browser_type = options.browser_type + tempdir = tempfile.mkdtemp() + benchmark = 'dummy_benchmark.stable_benchmark_1' return_code, stdout = self.RunPerfScript( - '../../testing/scripts/run_telemetry_benchmark_as_googletest.py ' - 'run_benchmark dummy_benchmark.stable_benchmark_1 --browser=%s ' + '../../testing/scripts/run_performance_tests.py ' + '../../tools/perf/run_benchmark ' + '--benchmarks=dummy_benchmark.stable_benchmark_1 ' + '--browser=%s ' '--isolated-script-test-repeat=2 ' '--isolated-script-test-also-run-disabled-tests ' - '--isolated-script-test-output=output.json ' - '--isolated-script-test-chartjson-output=chartjson_output.json ' - '--output-format=chartjson' % browser_type) + '--isolated-script-test-output=%s' % ( + browser_type, + os.path.join(tempdir, 'output.json') + )) self.assertEquals(return_code, 0, stdout) try: - with open('../../tools/perf/output.json') as f: + # By design, run_performance_tests.py does not output test results + # to the location passed in by --isolated-script-test-output. Instead + # it uses that directory of that file and puts stuff in its own + # subdirectories for the purposes of merging later. + with open(os.path.join(tempdir, benchmark, 'test_results.json')) as f: test_results = json.load(f) self.assertIsNotNone( test_results, 'json_test_results should be populated: ' + stdout) test_repeats = test_results['num_failures_by_type']['PASS'] self.assertEqual( test_repeats, 2, '--isolated-script-test-repeat=2 should work.') - os.remove('../../tools/perf/output.json') except IOError as e: self.fail('json_test_results should be populated: ' + stdout + str(e)) - try: - with open('../../tools/perf/chartjson_output.json') as f: - self.assertIsNotNone( - json.load(f), 'chartjson should be populated: ' + stdout) - os.remove('../../tools/perf/chartjson_output.json') - except IOError as e: - self.fail('chartjson should be populated: ' + stdout + str(e)) + finally: + shutil.rmtree(tempdir) +
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc index 0a3e1d9..85c53f4ec 100644 --- a/ui/accessibility/ax_node.cc +++ b/ui/accessibility/ax_node.cc
@@ -344,7 +344,7 @@ // bool AXNode::IsTableRow() const { - return data().role == ax::mojom::Role::kRow; + return ui::IsTableRow(data().role); } int32_t AXNode::GetTableRowRowIndex() const { @@ -362,12 +362,13 @@ } #if defined(OS_MACOSX) + // // Table column-like nodes. These nodes are only present on macOS. // bool AXNode::IsTableColumn() const { - return data().role == ax::mojom::Role::kColumn; + return ui::IsTableColumn(data().role); } int32_t AXNode::GetTableColColIndex() const { @@ -386,6 +387,7 @@ } return index; } + #endif // defined(OS_MACOSX) // @@ -465,7 +467,7 @@ int32_t AXNode::GetTableCellAriaColIndex() const { AXTableInfo* table_info = GetAncestorTableInfo(); if (!table_info) - return -0; + return 0; int32_t index = GetTableCellIndex(); if (index == -1) @@ -477,11 +479,11 @@ int32_t AXNode::GetTableCellAriaRowIndex() const { AXTableInfo* table_info = GetAncestorTableInfo(); if (!table_info) - return -0; + return -1; int32_t index = GetTableCellIndex(); if (index == -1) - return 0; + return -1; return table_info->cell_data_vector[index].aria_row_index; }
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc index ef06d922..a3642dc 100644 --- a/ui/accessibility/ax_role_properties.cc +++ b/ui/accessibility/ax_role_properties.cc
@@ -297,6 +297,17 @@ } } +bool IsTableColumn(ax::mojom::Role role) { + switch (role) { + case ax::mojom::Role::kColumn: + return true; + case ax::mojom::Role::kLayoutTableColumn: + return kExposeLayoutTableAsDataTable; + default: + return false; + } +} + bool IsTableHeader(ax::mojom::Role role) { switch (role) { case ax::mojom::Role::kColumnHeader:
diff --git a/ui/accessibility/ax_role_properties.h b/ui/accessibility/ax_role_properties.h index dc056e7..d79ec98 100644 --- a/ui/accessibility/ax_role_properties.h +++ b/ui/accessibility/ax_role_properties.h
@@ -72,13 +72,18 @@ // Returns true if the provided role belongs to a non-interactive list. AX_EXPORT bool IsStaticList(const ax::mojom::Role role); +// Returns true if the provided role belongs to a table or grid column, and the +// table is not used for layout purposes. +AX_EXPORT bool IsTableColumn(ax::mojom::Role role); + // Returns true if the provided role belongs to a table header. AX_EXPORT bool IsTableHeader(ax::mojom::Role role); // Returns true if the provided role belongs to a table, a grid or a treegrid. AX_EXPORT bool IsTableLike(const ax::mojom::Role role); -// Returns true if the provided role belongs to a table or grid row. +// Returns true if the provided role belongs to a table or grid row, and the +// table is not used for layout purposes. AX_EXPORT bool IsTableRow(ax::mojom::Role role); // Returns true if the provided role supports expand/collapse.
diff --git a/ui/accessibility/ax_table_info.cc b/ui/accessibility/ax_table_info.cc index aa559a202..250b91d 100644 --- a/ui/accessibility/ax_table_info.cc +++ b/ui/accessibility/ax_table_info.cc
@@ -236,7 +236,7 @@ // Update the row count and col count for the whole table to make // sure they're large enough to fit this cell, including its spans. - // The -1 in the ARIA calcluations is because ARIA indices are 1-based, + // The -1 in the ARIA calculations is because ARIA indices are 1-based, // whereas all other indices are zero-based. row_count = std::max(row_count, cell_data.row_index + cell_data.row_span); col_count = std::max(col_count, cell_data.col_index + cell_data.col_span);
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc index 98abda2..5f0630e7 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
@@ -86,7 +86,7 @@ AtkAttributeSet* current = attributes; while (current) { AtkAttribute* attribute = static_cast<AtkAttribute*>(current->data); - ASSERT_NE(0, strcmp(attribute_name, attribute->name)); + ASSERT_NE(0, strcmp(attribute_name, attribute->name)) << attribute_name; current = current->next; } atk_attribute_set_free(attributes); @@ -575,7 +575,7 @@ g_object_unref(root_atk_object); } -TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectIntAttributes) { +TEST_F(AXPlatformNodeAuraLinuxTest, DISABLED_TestAtkObjectIntAttributes) { AXNodeData root_data; root_data.id = 1;
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc index bbe67573..71666916 100644 --- a/ui/accessibility/platform/ax_platform_node_base.cc +++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -228,7 +228,7 @@ int AXPlatformNodeBase::GetIntAttribute( ax::mojom::IntAttribute attribute) const { if (!delegate_) - return false; + return 0; return GetData().GetIntAttribute(attribute); } @@ -426,6 +426,7 @@ if (!table) return nullptr; + DCHECK(table->delegate_); return static_cast<AXPlatformNodeBase*>( table->delegate_->GetFromNodeID(table->delegate_->CellIndexToId(index))); } @@ -444,58 +445,68 @@ if (!table) return nullptr; + DCHECK(table->delegate_); int32_t cell_id = table->delegate_->GetCellId(row, column); return static_cast<AXPlatformNodeBase*>( table->delegate_->GetFromNodeID(cell_id)); } int AXPlatformNodeBase::GetTableCellIndex() const { - return delegate_->GetTableCellIndex(); + if (!delegate_) + return 0; + return int{delegate_->GetTableCellIndex()}; } int AXPlatformNodeBase::GetTableColumn() const { - return GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex); + if (!delegate_) + return 0; + return int{delegate_->GetTableCellColIndex()}; } int AXPlatformNodeBase::GetTableColumnCount() const { + if (!delegate_) + return 0; + AXPlatformNodeBase* table = GetTable(); if (!table) return 0; - return table->GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount); + DCHECK(table->delegate_); + return int{table->delegate_->GetTableColCount()}; } int AXPlatformNodeBase::GetTableColumnSpan() const { - if (!IsCellOrTableHeader(GetData().role)) - return 0; - - int column_span; - if (GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnSpan, - &column_span)) - return column_span; - return 1; + if (!delegate_) + return 1; + return int{delegate_->GetTableCellColSpan()}; } int AXPlatformNodeBase::GetTableRow() const { - return GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex); + if (!delegate_) + return 0; + if (delegate_->IsTableRow()) + return int{delegate_->GetTableRowRowIndex()}; + if (delegate_->IsTableCellOrHeader()) + return int{delegate_->GetTableCellRowIndex()}; + return 0; } int AXPlatformNodeBase::GetTableRowCount() const { + if (!delegate_) + return 0; + AXPlatformNodeBase* table = GetTable(); if (!table) return 0; - return table->GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount); + DCHECK(table->delegate_); + return int{table->delegate_->GetTableRowCount()}; } int AXPlatformNodeBase::GetTableRowSpan() const { - if (!IsCellOrTableHeader(GetData().role)) - return 0; - - int row_span; - if (GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowSpan, &row_span)) - return row_span; - return 1; + if (!delegate_) + return 1; + return int{delegate_->GetTableCellRowSpan()}; } bool AXPlatformNodeBase::HasCaret() { @@ -633,6 +644,8 @@ } void AXPlatformNodeBase::ComputeAttributes(PlatformAttributeList* attributes) { + DCHECK(delegate_) << "Many attributes need to be retrieved from our " + "AXPlatformNodeDelegate."; // Expose some HTML and ARIA attributes in the IAccessible2 attributes string // "display", "tag", and "xml-roles" have somewhat unusual names for // historical reasons. Aside from that virtually every ARIA attribute @@ -781,22 +794,31 @@ if (GetData().role == ax::mojom::Role::kLayoutTable) AddAttributeToList("layout-guess", "true", attributes); - // Expose aria-colcount and aria-rowcount in a table, grid or treegrid. - if (IsTableLike(GetData().role)) { + // Expose aria-colcount and aria-rowcount in a table, grid or treegrid if they + // are different from its physical dimensions. + if (IsTableLike(GetData().role) && + (delegate_->GetTableAriaRowCount() != delegate_->GetTableRowCount() || + delegate_->GetTableAriaColCount() != delegate_->GetTableColCount())) { AddAttributeToList(ax::mojom::IntAttribute::kAriaColumnCount, "colcount", attributes); AddAttributeToList(ax::mojom::IntAttribute::kAriaRowCount, "rowcount", attributes); } - // Expose aria-colindex and aria-rowindex in a cell or row. - if (IsCellOrTableHeader(GetData().role) || - GetData().role == ax::mojom::Role::kRow) { - if (GetData().role != ax::mojom::Role::kRow) - AddAttributeToList(ax::mojom::IntAttribute::kAriaCellColumnIndex, - "colindex", attributes); - AddAttributeToList(ax::mojom::IntAttribute::kAriaCellRowIndex, "rowindex", - attributes); + if (IsCellOrTableHeader(GetData().role) || IsTableRow(GetData().role)) { + // Expose aria-colindex and aria-rowindex in a cell or row only if they are + // different from the table's physical coordinates. + if (delegate_->GetTableCellAriaRowIndex() != + delegate_->GetTableCellRowIndex() || + delegate_->GetTableCellAriaColIndex() != + delegate_->GetTableCellColIndex()) { + if (!IsTableRow(GetData().role)) { + AddAttributeToList(ax::mojom::IntAttribute::kAriaCellColumnIndex, + "colindex", attributes); + } + AddAttributeToList(ax::mojom::IntAttribute::kAriaCellRowIndex, "rowindex", + attributes); + } // Experimental: expose aria-rowtext / aria-coltext. Not standardized // yet, but obscure enough that it's safe to expose.
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index 58547edf..8303f08 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -2628,7 +2628,7 @@ return E_INVALIDARG; *n_column_header_cells = 0; - if (GetData().role != ax::mojom::Role::kCell) + if (!IsCellOrTableHeader(GetData().role)) return S_FALSE; AXPlatformNodeBase* table = GetTable(); @@ -2697,13 +2697,12 @@ return E_INVALIDARG; *n_row_header_cells = 0; - if (GetData().role != ax::mojom::Role::kCell) + if (!IsCellOrTableHeader(GetData().role)) return S_FALSE; AXPlatformNodeBase* table = GetTable(); - if (!table) { + if (!table) return S_FALSE; - } int row = GetTableRow(); int columns = GetTableColumnCount();
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc index 36e43d6..03a5f05 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.cc +++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -194,6 +194,10 @@ node_->SetData(new_data); } +bool TestAXNodeWrapper::IsTable() const { + return node_->IsTable(); +} + int TestAXNodeWrapper::GetTableRowCount() const { return node_->GetTableRowCount(); } @@ -202,6 +206,18 @@ return node_->GetTableColCount(); } +int TestAXNodeWrapper::GetTableAriaRowCount() const { + return node_->GetTableAriaRowCount(); +} + +int TestAXNodeWrapper::GetTableAriaColCount() const { + return node_->GetTableAriaColCount(); +} + +int TestAXNodeWrapper::GetTableCellCount() const { + return node_->GetTableCellCount(); +} + const std::vector<int32_t> TestAXNodeWrapper::GetColHeaderNodeIds() const { std::vector<int32_t> header_ids; node_->GetTableCellColHeaderNodeIds(&header_ids); @@ -228,6 +244,46 @@ return header_ids; } +bool TestAXNodeWrapper::IsTableRow() const { + return node_->IsTableRow(); +} + +int TestAXNodeWrapper::GetTableRowRowIndex() const { + return node_->GetTableRowRowIndex(); +} + +bool TestAXNodeWrapper::IsTableCellOrHeader() const { + return node_->IsTableCellOrHeader(); +} + +int TestAXNodeWrapper::GetTableCellIndex() const { + return node_->GetTableCellIndex(); +} + +int TestAXNodeWrapper::GetTableCellColIndex() const { + return node_->GetTableCellColIndex(); +} + +int TestAXNodeWrapper::GetTableCellRowIndex() const { + return node_->GetTableCellRowIndex(); +} + +int TestAXNodeWrapper::GetTableCellColSpan() const { + return node_->GetTableCellColSpan(); +} + +int TestAXNodeWrapper::GetTableCellRowSpan() const { + return node_->GetTableCellRowSpan(); +} + +int TestAXNodeWrapper::GetTableCellAriaColIndex() const { + return node_->GetTableCellAriaColIndex(); +} + +int TestAXNodeWrapper::GetTableCellAriaRowIndex() const { + return node_->GetTableCellAriaRowIndex(); +} + int32_t TestAXNodeWrapper::GetCellId(int32_t row_index, int32_t col_index) const { ui::AXNode* cell = node_->GetTableCellFromCoords(row_index, col_index); @@ -237,10 +293,6 @@ return -1; } -int32_t TestAXNodeWrapper::GetTableCellIndex() const { - return node_->GetTableCellIndex(); -} - int32_t TestAXNodeWrapper::CellIndexToId(int32_t cell_index) const { ui::AXNode* cell = node_->GetTableCellFromIndex(cell_index); if (cell)
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.h b/ui/accessibility/platform/test_ax_node_wrapper.h index deceb33e..4c374cd 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.h +++ b/ui/accessibility/platform/test_ax_node_wrapper.h
@@ -42,16 +42,29 @@ gfx::NativeViewAccessible HitTestSync(int x, int y) override; AXPlatformNode* GetFromNodeID(int32_t id) override; int GetIndexInParent() const override; + bool IsTable() const override; int GetTableRowCount() const override; int GetTableColCount() const override; + int GetTableAriaColCount() const override; + int GetTableAriaRowCount() const override; + int GetTableCellCount() const override; const std::vector<int32_t> GetColHeaderNodeIds() const override; const std::vector<int32_t> GetColHeaderNodeIds( int32_t col_index) const override; const std::vector<int32_t> GetRowHeaderNodeIds() const override; const std::vector<int32_t> GetRowHeaderNodeIds( int32_t row_index) const override; + bool IsTableRow() const override; + int GetTableRowRowIndex() const override; + bool IsTableCellOrHeader() const override; + int GetTableCellIndex() const override; + int GetTableCellColIndex() const override; + int GetTableCellRowIndex() const override; + int GetTableCellColSpan() const override; + int GetTableCellRowSpan() const override; + int GetTableCellAriaColIndex() const override; + int GetTableCellAriaRowIndex() const override; int32_t GetCellId(int32_t row_index, int32_t col_index) const override; - int32_t GetTableCellIndex() const override; int32_t CellIndexToId(int32_t cell_index) const override; bool AccessibilityPerformAction(const AXActionData& data) override; bool ShouldIgnoreHoveredStateForTesting() override;
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index 8e04ec3..f913d76 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -848,7 +848,6 @@ if (build_ime) { sources += [ "ime/candidate_window_unittest.cc", - "ime/chromeos/character_composer_unittest.cc", "ime/chromeos/extension_ime_util_unittest.cc", "ime/chromeos/ime_keyboard_unittest.cc", "ime/chromeos/input_method_util_unittest.cc", @@ -870,6 +869,11 @@ if (use_x11) { sources += [ "ime/composition_text_util_pango_unittest.cc" ] } + if (is_chromeos || use_ozone) { + sources += [ + "ime/character_composer_unittest.cc", + ] + } } deps = [
diff --git a/ui/base/ime/BUILD.gn b/ui/base/ime/BUILD.gn index d686d1d..47fb630 100644 --- a/ui/base/ime/BUILD.gn +++ b/ui/base/ime/BUILD.gn
@@ -98,8 +98,6 @@ if (is_chromeos) { sources += [ - "chromeos/character_composer.cc", - "chromeos/character_composer.h", "chromeos/component_extension_ime_manager.cc", "chromeos/component_extension_ime_manager.h", "chromeos/extension_ime_util.cc", @@ -175,6 +173,14 @@ ] } + if (is_chromeos || use_ozone) { + sources += [ + "character_composer.cc", + "character_composer.h", + ] + deps += [ "//ui/events:dom_keycode_converter" ] + } + if (!toolkit_views && !use_aura) { sources -= [ "input_method_factory.cc", @@ -190,7 +196,6 @@ "//services/ws/public/cpp/input_devices", "//ui/base/ime/chromeos/public/interfaces", "//ui/chromeos/strings", - "//ui/events:dom_keycode_converter", ] sources += [ "chromeos/ime_keyboard_mus.cc",
diff --git a/ui/base/ime/chromeos/PRESUBMIT.py b/ui/base/ime/PRESUBMIT.py similarity index 97% rename from ui/base/ime/chromeos/PRESUBMIT.py rename to ui/base/ime/PRESUBMIT.py index ed44dfb..e9f33bbe 100644 --- a/ui/base/ime/chromeos/PRESUBMIT.py +++ b/ui/base/ime/PRESUBMIT.py
@@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""Presubmit script for ui/base/ime/chromeos +"""Presubmit script for ui/base/ime See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for more details about the presubmit API built into depot_tools.
diff --git a/ui/base/ime/chromeos/character_composer.cc b/ui/base/ime/character_composer.cc similarity index 97% rename from ui/base/ime/chromeos/character_composer.cc rename to ui/base/ime/character_composer.cc index e0026255..d1ddcaa8 100644 --- a/ui/base/ime/chromeos/character_composer.cc +++ b/ui/base/ime/character_composer.cc
@@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/base/ime/chromeos/character_composer.h" +#include "ui/base/ime/character_composer.h" #include <algorithm> #include <iterator> +#include <string> #include "base/strings/string_util.h" #include "base/strings/utf_string_conversion_utils.h" @@ -18,7 +19,7 @@ namespace { -#include "ui/base/ime/chromeos/character_composer_data.h" +#include "ui/base/ime/character_composer_data.h" bool CheckCharacterComposeTable( const ui::CharacterComposer::ComposeBuffer& compose_sequence, @@ -58,11 +59,9 @@ namespace ui { -CharacterComposer::CharacterComposer() : composition_mode_(KEY_SEQUENCE_MODE) { -} +CharacterComposer::CharacterComposer() : composition_mode_(KEY_SEQUENCE_MODE) {} -CharacterComposer::~CharacterComposer() { -} +CharacterComposer::~CharacterComposer() {} void CharacterComposer::Reset() { compose_buffer_.clear();
diff --git a/ui/base/ime/chromeos/character_composer.h b/ui/base/ime/character_composer.h similarity index 93% rename from ui/base/ime/chromeos/character_composer.h rename to ui/base/ime/character_composer.h index d1befb6c..b3845c3 100644 --- a/ui/base/ime/chromeos/character_composer.h +++ b/ui/base/ime/character_composer.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 UI_BASE_IME_CHROMEOS_CHARACTER_COMPOSER_H_ -#define UI_BASE_IME_CHROMEOS_CHARACTER_COMPOSER_H_ +#ifndef UI_BASE_IME_CHARACTER_COMPOSER_H_ +#define UI_BASE_IME_CHARACTER_COMPOSER_H_ #include <stddef.h> #include <stdint.h> @@ -102,6 +102,7 @@ virtual CheckSequenceResult CheckSequence( const ui::CharacterComposer::ComposeBuffer& sequence, uint32_t* composed_character) const = 0; + private: DISALLOW_COPY_AND_ASSIGN(ComposeChecker); }; @@ -115,7 +116,7 @@ const uint16_t* tree; }; - TreeComposeChecker(const CompositionData& data) : data_(data) {} + explicit TreeComposeChecker(const CompositionData& data) : data_(data) {} CheckSequenceResult CheckSequence( const ui::CharacterComposer::ComposeBuffer& sequence, uint32_t* composed_character) const override; @@ -127,4 +128,4 @@ } // namespace ui -#endif // UI_BASE_IME_CHROMEOS_CHARACTER_COMPOSER_H_ +#endif // UI_BASE_IME_CHARACTER_COMPOSER_H_
diff --git a/ui/base/ime/chromeos/character_composer_data.h b/ui/base/ime/character_composer_data.h similarity index 100% rename from ui/base/ime/chromeos/character_composer_data.h rename to ui/base/ime/character_composer_data.h
diff --git a/ui/base/ime/chromeos/character_composer_sequences.txt b/ui/base/ime/character_composer_sequences.txt similarity index 100% rename from ui/base/ime/chromeos/character_composer_sequences.txt rename to ui/base/ime/character_composer_sequences.txt
diff --git a/ui/base/ime/chromeos/character_composer_unittest.cc b/ui/base/ime/character_composer_unittest.cc similarity index 98% rename from ui/base/ime/chromeos/character_composer_unittest.cc rename to ui/base/ime/character_composer_unittest.cc index 6ea0a0f..95ade2d 100644 --- a/ui/base/ime/chromeos/character_composer_unittest.cc +++ b/ui/base/ime/character_composer_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 "ui/base/ime/chromeos/character_composer.h" +#include "ui/base/ime/character_composer.h" #include <stdint.h> @@ -63,9 +63,9 @@ DomCode code, int flags, base::char16 character) const { - KeyEvent* event = new KeyEvent(ET_KEY_PRESSED, vkey, code, flags, - DomKey::FromCharacter(character), - EventTimeForNow()); + KeyEvent* event = + new KeyEvent(ET_KEY_PRESSED, vkey, code, flags, + DomKey::FromCharacter(character), EventTimeForNow()); return event; } @@ -233,7 +233,7 @@ // This file is included here intentionally, instead of the top of the file, // because including this file at the top of the file will define a // global constant and contaminate the global namespace. -#include "ui/base/ime/chromeos/character_composer_data.h" +#include "ui/base/ime/character_composer_data.h" const int kTypes = 2; // Record the subtree locations and check subtable sizes. @@ -331,8 +331,7 @@ ExpectUnicodeKeyFiltered(VKEY_BACK, DomCode::BACKSPACE, EF_NONE, '\b'); EXPECT_EQ(ASCIIToUTF16("u304"), character_composer_.preedit_string()); ExpectUnicodeKeyFiltered(VKEY_2, DomCode::DIGIT2, EF_NONE, '2'); - ExpectUnicodeKeyComposed(VKEY_RETURN, DomCode::ENTER, EF_NONE, - '\r', + ExpectUnicodeKeyComposed(VKEY_RETURN, DomCode::ENTER, EF_NONE, '\r', base::string16(1, 0x3042)); EXPECT_EQ(ASCIIToUTF16(""), character_composer_.preedit_string()); @@ -462,8 +461,7 @@ EXPECT_EQ(ASCIIToUTF16("u304"), character_composer_.preedit_string()); ExpectUnicodeKeyFiltered(ui::VKEY_2, DomCode::DIGIT2, kControlShift, 0); EXPECT_EQ(ASCIIToUTF16("u3042"), character_composer_.preedit_string()); - ExpectUnicodeKeyComposed(VKEY_RETURN, DomCode::ENTER, kControlShift, - '\r', + ExpectUnicodeKeyComposed(VKEY_RETURN, DomCode::ENTER, kControlShift, '\r', base::string16(1, 0x3042)); EXPECT_EQ(ASCIIToUTF16(""), character_composer_.preedit_string());
diff --git a/ui/base/ime/chromeos/generate_character_composer_data.py b/ui/base/ime/generate_character_composer_data.py similarity index 100% rename from ui/base/ime/chromeos/generate_character_composer_data.py rename to ui/base/ime/generate_character_composer_data.py
diff --git a/ui/base/ime/input_method_chromeos.h b/ui/base/ime/input_method_chromeos.h index 52942a6..7787491 100644 --- a/ui/base/ime/input_method_chromeos.h +++ b/ui/base/ime/input_method_chromeos.h
@@ -15,7 +15,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "ui/base/ime/chromeos/character_composer.h" +#include "ui/base/ime/character_composer.h" #include "ui/base/ime/composition_text.h" #include "ui/base/ime/ime_input_context_handler_interface.h" #include "ui/base/ime/input_method_base.h"
diff --git a/ui/base/test/ui_controls_aura.cc b/ui/base/test/ui_controls_aura.cc index 5d0a3e7..bd6f409 100644 --- a/ui/base/test/ui_controls_aura.cc +++ b/ui/base/test/ui_controls_aura.cc
@@ -111,6 +111,7 @@ // static. declared in ui_controls.h void InstallUIControlsAura(UIControlsAura* instance) { + EnableUIControls(); delete instance_; instance_ = instance; }
diff --git a/ui/webui/resources/cr_elements/shared_vars_css.html b/ui/webui/resources/cr_elements/shared_vars_css.html index f117edb..fc8a660 100644 --- a/ui/webui/resources/cr_elements/shared_vars_css.html +++ b/ui/webui/resources/cr_elements/shared_vars_css.html
@@ -184,6 +184,8 @@ white-space: nowrap; } + --cr-text-element-min-width: 200px; + --cr-title-text: { color: var(--cr-title-text-color); font-size: 107.6923%; /* Go to 14px from 13px. */ @@ -200,7 +202,7 @@ font-size: 92.31%; /* Effectively 12px if the host default is 13px. */ font-weight: 500; max-width: 330px; - min-width: 200px; + min-width: var(--cr-text-element-min-width); padding: 10px 8px; }
diff --git a/ui/webui/resources/html/md_select_css.html b/ui/webui/resources/html/md_select_css.html index 9c72fee..c73f901 100644 --- a/ui/webui/resources/html/md_select_css.html +++ b/ui/webui/resources/html/md_select_css.html
@@ -28,6 +28,7 @@ font-size: inherit; line-height: inherit; max-width: 100%; + min-width: var(--cr-text-element-min-width); outline: none; padding-bottom: 6px; /* Ensures 3px space between text and arrow */