diff --git a/AUTHORS b/AUTHORS index c9bcb5c2..7ffcaba 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -1131,6 +1131,7 @@ Seznam.cz, a.s. <*@firma.seznam.cz> Slack Technologies Inc. <*@slack-corp.com> Spotify AB <*@spotify.com> +Synaptics <*@synaptics.com> Tableau Software <*@tableau.com> TeamSpeak Systems GmbH <*@teamspeak.com> The Chromium Authors <*@chromium.org>
diff --git a/DEPS b/DEPS index e5976dc..be4246c 100644 --- a/DEPS +++ b/DEPS
@@ -175,11 +175,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': '7363af8c513675e67df2729f8463b6828c80d776', + 'skia_revision': '3aee4845b5039149a506fb85e7442be1924f69c8', # 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': 'b9280b4dcba2321067300294596bca946f137551', + 'v8_revision': '5269c3133de0093c180c57cc51dac04406293e24', # 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. @@ -187,15 +187,15 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'd03b15b2f9f546fb984aa78c174d180d4326d628', + 'angle_revision': '1b2dd6f92a6ba4ac4738ae796692e4844bfd28c7', # 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': 'de3f38a72c486c14a5cfe0810af9871acb7dec9a', + 'swiftshader_revision': '1c29477aa06ea733994d1d11d6bf63ba27ac8359', # 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': '6489c0e7dc806db4363cfc5d91033b4bc83d35bc', + 'pdfium_revision': '0058260afa11281d48303e6720b2566e42083cbf', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -521,7 +521,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '8c7be049e94b0da2843869888281fdf115e2da7f', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '144b2f61dc052661a81e8822c9739fc61a1df8e4', 'condition': 'checkout_ios', }, @@ -877,7 +877,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'b73f8a96ec6daa0a6cfe5dfdab1c7249761a4b7d', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6a7e234b584eff3fbbd5686f5ec75cba3d25667c', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -933,7 +933,7 @@ Var('chromium_git') + '/codecs/libgav1.git' + '@' + 'fa1c3c4e673cf12ffa22b8fbe4a7c79314571f1b', 'src/third_party/glslang/src': - Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '4d7c749b7610c891db4fbe49a25fbd54afe374e5', + Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + 'bfe4c5957fc51148a0aab6e04bb22020667c1092', 'src/third_party/google_toolbox_for_mac/src': { 'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'), @@ -1523,7 +1523,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0935127287847942e9c8193e03a4442ad34857c9', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@04f3ecdadc728b53cb94d8f282eefd3748311912', 'condition': 'checkout_src_internal', },
diff --git a/ash/login/ui/login_user_view.cc b/ash/login/ui/login_user_view.cc index de411a08..677d4f1 100644 --- a/ash/login/ui/login_user_view.cc +++ b/ash/login/ui/login_user_view.cc
@@ -23,6 +23,7 @@ #include "base/memory/weak_ptr.h" #include "base/strings/utf_string_conversions.h" #include "components/user_manager/user_type.h" +#include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer_animation_sequence.h" #include "ui/compositor/layer_animator.h" @@ -240,6 +241,11 @@ views::Button::OnBlur(); parent_->UpdateOpacity(); } + void GetAccessibleNodeData(ui::AXNodeData* node_data) override { + // TODO(https://crbug.com/1065516): Define the button name. + node_data->SetNameExplicitlyEmpty(); + Button::GetAccessibleNodeData(node_data); + } private: LoginUserView* const parent_;
diff --git a/base/allocator/partition_allocator/page_allocator_internals_fuchsia.h b/base/allocator/partition_allocator/page_allocator_internals_fuchsia.h index d78f5f9..7e1bff1 100644 --- a/base/allocator/partition_allocator/page_allocator_internals_fuchsia.h +++ b/base/allocator/partition_allocator/page_allocator_internals_fuchsia.h
@@ -89,7 +89,7 @@ if (page_tag == PageTag::kV8) { // V8 uses JIT. Call zx_vmo_replace_as_executable() to allow code execution // in the new VMO. - status = vmo.replace_as_executable(zx::handle(), &vmo); + status = vmo.replace_as_executable(zx::resource(), &vmo); if (status != ZX_OK) { ZX_DLOG(INFO, status) << "zx_vmo_replace_as_executable"; return nullptr;
diff --git a/base/test/task_environment.cc b/base/test/task_environment.cc index 50e65ef..cfa60ded 100644 --- a/base/test/task_environment.cc +++ b/base/test/task_environment.cc
@@ -177,8 +177,12 @@ void AdvanceClock(TimeDelta delta) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - AutoLock lock(now_ticks_lock_); - now_ticks_ += delta; + { + AutoLock lock(now_ticks_lock_); + now_ticks_ += delta; + } + if (thread_pool_) + thread_pool_->ProcessRipeDelayedTasksForTesting(); } static std::unique_ptr<TaskEnvironment::MockTimeDomain> CreateAndRegister(
diff --git a/base/test/task_environment.h b/base/test/task_environment.h index 3a3e03031..1f77ed6 100644 --- a/base/test/task_environment.h +++ b/base/test/task_environment.h
@@ -259,6 +259,15 @@ // by |delta|. Unlike FastForwardBy, this does not run tasks. Prefer // FastForwardBy() when possible but this can be useful when testing blocked // pending tasks where being idle (required to fast-forward) is not possible. + // + // Delayed tasks that are ripe as a result of this will be scheduled. + // RunUntilIdle() can be used after this call to ensure those tasks have run. + // Note: AdvanceClock(delta) + RunUntilIdle() is slightly different from + // FastForwardBy(delta) in that time passes instantly before running any task + // (whereas FastForwardBy() will advance the clock in the smallest increments + // possible at a time). Hence FastForwardBy() is more realistic but + // AdvanceClock() can be useful when testing edge case scenarios that + // specifically handle more time than expected to have passed. void AdvanceClock(TimeDelta delta); // Only valid for instances using TimeSource::MOCK_TIME. Returns a
diff --git a/base/test/task_environment_unittest.cc b/base/test/task_environment_unittest.cc index 0367fa7..5d20d60f 100644 --- a/base/test/task_environment_unittest.cc +++ b/base/test/task_environment_unittest.cc
@@ -405,7 +405,7 @@ // Verify that the TickClock returned by // |TaskEnvironment::GetMockTickClock| gets updated when the // FastForward(By|UntilNoTasksRemain) functions are called. -TEST_F(TaskEnvironmentTest, FastForwardAdvanceTickClock) { +TEST_F(TaskEnvironmentTest, FastForwardAdvancesTickClock) { // Use a QUEUED execution-mode environment, so that no tasks are actually // executed until RunUntilIdle()/FastForwardBy() are invoked. TaskEnvironment task_environment( @@ -437,7 +437,7 @@ EXPECT_EQ(kLongTaskDelay * 2, tick_clock->NowTicks() - tick_clock_ref); } -TEST_F(TaskEnvironmentTest, FastForwardAdvanceMockClock) { +TEST_F(TaskEnvironmentTest, FastForwardAdvancesMockClock) { constexpr base::TimeDelta kDelay = TimeDelta::FromSeconds(42); TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME); @@ -448,7 +448,7 @@ EXPECT_EQ(start_time + kDelay, clock->Now()); } -TEST_F(TaskEnvironmentTest, FastForwardAdvanceTime) { +TEST_F(TaskEnvironmentTest, FastForwardAdvancesTime) { constexpr base::TimeDelta kDelay = TimeDelta::FromSeconds(42); TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME); @@ -457,7 +457,7 @@ EXPECT_EQ(start_time + kDelay, base::Time::Now()); } -TEST_F(TaskEnvironmentTest, FastForwardAdvanceTimeTicks) { +TEST_F(TaskEnvironmentTest, FastForwardAdvancesTimeTicks) { constexpr base::TimeDelta kDelay = TimeDelta::FromSeconds(42); TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME); @@ -466,7 +466,7 @@ EXPECT_EQ(start_time + kDelay, base::TimeTicks::Now()); } -TEST_F(TaskEnvironmentTest, AdvanceClockAdvanceTickClock) { +TEST_F(TaskEnvironmentTest, AdvanceClockAdvancesTickClock) { constexpr base::TimeDelta kDelay = TimeDelta::FromSeconds(42); TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME); @@ -477,7 +477,7 @@ EXPECT_EQ(start_time + kDelay, tick_clock->NowTicks()); } -TEST_F(TaskEnvironmentTest, AdvanceClockAdvanceMockClock) { +TEST_F(TaskEnvironmentTest, AdvanceClockAdvancesMockClock) { constexpr base::TimeDelta kDelay = TimeDelta::FromSeconds(42); TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME); @@ -488,7 +488,7 @@ EXPECT_EQ(start_time + kDelay, clock->Now()); } -TEST_F(TaskEnvironmentTest, AdvanceClockAdvanceTime) { +TEST_F(TaskEnvironmentTest, AdvanceClockAdvancesTime) { constexpr base::TimeDelta kDelay = TimeDelta::FromSeconds(42); TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME); @@ -497,7 +497,7 @@ EXPECT_EQ(start_time + kDelay, base::Time::Now()); } -TEST_F(TaskEnvironmentTest, AdvanceClockAdvanceTimeTicks) { +TEST_F(TaskEnvironmentTest, AdvanceClockAdvancesTimeTicks) { constexpr base::TimeDelta kDelay = TimeDelta::FromSeconds(42); TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME); @@ -523,6 +523,21 @@ EXPECT_FALSE(task_environment.NextTaskIsDelayed()); } +TEST_F(TaskEnvironmentTest, AdvanceClockSchedulesRipeDelayedTasks) { + TaskEnvironment task_environment(TaskEnvironment::TimeSource::MOCK_TIME); + + bool ran = false; + + constexpr base::TimeDelta kTaskDelay = TimeDelta::FromDays(1); + ThreadPool::PostDelayedTask( + FROM_HERE, base::BindLambdaForTesting([&]() { ran = true; }), kTaskDelay); + + task_environment.AdvanceClock(kTaskDelay); + EXPECT_FALSE(ran); + task_environment.RunUntilIdle(); + EXPECT_TRUE(ran); +} + // Verify that FastForwardBy() runs existing immediate tasks before advancing, // then advances to the next delayed task, runs it, then advances the remainder // of time when out of tasks.
diff --git a/build/args/headless.gn b/build/args/headless.gn index 8a3d4088..d941799 100644 --- a/build/args/headless.gn +++ b/build/args/headless.gn
@@ -43,3 +43,4 @@ rtc_use_pipewire = false v8_enable_lazy_source_positions = false use_glib = false +use_gtk = false
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 69d448a..6c50e93 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1591,8 +1591,7 @@ # TODO(thakis): Enable this more often, https://crbug.com/346399 # use_libfuzzer: https://crbug.com/1063180 - if (!is_nacl && !use_libfuzzer && - (target_os != "ios" && target_os != "mac")) { + if (!is_nacl && !use_libfuzzer && target_os != "ios") { cflags += [ "-Wunreachable-code" ] }
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 789f48f..8e7aa7e 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20200327.2.4 \ No newline at end of file +0.20200329.2.1 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 789f48f..8e7aa7e 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20200327.2.4 \ No newline at end of file +0.20200329.2.1 \ No newline at end of file
diff --git a/build/fuchsia/test_runner.py b/build/fuchsia/test_runner.py index 3c9882e..02fb07f 100755 --- a/build/fuchsia/test_runner.py +++ b/build/fuchsia/test_runner.py
@@ -40,10 +40,12 @@ parser.add_argument( '--test-launcher-shard-index', type=int, + default=os.environ.get('GTEST_SHARD_INDEX'), help='Index of this instance amongst swarming shards.') parser.add_argument( '--test-launcher-total-shards', type=int, + default=os.environ.get('GTEST_TOTAL_SHARDS'), help='Total number of swarming shards of this suite.') parser.add_argument('--gtest_break_on_failure', action='store_true', default=False, @@ -88,6 +90,12 @@ ConfigureLogging(args) child_args = [] + if args.test_launcher_shard_index != None: + child_args.append( + '--test-launcher-shard-index=%d' % args.test_launcher_shard_index) + if args.test_launcher_total_shards != None: + child_args.append( + '--test-launcher-total-shards=%d' % args.test_launcher_total_shards) if args.single_process_tests: child_args.append('--single-process-tests') if args.test_launcher_bot_mode: @@ -120,12 +128,6 @@ if args.test_launcher_retry_limit: child_args.append( '--test-launcher-retry-limit=' + args.test_launcher_retry_limit) - if args.test_launcher_shard_index: - child_args.append( - '--test-launcher-shard-index=%d' % args.test_launcher_shard_index) - if args.test_launcher_total_shards: - child_args.append( - '--test-launcher-total-shards=%d' % args.test_launcher_total_shards) if args.gtest_break_on_failure: child_args.append('--gtest_break_on_failure') if args.test_launcher_summary_output:
diff --git a/chrome/VERSION b/chrome/VERSION index 22e4b84..3b52afb 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=83 MINOR=0 -BUILD=4098 +BUILD=4099 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java index 0fd7d55..12d5056 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -334,17 +334,19 @@ if (params.isAnchor()) { List<ContextMenuItem> linkTab = new ArrayList<>(); - if (FirstRunStatus.getFirstRunFlowComplete() && mMode == ContextMenuMode.NORMAL - && !isEmptyUrl(params.getUrl()) + if (FirstRunStatus.getFirstRunFlowComplete() && !isEmptyUrl(params.getUrl()) && UrlUtilities.isAcceptedScheme(params.getUrl())) { - linkTab.add(new ChromeContextMenuItem(Item.OPEN_IN_NEW_TAB)); - if (!mDelegate.isIncognito() && mDelegate.isIncognitoSupported()) { - linkTab.add(new ChromeContextMenuItem(Item.OPEN_IN_INCOGNITO_TAB)); + if (mMode == ContextMenuMode.NORMAL) { + linkTab.add(new ChromeContextMenuItem(Item.OPEN_IN_NEW_TAB)); + if (!mDelegate.isIncognito() && mDelegate.isIncognitoSupported()) { + linkTab.add(new ChromeContextMenuItem(Item.OPEN_IN_INCOGNITO_TAB)); + } + if (mDelegate.isOpenInOtherWindowSupported()) { + linkTab.add(new ChromeContextMenuItem(Item.OPEN_IN_OTHER_WINDOW)); + } } - if (mDelegate.isOpenInOtherWindowSupported()) { - linkTab.add(new ChromeContextMenuItem(Item.OPEN_IN_OTHER_WINDOW)); - } - if (EphemeralTabCoordinator.isSupported()) { + if ((mMode == ContextMenuMode.NORMAL || mMode == ContextMenuMode.CUSTOM_TAB) + && EphemeralTabCoordinator.isSupported()) { ContextMenuItem item = new ChromeContextMenuItem(Item.OPEN_IN_EPHEMERAL_TAB); mShowEphemeralTabNewLabel = shouldTriggerEphemeralTabHelpUi(); if (mShowEphemeralTabNewLabel) item.setShowInProductHelp(); @@ -407,7 +409,8 @@ if (mMode == ContextMenuMode.NORMAL) { imageTab.add(new ChromeContextMenuItem(Item.OPEN_IMAGE_IN_NEW_TAB)); } - if (EphemeralTabCoordinator.isSupported()) { + if ((mMode == ContextMenuMode.NORMAL || mMode == ContextMenuMode.CUSTOM_TAB) + && EphemeralTabCoordinator.isSupported()) { ContextMenuItem item = new ChromeContextMenuItem(Item.OPEN_IMAGE_IN_EPHEMERAL_TAB); if (mShowEphemeralTabNewLabel == null) {
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 c99e916..6fca974 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
@@ -331,7 +331,7 @@ @Override protected boolean requiresFirstRunToBeCompleted(Intent intent) { // Custom Tabs can be used to open Chrome help pages before the ToS has been accepted. - if (CustomTabIntentDataProvider.isTrustedCustomTab(intent, mSession) + if (IntentHandler.notSecureIsIntentChromeOrFirstParty(intent) && IntentUtils.safeGetIntExtra(intent, CustomTabIntentDataProvider.EXTRA_UI_TYPE, CustomTabIntentDataProvider.CustomTabsUiType.DEFAULT) == CustomTabIntentDataProvider.CustomTabsUiType.INFO_PAGE) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java index 597b41c0..56e5c1a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java
@@ -25,6 +25,7 @@ import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.ShortcutHelper; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; +import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator; import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator; import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator; import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabBrowserControlsVisibilityDelegate; @@ -352,6 +353,7 @@ private TabWebContentsDelegateAndroid mWebContentsDelegateAndroid; private ExternalNavigationDelegateImpl mNavigationDelegate; + private EphemeralTabCoordinator mEphemeralTabCoordinator; /** * @param activity {@link ChromeActivity} instance. @@ -459,7 +461,15 @@ int contextMenuMode = getContextMenuMode(mActivityType); Supplier<ShareDelegate> shareDelegateSupplier = mActivity == null ? null : mActivity.getShareDelegateSupplier(); - return new ChromeContextMenuPopulator(new TabContextMenuItemDelegate(tab, null), + if (EphemeralTabCoordinator.isSupported() && mActivity != null + && mActivity.getBottomSheetController() != null) { + mEphemeralTabCoordinator = new EphemeralTabCoordinator(mActivity, + mActivity.getWindowAndroid(), mActivity.getWindow().getDecorView(), + mActivity.getActivityTabProvider(), mActivity::getCurrentTabCreator, + mActivity.getBottomSheetController(), () -> false); + } + return new ChromeContextMenuPopulator( + new TabContextMenuItemDelegate(tab, () -> mEphemeralTabCoordinator), shareDelegateSupplier, contextMenuMode, ExternalAuthUtils.getInstance()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index 1b6df1d..71b7670c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -219,20 +219,6 @@ } /** - * Evaluates whether the passed Intent and/or CustomTabsSessionToken are - * from a trusted source. Trusted in this case means from the app itself or - * via a first-party application. - * - * @param intent The Intent used to start the custom tabs activity, or null. - * @param session The connected session for the custom tabs activity, or null. - * @return True if the intent or session are trusted. - */ - public static boolean isTrustedCustomTab(Intent intent, CustomTabsSessionToken session) { - return IntentHandler.wasIntentSenderChrome(intent) - || CustomTabsConnection.getInstance().isSessionFirstParty(session); - } - - /** * Constructs a {@link CustomTabIntentDataProvider}. * * The colorScheme parameter specifies which color scheme the Custom Tab should use. @@ -247,7 +233,7 @@ mIntent = intent; mSession = CustomTabsSessionToken.getSessionTokenFromIntent(intent); - mIsTrustedIntent = isTrustedCustomTab(intent, mSession); + mIsTrustedIntent = IntentHandler.notSecureIsIntentChromeOrFirstParty(intent); mAnimationBundle = IntentUtils.safeGetBundleExtra( intent, CustomTabsIntent.EXTRA_EXIT_ANIMATION_BUNDLE);
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 f5d4eef6..48b3982 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
@@ -57,7 +57,6 @@ import org.chromium.chrome.browser.browserservices.SessionDataHolder; import org.chromium.chrome.browser.browserservices.SessionHandler; import org.chromium.chrome.browser.device.DeviceClassManager; -import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.init.ChainedTasks; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; @@ -1066,13 +1065,6 @@ return mClientManager.getClientPackageNameForSession(session); } - /** @return Whether the client of the {@code session} is a first-party application. */ - public boolean isSessionFirstParty(CustomTabsSessionToken session) { - String packageName = getClientPackageNameForSession(session); - if (packageName == null) return false; - return ExternalAuthUtils.getInstance().isGoogleSigned(packageName); - } - @VisibleForTesting void setIgnoreUrlFragmentsForSession(CustomTabsSessionToken session, boolean value) { mClientManager.setIgnoreFragmentsForSession(session, value); @@ -1101,6 +1093,15 @@ } /** + * Extracts the creator package name from the intent. + * @param intent The intent to get the package name from. + * @return the package name which can be null. + */ + String extractCreatorPackage(Intent intent) { + return null; + } + + /** * Shows a toast about any possible sign in issues encountered during custom tab startup. * @param session The session that corresponding custom tab is assigned. * @param intent The intent that launched the custom tab.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java index 0e4695d..f807a51 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java
@@ -28,7 +28,6 @@ import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.customtabs.CustomTabDelegateFactory; -import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider; import org.chromium.chrome.browser.customtabs.CustomTabNavigationEventObserver; import org.chromium.chrome.browser.customtabs.CustomTabObserver; import org.chromium.chrome.browser.customtabs.CustomTabTabPersistencePolicy; @@ -441,7 +440,7 @@ /** Sets the initial background color for the Tab, shown before the page content is ready. */ private void prepareTabBackground(final Tab tab) { - if (!CustomTabIntentDataProvider.isTrustedCustomTab(mIntent, mSession)) return; + if (!IntentHandler.notSecureIsIntentChromeOrFirstParty(mIntent)) return; int backgroundColor = mIntentDataProvider.getInitialBackgroundColor(); if (backgroundColor == Color.TRANSPARENT) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java index b161fde..480e1d23 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
@@ -247,7 +247,10 @@ mSiteSectionViewHolder = SiteSection.createViewHolder(getSiteSectionView(), mUiConfig); mSiteSectionViewHolder.bindDataSource(mTileGroup, tileRenderer); - mQueryTileSection = new QueryTileSection(findViewById(R.id.query_tiles), profile); + final TextView searchBoxTextView = + mSearchBoxContainerView.findViewById(R.id.search_box_text); + mQueryTileSection = + new QueryTileSection(findViewById(R.id.query_tiles), searchBoxTextView, profile); int variation = ExploreSitesBridge.getVariation(); if (ExploreSitesBridge.isExperimental(variation)) { @@ -880,8 +883,8 @@ final int width = mSiteSectionView.getMeasuredWidth() - mTileGridLayoutBleed; measureExactly( mSearchBoxContainerView, width, mSearchBoxContainerView.getMeasuredHeight()); - measureExactly(mSearchProviderLogoView, - width, mSearchProviderLogoView.getMeasuredHeight()); + measureExactly( + mSearchProviderLogoView, width, mSearchProviderLogoView.getMeasuredHeight()); if (mExploreSectionView != null) { measureExactly(mExploreSectionView, mSiteSectionView.getMeasuredWidth(), @@ -996,4 +999,4 @@ ApiCompatibilityUtils.setImageTintList(mVoiceSearchButton, colorStateList); } } -} +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileSection.java b/chrome/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileSection.java index e275a2c..fbdcc9c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileSection.java
@@ -4,13 +4,18 @@ package org.chromium.chrome.browser.query_tiles; +import android.graphics.Bitmap; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; +import android.widget.TextView; +import org.chromium.base.Callback; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.profiles.Profile; +import java.util.List; + /** * Represents the query tiles section on the new tab page. Abstracts away the general tasks related * to initializing and fetching data for the UI and making decisions whether to show or hide this @@ -18,22 +23,35 @@ */ public class QueryTileSection { private final ViewGroup mQueryTileSectionView; - private TileProvider mTileProvider; + private final TextView mSearchBox; private QueryTileCoordinator mQueryTileCoordinator; + private TileProvider mTileProvider; /** Constructor. */ - public QueryTileSection(ViewGroup queryTileSectionView, Profile profile) { + public QueryTileSection( + ViewGroup queryTileSectionView, TextView searchTextView, Profile profile) { mQueryTileSectionView = queryTileSectionView; + mSearchBox = searchTextView; if (!ChromeFeatureList.isEnabled(ChromeFeatureList.QUERY_TILES)) return; mTileProvider = TileProviderFactory.getForProfile(profile); mQueryTileCoordinator = QueryTileCoordinatorFactory.create( - mQueryTileSectionView.getContext(), mTileProvider, this::onQueryTilesChanged); + mQueryTileSectionView.getContext(), this::onTileClicked, this::getVisuals); mQueryTileSectionView.addView(mQueryTileCoordinator.getView(), new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); + onTileClicked(null); } - private void onQueryTilesChanged(boolean hasTiles) { - mQueryTileSectionView.setVisibility(hasTiles ? View.VISIBLE : View.GONE); + private void onTileClicked(Tile tile) { + mTileProvider.getQueryTiles(tiles -> { + mQueryTileCoordinator.setTiles(tiles); + mQueryTileSectionView.setVisibility(tiles.isEmpty() ? View.GONE : View.VISIBLE); + }); + + if (tile != null) mSearchBox.setText(tile.queryText); } -} + + private void getVisuals(Tile tile, Callback<List<Bitmap>> callback) { + mTileProvider.getVisuals(tile.id, callback); + } +} \ No newline at end of file
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 0904088e..3bc3033 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
@@ -958,7 +958,7 @@ // Mark the intent as trusted so it can show more than one action button. IntentHandler.addTrustedIntentExtras(intent); - Assert.assertTrue(IntentHandler.wasIntentSenderChrome(intent)); + Assert.assertTrue(IntentHandler.notSecureIsIntentChromeOrFirstParty(intent)); ArrayList<Bundle> toolbarItems = new ArrayList<>(2); final PendingIntent pi1 = PendingIntent.getBroadcast( @@ -1033,7 +1033,7 @@ Intent intent = createMinimalCustomTabIntent(); // By default, the intent should not be trusted. - Assert.assertFalse(IntentHandler.wasIntentSenderChrome(intent)); + Assert.assertFalse(IntentHandler.notSecureIsIntentChromeOrFirstParty(intent)); ArrayList<Bundle> toolbarItems = new ArrayList<>(2); final PendingIntent pi = PendingIntent.getBroadcast(
diff --git a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java index 7c55937..22826eb 100644 --- a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java +++ b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
@@ -152,6 +152,39 @@ } @CalledByNativeJavaTest + public void testHttpLinkWithPreviewTabEnabled() { + ContextMenuParams contextMenuParams = new ContextMenuParams(0, PAGE_URL, LINK_URL, + LINK_TEXT, "", "", "", null, false, 0, 0, MenuSourceType.MENU_SOURCE_TOUCH); + + FirstRunStatus.setFirstRunFlowComplete(true); + + HashMap<String, Boolean> features = new HashMap<String, Boolean>(); + features.put(ChromeFeatureList.EPHEMERAL_TAB_USING_BOTTOM_SHEET, true); + ChromeFeatureList.setTestFeatures(features); + + initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL); + int[] expected1 = {R.id.contextmenu_open_in_new_tab, R.id.contextmenu_open_in_incognito_tab, + R.id.contextmenu_open_in_other_window, R.id.contextmenu_open_in_ephemeral_tab, + R.id.contextmenu_copy_link_address, R.id.contextmenu_copy_link_text, + R.id.contextmenu_save_link_as, R.id.contextmenu_share_link}; + checkMenuOptions(contextMenuParams, expected1); + + initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB); + int[] expected2 = {R.id.contextmenu_open_in_browser_id, + R.id.contextmenu_open_in_ephemeral_tab, R.id.contextmenu_copy_link_address, + R.id.contextmenu_copy_link_text, R.id.contextmenu_save_link_as, + R.id.contextmenu_share_link}; + checkMenuOptions(contextMenuParams, expected2); + + // Webapp doesn't show preview tab. + initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.WEB_APP); + int[] expected3 = {R.id.contextmenu_copy_link_address, R.id.contextmenu_copy_link_text, + R.id.contextmenu_save_link_as, R.id.contextmenu_share_link, + R.id.contextmenu_open_in_chrome}; + checkMenuOptions(contextMenuParams, expected3); + } + + @CalledByNativeJavaTest public void testMailLink() { FirstRunStatus.setFirstRunFlowComplete(false); ContextMenuParams contextMenuParams =
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 6904f61..9be8ed4 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-83.0.4094.0_rc-r1-merged.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-83.0.4097.3_rc-r1-merged.afdo.bz2 \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 19bb780..e8545cef 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2798,6 +2798,10 @@ flag_descriptions::kImeAssistPersonalInfoName, flag_descriptions::kImeAssistPersonalInfoDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kAssistPersonalInfo)}, + {"enable-cros-ime-emoji-suggest-addition", + flag_descriptions::kImeEmojiSuggestAdditionName, + flag_descriptions::kImeEmojiSuggestAdditionDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kEmojiSuggestAddition)}, {"enable-cros-ime-input-logic-fst", flag_descriptions::kImeInputLogicFstName, flag_descriptions::kImeInputLogicFstDescription, kOsCrOS,
diff --git a/chrome/browser/apps/app_shim/BUILD.gn b/chrome/browser/apps/app_shim/BUILD.gn index 07bc914..1a6daa7 100644 --- a/chrome/browser/apps/app_shim/BUILD.gn +++ b/chrome/browser/apps/app_shim/BUILD.gn
@@ -18,10 +18,13 @@ "app_shim_termination_manager.h", "mach_bootstrap_acceptor.cc", "mach_bootstrap_acceptor.h", + "web_app_shim_manager_delegate_mac.cc", + "web_app_shim_manager_delegate_mac.h", ] deps = [ "//apps", + "//chrome/browser/web_applications:web_applications_on_extensions", "//chrome/browser/web_applications/components", "//chrome/common", "//chrome/common:app_mode_app_support",
diff --git a/chrome/browser/apps/app_shim/app_shim_manager_mac.cc b/chrome/browser/apps/app_shim/app_shim_manager_mac.cc index d8086f54..7978d9b 100644 --- a/chrome/browser/apps/app_shim/app_shim_manager_mac.cc +++ b/chrome/browser/apps/app_shim/app_shim_manager_mac.cc
@@ -35,7 +35,9 @@ #include "chrome/browser/profiles/profile_avatar_icon_util.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_window.h" +#include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/user_manager.h" #include "chrome/browser/web_applications/components/app_shim_registry_mac.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/components/web_app_shortcut_mac.h" @@ -282,7 +284,7 @@ DCHECK(!app_state->profiles.empty()); profile = app_state->profiles.begin()->first; } else { - profile = delegate_->ProfileForPath(host->GetProfilePath()); + profile = ProfileForPath(host->GetProfilePath()); } } delegate_->LaunchShim(profile, host->GetAppId(), recreate_shims, @@ -312,7 +314,7 @@ // Create a ProfileState the specified profile (if there is one). We should // not do this (if there exists no ProfileState, then the shim should just // exit), but many tests assume this behavior, and need to be updated. - Profile* profile = delegate_->ProfileForPath(bootstrap->GetProfilePath()); + Profile* profile = ProfileForPath(bootstrap->GetProfilePath()); bool app_installed = delegate_->AppIsInstalled(profile, app_id); if (profile && app_installed && delegate_->AppCanCreateHost(profile, app_id)) GetOrCreateProfileState(profile, app_id); @@ -413,11 +415,11 @@ const base::FilePath& profile_path = profile_paths_to_launch[iter]; if (profile_path.empty()) continue; - if (delegate_->IsProfileLockedForPath(profile_path)) { + if (IsProfileLockedForPath(profile_path)) { launch_result = chrome::mojom::AppShimLaunchResult::kProfileLocked; continue; } - Profile* profile = delegate_->ProfileForPath(profile_path); + Profile* profile = ProfileForPath(profile_path); if (!profile) { launch_result = chrome::mojom::AppShimLaunchResult::kProfileNotFound; continue; @@ -472,7 +474,7 @@ // Otherwise, if the app specified a URL, open that URL in a new window. const GURL& url = bootstrap->GetAppURL(); if (url.is_valid()) - delegate_->OpenAppURLInBrowserWindow(bootstrap->GetProfilePath(), url); + OpenAppURLInBrowserWindow(bootstrap->GetProfilePath(), url); } OnShimProcessConnectedAndAllLaunchesDone(launched_profile_state, @@ -485,7 +487,7 @@ std::unique_ptr<AppShimHostBootstrap> bootstrap) { // If we failed because the profile was locked, launch the profile manager. if (result == chrome::mojom::AppShimLaunchResult::kProfileLocked) - delegate_->LaunchUserManager(); + LaunchUserManager(); // If we failed to find a AppShimHost (in a ProfileState) for |bootstrap| // to attempt to connect to, then quit the shim. This may not represent an @@ -563,14 +565,14 @@ void AppShimManager::LoadProfileAndApp(const base::FilePath& profile_path, const web_app::AppId& app_id, LoadProfileAppCallback callback) { - Profile* profile = delegate_->ProfileForPath(profile_path); + Profile* profile = ProfileForPath(profile_path); if (profile) { OnProfileLoaded(profile_path, app_id, std::move(callback), profile); } else { - delegate_->LoadProfileAsync( - profile_path, base::BindOnce(&AppShimManager::OnProfileLoaded, - weak_factory_.GetWeakPtr(), profile_path, - app_id, std::move(callback))); + LoadProfileAsync(profile_path, + base::BindOnce(&AppShimManager::OnProfileLoaded, + weak_factory_.GetWeakPtr(), profile_path, + app_id, std::move(callback))); } } @@ -606,13 +608,69 @@ void AppShimManager::OnAppEnabled(const base::FilePath& profile_path, const web_app::AppId& app_id, LoadProfileAppCallback callback) { - std::move(callback).Run(delegate_->ProfileForPath(profile_path)); + std::move(callback).Run(ProfileForPath(profile_path)); } bool AppShimManager::IsAcceptablyCodeSigned(pid_t pid) const { return IsAcceptablyCodeSignedInternal(pid); } +Profile* AppShimManager::ProfileForPath(const base::FilePath& full_path) { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + Profile* profile = profile_manager->GetProfileByPath(full_path); + + // Use IsValidProfile to check if the profile has been created. + return profile && profile_manager->IsValidProfile(profile) ? profile + : nullptr; +} + +void AppShimManager::LoadProfileAsync( + const base::FilePath& full_path, + base::OnceCallback<void(Profile*)> callback) { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + profile_manager->LoadProfileByPath(full_path, false, std::move(callback)); +} + +bool AppShimManager::IsProfileLockedForPath(const base::FilePath& full_path) { + return profiles::IsProfileLocked(full_path); +} + +std::unique_ptr<AppShimHost> AppShimManager::CreateHost( + AppShimHost::Client* client, + const base::FilePath& profile_path, + const web_app::AppId& app_id, + bool use_remote_cocoa) { + return std::make_unique<AppShimHost>(client, app_id, profile_path, + use_remote_cocoa); +} + +void AppShimManager::OpenAppURLInBrowserWindow( + const base::FilePath& profile_path, + const GURL& url) { + Profile* profile = + profile_path.empty() ? nullptr : ProfileForPath(profile_path); + if (!profile) + profile = g_browser_process->profile_manager()->GetLastUsedProfile(); + if (!profile) + return; + Browser* browser = + new Browser(Browser::CreateParams(Browser::TYPE_NORMAL, profile, true)); + browser->window()->Show(); + NavigateParams params(browser, url, ui::PAGE_TRANSITION_AUTO_BOOKMARK); + params.tabstrip_add_types = TabStripModel::ADD_ACTIVE; + params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; + Navigate(¶ms); +} + +void AppShimManager::LaunchUserManager() { + UserManager::Show(base::FilePath(), + profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION); +} + +void AppShimManager::MaybeTerminate() { + apps::AppShimTerminationManager::Get()->MaybeTerminate(); +} + void AppShimManager::OnShimProcessDisconnected(AppShimHost* host) { const std::string app_id = host->GetAppId(); @@ -637,7 +695,7 @@ !host->UsesRemoteViews() && host->HasBootstrapConnected(); // Erase the ProfileState, which will delete |host|. - Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); + Profile* profile = ProfileForPath(host->GetProfilePath()); auto found_profile = app_state->profiles.find(profile); DCHECK(found_profile != app_state->profiles.end()); ProfileState* profile_state = found_profile->second.get(); @@ -659,7 +717,7 @@ if (host->UsesRemoteViews()) return; - Profile* profile = delegate_->ProfileForPath(host->GetProfilePath()); + Profile* profile = ProfileForPath(host->GetProfilePath()); if (!delegate_->AppIsInstalled(profile, host->GetAppId())) { CloseShimForApp(profile, host->GetAppId()); return; @@ -684,7 +742,7 @@ // profile. This just grabs one at random. profile = app_state->profiles.begin()->first; } else { - profile = delegate_->ProfileForPath(host->GetProfilePath()); + profile = ProfileForPath(host->GetProfilePath()); } DCHECK(profile); delegate_->LaunchApp(profile, host->GetAppId(), files); @@ -769,7 +827,7 @@ const std::string& app_id) { CloseShimForApp(static_cast<Profile*>(context), app_id); if (apps_.empty()) - delegate_->MaybeTerminate(); + MaybeTerminate(); } void AppShimManager::OnAppStop(content::BrowserContext* context, @@ -895,7 +953,7 @@ std::unique_ptr<AppShimHost> multi_profile_host; if (is_multi_profile) { multi_profile_host = - delegate_->CreateHost(this, profile_path, app_id, use_remote_cocoa); + CreateHost(this, profile_path, app_id, use_remote_cocoa); } auto new_app_state = std::make_unique<AppState>(app_id, std::move(multi_profile_host)); @@ -913,7 +971,7 @@ std::unique_ptr<AppShimHost> single_profile_host; if (!is_multi_profile) { single_profile_host = - delegate_->CreateHost(this, profile_path, app_id, use_remote_cocoa); + CreateHost(this, profile_path, app_id, use_remote_cocoa); } auto new_profile_state = std::make_unique<ProfileState>( app_state, std::move(single_profile_host));
diff --git a/chrome/browser/apps/app_shim/app_shim_manager_mac.h b/chrome/browser/apps/app_shim/app_shim_manager_mac.h index f244237..6bb7674 100644 --- a/chrome/browser/apps/app_shim/app_shim_manager_mac.h +++ b/chrome/browser/apps/app_shim/app_shim_manager_mac.h
@@ -49,18 +49,6 @@ public: virtual ~Delegate() = default; - // Return the profile for |path|, only if it is already loaded. - virtual Profile* ProfileForPath(const base::FilePath& path) = 0; - - // Load a profile and call |callback| when completed or failed. - virtual void LoadProfileAsync( - const base::FilePath& path, - base::OnceCallback<void(Profile*)> callback) = 0; - - // Return true if the specified path is for a valid profile that is also - // locked. - virtual bool IsProfileLockedForPath(const base::FilePath& path) = 0; - // Show all app windows (for non-PWA apps). Return true if there existed any // windows. virtual bool ShowAppWindows(Profile* profile, @@ -71,7 +59,8 @@ const web_app::AppId& app_id) = 0; // Return true iff |app_id| corresponds to an app that is installed for - // |profile|. + // |profile|. Note that |profile| may be nullptr (in which case it should + // always return false). virtual bool AppIsInstalled(Profile* profile, const web_app::AppId& app_id) = 0; @@ -91,47 +80,27 @@ virtual bool AppIsMultiProfile(Profile* profile, const web_app::AppId& app_id) = 0; - // Create an AppShimHost for the specified parameters (intercept-able for - // tests). - virtual std::unique_ptr<AppShimHost> CreateHost( - AppShimHost::Client* client, - const base::FilePath& profile_path, - const web_app::AppId& app_id, - bool use_remote_cocoa) = 0; - // Open a dialog to enable the specified extension. Call |callback| after // the dialog is executed. virtual void EnableExtension(Profile* profile, const std::string& extension_id, base::OnceCallback<void()> callback) = 0; - // Launch the app in Chrome. This will (often) create a new window. + // Launch the app in Chrome. This will (often) create a new window. It is + // guaranteed that |app_id| is installed for |profile| when this method + // is called. virtual void LaunchApp(Profile* profile, const web_app::AppId& app_id, const std::vector<base::FilePath>& files) = 0; - // Open the specified URL in a new Chrome window. This is the fallback when - // an app shim exists, but there is no profile or extension for it. If - // |profile_path| is specified, then that profile is preferred, otherwise, - // the last used profile is used. - virtual void OpenAppURLInBrowserWindow(const base::FilePath& profile_path, - const GURL& url) = 0; - - // Launch the shim process for an app. + // Launch the shim process for an app. It is guaranteed that |app_id| is + // installed for |profile| when this method is called. virtual void LaunchShim(Profile* profile, const web_app::AppId& app_id, bool recreate_shims, ShimLaunchedCallback launched_callback, ShimTerminatedCallback terminated_callback) = 0; - // Launch the user manager (in response to attempting to access a locked - // profile). - virtual void LaunchUserManager() = 0; - - // Terminate Chrome if Chrome attempted to quit, but was prevented from - // quitting due to apps being open. - virtual void MaybeTerminate() = 0; - // Return true if any app windows are open. This is eventually invoked // by MaybeTerminate. It does not apply to bookmark apps. virtual bool HasNonBookmarkAppWindowsOpen() = 0; @@ -204,6 +173,40 @@ // Virtual for tests. virtual bool IsAcceptablyCodeSigned(pid_t pid) const; + // Return the profile for |path|, only if it is already loaded. + virtual Profile* ProfileForPath(const base::FilePath& path); + + // Load a profile and call |callback| when completed or failed. + virtual void LoadProfileAsync(const base::FilePath& path, + base::OnceCallback<void(Profile*)> callback); + + // Return true if the specified path is for a valid profile that is also + // locked. + virtual bool IsProfileLockedForPath(const base::FilePath& path); + + // Create an AppShimHost for the specified parameters (intercept-able for + // tests). + virtual std::unique_ptr<AppShimHost> CreateHost( + AppShimHost::Client* client, + const base::FilePath& profile_path, + const web_app::AppId& app_id, + bool use_remote_cocoa); + + // Open the specified URL in a new Chrome window. This is the fallback when + // an app shim exists, but there is no profile or extension for it. If + // |profile_path| is specified, then that profile is preferred, otherwise, + // the last used profile is used. + virtual void OpenAppURLInBrowserWindow(const base::FilePath& profile_path, + const GURL& url); + + // Launch the user manager (in response to attempting to access a locked + // profile). + virtual void LaunchUserManager(); + + // Terminate Chrome if Chrome attempted to quit, but was prevented from + // quitting due to apps being open. + virtual void MaybeTerminate(); + // Exposed for testing. content::NotificationRegistrar& registrar() { return registrar_; }
diff --git a/chrome/browser/apps/app_shim/app_shim_manager_mac_unittest.cc b/chrome/browser/apps/app_shim/app_shim_manager_mac_unittest.cc index d849f47..3a662f12 100644 --- a/chrome/browser/apps/app_shim/app_shim_manager_mac_unittest.cc +++ b/chrome/browser/apps/app_shim/app_shim_manager_mac_unittest.cc
@@ -42,14 +42,7 @@ class MockDelegate : public AppShimManager::Delegate { public: - virtual ~MockDelegate() { DCHECK(load_profile_callbacks_.empty()); } - - MOCK_METHOD1(ProfileForPath, Profile*(const base::FilePath&)); - void LoadProfileAsync(const base::FilePath& path, - base::OnceCallback<void(Profile*)> callback) override { - CaptureLoadProfileCallback(path, std::move(callback)); - } - MOCK_METHOD1(IsProfileLockedForPath, bool(const base::FilePath&)); + virtual ~MockDelegate() {} MOCK_METHOD2(ShowAppWindows, bool(Profile*, const std::string&)); MOCK_METHOD2(CloseAppWindows, void(Profile*, const std::string&)); @@ -63,8 +56,6 @@ void(Profile*, const std::string& app_id, const std::vector<base::FilePath>&)); - MOCK_METHOD2(OpenAppURLInBrowserWindow, - void(const base::FilePath&, const GURL& url)); // Conditionally mock LaunchShim. Some tests will execute |launch_callback| // with a particular value. @@ -87,9 +78,6 @@ terminated_shim_callback_capture_ = callback; } - MOCK_METHOD0(LaunchUserManager, void()); - - MOCK_METHOD0(MaybeTerminate, void()); MOCK_METHOD0(HasNonBookmarkAppWindowsOpen, bool()); void SetAppCanCreateHost(bool should_create_host) { @@ -99,34 +87,9 @@ return allow_shim_to_connect_; } - void SetHostForCreate(std::unique_ptr<AppShimHost> host_for_create) { - host_for_create_ = std::move(host_for_create); - } - std::unique_ptr<AppShimHost> CreateHost(AppShimHost::Client* client, - const base::FilePath& profile_path, - const std::string& app_id, - bool use_remote_cocoa) override { - DCHECK(host_for_create_); - std::unique_ptr<AppShimHost> result = std::move(host_for_create_); - return result; - } - - void CaptureLoadProfileCallback(const base::FilePath& path, - base::OnceCallback<void(Profile*)> callback) { - load_profile_callbacks_[path] = std::move(callback); - } - - bool RunLoadProfileCallback(const base::FilePath& path, Profile* profile) { - std::move(load_profile_callbacks_[path]).Run(profile); - return load_profile_callbacks_.erase(path); - } - private: ShimLaunchedCallback* launch_shim_callback_capture_ = nullptr; ShimTerminatedCallback* terminated_shim_callback_capture_ = nullptr; - std::map<base::FilePath, base::OnceCallback<void(Profile*)>> - load_profile_callbacks_; - std::unique_ptr<AppShimHost> host_for_create_ = nullptr; bool allow_shim_to_connect_ = true; }; @@ -134,7 +97,7 @@ public: TestingAppShimManager(std::unique_ptr<Delegate> delegate) : AppShimManager(std::move(delegate)) {} - virtual ~TestingAppShimManager() {} + virtual ~TestingAppShimManager() { DCHECK(load_profile_callbacks_.empty()); } MOCK_METHOD1(OnShimFocus, void(AppShimHost* host)); @@ -158,9 +121,43 @@ return is_acceptably_code_signed_; } + MOCK_METHOD1(ProfileForPath, Profile*(const base::FilePath&)); + void LoadProfileAsync(const base::FilePath& path, + base::OnceCallback<void(Profile*)> callback) override { + CaptureLoadProfileCallback(path, std::move(callback)); + } + MOCK_METHOD1(IsProfileLockedForPath, bool(const base::FilePath&)); + void SetHostForCreate(std::unique_ptr<AppShimHost> host_for_create) { + host_for_create_ = std::move(host_for_create); + } + std::unique_ptr<AppShimHost> CreateHost(AppShimHost::Client* client, + const base::FilePath& profile_path, + const std::string& app_id, + bool use_remote_cocoa) override { + DCHECK(host_for_create_); + std::unique_ptr<AppShimHost> result = std::move(host_for_create_); + return result; + } + MOCK_METHOD2(OpenAppURLInBrowserWindow, + void(const base::FilePath&, const GURL& url)); + MOCK_METHOD0(LaunchUserManager, void()); + MOCK_METHOD0(MaybeTerminate, void()); + + void CaptureLoadProfileCallback(const base::FilePath& path, + base::OnceCallback<void(Profile*)> callback) { + load_profile_callbacks_[path] = std::move(callback); + } + bool RunLoadProfileCallback(const base::FilePath& path, Profile* profile) { + std::move(load_profile_callbacks_[path]).Run(profile); + return load_profile_callbacks_.erase(path); + } + content::NotificationRegistrar& GetRegistrar() { return registrar(); } private: + std::map<base::FilePath, base::OnceCallback<void(Profile*)>> + load_profile_callbacks_; + std::unique_ptr<AppShimHost> host_for_create_ = nullptr; std::vector<chrome::mojom::ProfileMenuItemPtr> new_profile_menu_items_; bool is_acceptably_code_signed_ = true; DISALLOW_COPY_AND_ASSIGN(TestingAppShimManager); @@ -376,21 +373,21 @@ } // Tests that expect this call will override it. - EXPECT_CALL(*delegate_, OpenAppURLInBrowserWindow(_, _)).Times(0); + EXPECT_CALL(*manager_, OpenAppURLInBrowserWindow(_, _)).Times(0); - EXPECT_CALL(*delegate_, IsProfileLockedForPath(profile_path_a_)) + EXPECT_CALL(*manager_, IsProfileLockedForPath(profile_path_a_)) .WillRepeatedly(Return(false)); - EXPECT_CALL(*delegate_, ProfileForPath(profile_path_a_)) + EXPECT_CALL(*manager_, ProfileForPath(profile_path_a_)) .WillRepeatedly(Return(&profile_a_)); - EXPECT_CALL(*delegate_, IsProfileLockedForPath(profile_path_b_)) + EXPECT_CALL(*manager_, IsProfileLockedForPath(profile_path_b_)) .WillRepeatedly(Return(false)); - EXPECT_CALL(*delegate_, ProfileForPath(profile_path_b_)) + EXPECT_CALL(*manager_, ProfileForPath(profile_path_b_)) .WillRepeatedly(Return(&profile_b_)); - EXPECT_CALL(*delegate_, IsProfileLockedForPath(profile_path_c_)) + EXPECT_CALL(*manager_, IsProfileLockedForPath(profile_path_c_)) .WillRepeatedly(Return(false)); - EXPECT_CALL(*delegate_, ProfileForPath(profile_path_c_)) + EXPECT_CALL(*manager_, ProfileForPath(profile_path_c_)) .WillRepeatedly(Return(&profile_c_)); EXPECT_CALL(*delegate_, AppIsInstalled(&profile_a_, kTestAppIdA)) @@ -409,7 +406,7 @@ host_ab_unique_.reset(); host_bb_unique_.reset(); host_aa_duplicate_unique_.reset(); - delegate_->SetHostForCreate(nullptr); + manager_->SetHostForCreate(nullptr); manager_.reset(); // Delete the bootstraps via their weak pointers if they haven't been @@ -435,7 +432,7 @@ chrome::mojom::AppShimLaunchType launch_type, const std::vector<base::FilePath>& files) { if (host) - delegate_->SetHostForCreate(std::move(host)); + manager_->SetHostForCreate(std::move(host)); bootstrap->DoTestLaunch(launch_type, files); } @@ -524,31 +521,31 @@ TEST_F(AppShimManagerTest, LaunchProfileNotFound) { // Bad profile path, opens a bookmark app in a new window. - EXPECT_CALL(*delegate_, ProfileForPath(profile_path_a_)) + EXPECT_CALL(*manager_, ProfileForPath(profile_path_a_)) .WillRepeatedly(Return(static_cast<Profile*>(nullptr))); NormalLaunch(bootstrap_aa_, nullptr); - EXPECT_CALL(*delegate_, OpenAppURLInBrowserWindow(profile_path_a_, _)); - delegate_->RunLoadProfileCallback(profile_path_a_, nullptr); + EXPECT_CALL(*manager_, OpenAppURLInBrowserWindow(profile_path_a_, _)); + manager_->RunLoadProfileCallback(profile_path_a_, nullptr); EXPECT_EQ(chrome::mojom::AppShimLaunchResult::kProfileNotFound, *bootstrap_aa_result_); } TEST_F(AppShimManagerTest, LaunchProfileNotFoundNotBookmark) { // Bad profile path, not a bookmark app, doesn't open anything. - EXPECT_CALL(*delegate_, ProfileForPath(profile_path_a_)) + EXPECT_CALL(*manager_, ProfileForPath(profile_path_a_)) .WillRepeatedly(Return(static_cast<Profile*>(nullptr))); NormalLaunch(bootstrap_ab_, nullptr); - delegate_->RunLoadProfileCallback(profile_path_a_, nullptr); + manager_->RunLoadProfileCallback(profile_path_a_, nullptr); EXPECT_EQ(chrome::mojom::AppShimLaunchResult::kProfileNotFound, *bootstrap_ab_result_); } TEST_F(AppShimManagerTest, LaunchProfileIsLocked) { // Profile is locked. - EXPECT_CALL(*delegate_, IsProfileLockedForPath(profile_path_a_)) + EXPECT_CALL(*manager_, IsProfileLockedForPath(profile_path_a_)) .WillOnce(Return(true)); - EXPECT_CALL(*delegate_, LaunchUserManager()); - EXPECT_CALL(*delegate_, OpenAppURLInBrowserWindow(profile_path_a_, _)); + EXPECT_CALL(*manager_, LaunchUserManager()); + EXPECT_CALL(*manager_, OpenAppURLInBrowserWindow(profile_path_a_, _)); NormalLaunch(bootstrap_aa_, nullptr); EXPECT_EQ(chrome::mojom::AppShimLaunchResult::kProfileLocked, *bootstrap_aa_result_); @@ -560,7 +557,7 @@ .WillRepeatedly(Return(false)); EXPECT_CALL(*delegate_, EnableExtension(&profile_a_, kTestAppIdA, _)) .WillOnce(RunOnceCallback<2>()); - EXPECT_CALL(*delegate_, OpenAppURLInBrowserWindow(profile_path_a_, _)); + EXPECT_CALL(*manager_, OpenAppURLInBrowserWindow(profile_path_a_, _)); NormalLaunch(bootstrap_aa_, std::move(host_aa_unique_)); EXPECT_EQ(chrome::mojom::AppShimLaunchResult::kAppNotFound, *bootstrap_aa_result_); @@ -616,7 +613,7 @@ TEST_F(AppShimManagerTest, AppLifetime) { // When the app activates, a host is created. If there is no shim, one is // launched. - delegate_->SetHostForCreate(std::move(host_aa_unique_)); + manager_->SetHostForCreate(std::move(host_aa_unique_)); EXPECT_CALL(*delegate_, DoLaunchShim(&profile_a_, kTestAppIdA, false)); manager_->OnAppActivated(&profile_a_, kTestAppIdA); EXPECT_EQ(host_aa_.get(), manager_->FindHost(&profile_a_, kTestAppIdA)); @@ -651,7 +648,7 @@ EXPECT_EQ(nullptr, host_aa_.get()); // OnAppDeactivated should trigger a MaybeTerminate call. - EXPECT_CALL(*delegate_, MaybeTerminate()).WillOnce(Return()); + EXPECT_CALL(*manager_, MaybeTerminate()).WillOnce(Return()); manager_->OnAppDeactivated(&profile_a_, kTestAppIdA); } @@ -659,7 +656,7 @@ // When the app activates, it requests a launch. ShimLaunchedCallback launch_callback; delegate_->SetCaptureShimLaunchedCallback(&launch_callback); - delegate_->SetHostForCreate(std::move(host_aa_unique_)); + manager_->SetHostForCreate(std::move(host_aa_unique_)); EXPECT_CALL(*delegate_, DoLaunchShim(&profile_a_, kTestAppIdA, false)); manager_->OnAppActivated(&profile_a_, kTestAppIdA); EXPECT_EQ(host_aa_.get(), manager_->FindHost(&profile_a_, kTestAppIdA)); @@ -684,7 +681,7 @@ ShimTerminatedCallback terminated_callback; delegate_->SetCaptureShimTerminatedCallback(&terminated_callback); - delegate_->SetHostForCreate(std::move(host_aa_unique_)); + manager_->SetHostForCreate(std::move(host_aa_unique_)); EXPECT_CALL(*delegate_, DoLaunchShim(&profile_a_, kTestAppIdA, false)); manager_->OnAppActivated(&profile_a_, kTestAppIdA); EXPECT_EQ(host_aa_.get(), manager_->FindHost(&profile_a_, kTestAppIdA)); @@ -764,11 +761,11 @@ EXPECT_EQ(host_ab_.get(), manager_->FindHost(&profile_a_, kTestAppIdB)); // Quitting when there's another shim should not terminate. - EXPECT_CALL(*delegate_, MaybeTerminate()).Times(0); + EXPECT_CALL(*manager_, MaybeTerminate()).Times(0); manager_->OnAppDeactivated(&profile_a_, kTestAppIdA); // Quitting when it's the last shim should terminate. - EXPECT_CALL(*delegate_, MaybeTerminate()); + EXPECT_CALL(*manager_, MaybeTerminate()); manager_->OnAppDeactivated(&profile_a_, kTestAppIdB); } @@ -802,12 +799,12 @@ // If the profile is not loaded when an OnShimProcessConnected arrives, return // false and load the profile asynchronously. Launch the app when the profile // is ready. - EXPECT_CALL(*delegate_, ProfileForPath(profile_path_a_)) + EXPECT_CALL(*manager_, ProfileForPath(profile_path_a_)) .WillOnce(Return(static_cast<Profile*>(nullptr))) .WillRepeatedly(Return(&profile_a_)); NormalLaunch(bootstrap_aa_, std::move(host_aa_unique_)); EXPECT_FALSE(manager_->FindHost(&profile_a_, kTestAppIdA)); - delegate_->RunLoadProfileCallback(profile_path_a_, &profile_a_); + manager_->RunLoadProfileCallback(profile_path_a_, &profile_a_); EXPECT_TRUE(manager_->FindHost(&profile_a_, kTestAppIdA)); } @@ -831,7 +828,7 @@ TEST_F(AppShimManagerTest, PreExistingHost) { // Create a host for our profile. - delegate_->SetHostForCreate(std::move(host_aa_unique_)); + manager_->SetHostForCreate(std::move(host_aa_unique_)); EXPECT_EQ(nullptr, manager_->FindHost(&profile_a_, kTestAppIdA)); EXPECT_CALL(*delegate_, DoLaunchShim(&profile_a_, kTestAppIdA, false)) .Times(1); @@ -867,14 +864,14 @@ // Test with a bookmark app (host is shared). { // Create a host for profile A. - delegate_->SetHostForCreate(std::move(host_aa_unique_)); + manager_->SetHostForCreate(std::move(host_aa_unique_)); EXPECT_EQ(nullptr, manager_->FindHost(&profile_a_, kTestAppIdA)); manager_->OnAppActivated(&profile_a_, kTestAppIdA); EXPECT_EQ(host_aa_.get(), manager_->FindHost(&profile_a_, kTestAppIdA)); EXPECT_FALSE(host_aa_->did_connect_to_host()); // Ensure that profile B has the same host. - delegate_->SetHostForCreate(std::move(host_ba_unique_)); + manager_->SetHostForCreate(std::move(host_ba_unique_)); EXPECT_EQ(nullptr, manager_->FindHost(&profile_b_, kTestAppIdA)); manager_->OnAppActivated(&profile_b_, kTestAppIdA); EXPECT_EQ(host_aa_.get(), manager_->FindHost(&profile_b_, kTestAppIdA)); @@ -884,14 +881,14 @@ // Test with a non-bookmark app (host is not shared). { // Create a host for profile A. - delegate_->SetHostForCreate(std::move(host_ab_unique_)); + manager_->SetHostForCreate(std::move(host_ab_unique_)); EXPECT_EQ(nullptr, manager_->FindHost(&profile_a_, kTestAppIdB)); manager_->OnAppActivated(&profile_a_, kTestAppIdB); EXPECT_EQ(host_ab_.get(), manager_->FindHost(&profile_a_, kTestAppIdB)); EXPECT_FALSE(host_ab_->did_connect_to_host()); // Ensure that profile B has the same host. - delegate_->SetHostForCreate(std::move(host_bb_unique_)); + manager_->SetHostForCreate(std::move(host_bb_unique_)); EXPECT_EQ(nullptr, manager_->FindHost(&profile_b_, kTestAppIdB)); manager_->OnAppActivated(&profile_b_, kTestAppIdB); EXPECT_EQ(host_bb_.get(), manager_->FindHost(&profile_b_, kTestAppIdB)); @@ -900,7 +897,7 @@ } TEST_F(AppShimManagerTest, MultiProfileShimLaunch) { - delegate_->SetHostForCreate(std::move(host_aa_unique_)); + manager_->SetHostForCreate(std::move(host_aa_unique_)); ShimLaunchedCallback launched_callback; delegate_->SetCaptureShimLaunchedCallback(&launched_callback); ShimTerminatedCallback terminated_callback; @@ -927,7 +924,7 @@ } TEST_F(AppShimManagerTest, MultiProfileSelectMenu) { - delegate_->SetHostForCreate(std::move(host_aa_unique_)); + manager_->SetHostForCreate(std::move(host_aa_unique_)); ShimLaunchedCallback launched_callback; delegate_->SetCaptureShimLaunchedCallback(&launched_callback); ShimTerminatedCallback terminated_callback; @@ -979,7 +976,7 @@ // When the app activates, a host is created. This will trigger building // the avatar menu. - delegate_->SetHostForCreate(std::move(host_aa_unique_)); + manager_->SetHostForCreate(std::move(host_aa_unique_)); EXPECT_CALL(*delegate_, DoLaunchShim(&profile_a_, kTestAppIdA, false)); manager_->OnAppActivated(&profile_a_, kTestAppIdA); EXPECT_EQ(host_aa_.get(), manager_->FindHost(&profile_a_, kTestAppIdA)); @@ -1038,7 +1035,7 @@ AppShimRegistry::Get()->OnAppQuit(kTestAppIdA, last_active_profile_paths); // Launch the shim requesting profile C. - delegate_->SetHostForCreate(std::move(host_aa_unique_)); + manager_->SetHostForCreate(std::move(host_aa_unique_)); EXPECT_CALL(*delegate_, LaunchApp(&profile_a_, kTestAppIdA, _)).Times(1); EXPECT_CALL(*delegate_, LaunchApp(&profile_b_, kTestAppIdA, _)).Times(0); EXPECT_CALL(*delegate_, EnableExtension(&profile_c_, kTestAppIdA, _)) @@ -1055,7 +1052,7 @@ profile_path_a_); // Launch the shim without specifying a profile. - delegate_->SetHostForCreate(std::move(host_aa_unique_)); + manager_->SetHostForCreate(std::move(host_aa_unique_)); EXPECT_CALL(*delegate_, LaunchApp(&profile_a_, kTestAppIdA, _)).Times(1); EXPECT_CALL(*delegate_, LaunchApp(&profile_b_, kTestAppIdA, _)).Times(0); NormalLaunch(bootstrap_xa_, nullptr);
diff --git a/chrome/browser/apps/app_shim/web_app_shim_manager_delegate_mac.cc b/chrome/browser/apps/app_shim/web_app_shim_manager_delegate_mac.cc new file mode 100644 index 0000000..b81d9d6a --- /dev/null +++ b/chrome/browser/apps/app_shim/web_app_shim_manager_delegate_mac.cc
@@ -0,0 +1,141 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/apps/app_shim/web_app_shim_manager_delegate_mac.h" + +#include "chrome/browser/apps/app_service/app_launch_params.h" +#include "chrome/browser/apps/launch_service/launch_service.h" +#include "chrome/browser/web_applications/components/app_shortcut_manager.h" +#include "chrome/browser/web_applications/components/web_app_shortcut_mac.h" +#include "chrome/browser/web_applications/web_app_provider.h" + +namespace web_app { + +WebAppShimManagerDelegate::WebAppShimManagerDelegate( + std::unique_ptr<apps::AppShimManager::Delegate> fallback_delegate) + : fallback_delegate_(std::move(fallback_delegate)) {} + +WebAppShimManagerDelegate::~WebAppShimManagerDelegate() = default; + +bool WebAppShimManagerDelegate::ShowAppWindows(Profile* profile, + const AppId& app_id) { + if (UseFallback(profile, app_id)) + return fallback_delegate_->ShowAppWindows(profile, app_id); + // This is only used by legacy apps. + NOTREACHED(); + return false; +} + +void WebAppShimManagerDelegate::CloseAppWindows(Profile* profile, + const AppId& app_id) { + if (UseFallback(profile, app_id)) { + fallback_delegate_->CloseAppWindows(profile, app_id); + return; + } + // This is only used by legacy apps. + NOTREACHED(); +} + +bool WebAppShimManagerDelegate::AppIsInstalled(Profile* profile, + const AppId& app_id) { + if (UseFallback(profile, app_id)) { + return fallback_delegate_->AppIsInstalled(profile, app_id); + } + return profile && + WebAppProvider::Get(profile)->registrar().IsInstalled(app_id); +} + +bool WebAppShimManagerDelegate::AppCanCreateHost(Profile* profile, + const AppId& app_id) { + if (UseFallback(profile, app_id)) + return fallback_delegate_->AppCanCreateHost(profile, app_id); + // All PWAs and bookmark apps can attach to a host. + return AppIsInstalled(profile, app_id); +} + +bool WebAppShimManagerDelegate::AppUsesRemoteCocoa(Profile* profile, + const AppId& app_id) { + if (UseFallback(profile, app_id)) + return fallback_delegate_->AppUsesRemoteCocoa(profile, app_id); + // All PWAs and bookmark apps use RemoteCocoa. + return AppIsInstalled(profile, app_id); +} + +bool WebAppShimManagerDelegate::AppIsMultiProfile(Profile* profile, + const AppId& app_id) { + if (UseFallback(profile, app_id)) + return fallback_delegate_->AppIsMultiProfile(profile, app_id); + // All PWAs and bookmark apps are multi-profile. + return AppIsInstalled(profile, app_id); +} + +void WebAppShimManagerDelegate::EnableExtension( + Profile* profile, + const std::string& extension_id, + base::OnceCallback<void()> callback) { + if (UseFallback(profile, extension_id)) { + fallback_delegate_->EnableExtension(profile, extension_id, + std::move(callback)); + return; + } + std::move(callback).Run(); +} + +void WebAppShimManagerDelegate::LaunchApp( + Profile* profile, + const AppId& app_id, + const std::vector<base::FilePath>& files) { + DCHECK(AppIsInstalled(profile, app_id)); + if (UseFallback(profile, app_id)) { + fallback_delegate_->LaunchApp(profile, app_id, files); + return; + } + DisplayMode display_mode = + WebAppProvider::Get(profile)->registrar().GetAppUserDisplayMode(app_id); + apps::mojom::LaunchContainer launch_container = + web_app::ConvertDisplayModeToAppLaunchContainer(display_mode); + apps::AppLaunchParams params( + app_id, launch_container, WindowOpenDisposition::NEW_FOREGROUND_TAB, + apps::mojom::AppLaunchSource::kSourceCommandLine); + params.launch_files = files; + apps::LaunchService::Get(profile)->OpenApplication(params); +} + +void WebAppShimManagerDelegate::LaunchShim( + Profile* profile, + const AppId& app_id, + bool recreate_shims, + apps::ShimLaunchedCallback launched_callback, + apps::ShimTerminatedCallback terminated_callback) { + DCHECK(AppIsInstalled(profile, app_id)); + if (UseFallback(profile, app_id)) { + fallback_delegate_->LaunchShim(profile, app_id, recreate_shims, + std::move(launched_callback), + std::move(terminated_callback)); + return; + } + WebAppProvider::Get(profile)->shortcut_manager().GetShortcutInfoForApp( + app_id, + base::BindOnce( + &web_app::LaunchShim, + recreate_shims ? LaunchShimUpdateBehavior::RECREATE_UNCONDITIONALLY + : LaunchShimUpdateBehavior::DO_NOT_RECREATE, + std::move(launched_callback), std::move(terminated_callback))); +} + +bool WebAppShimManagerDelegate::HasNonBookmarkAppWindowsOpen() { + if (fallback_delegate_) + return fallback_delegate_->HasNonBookmarkAppWindowsOpen(); + // PWAs and bookmark apps do not participate in custom app quit behavior. + return false; +} + +bool WebAppShimManagerDelegate::UseFallback(Profile* profile, + const AppId& app_id) const { + if (!fallback_delegate_) + return false; + return fallback_delegate_->AppIsInstalled(profile, app_id); +} + +} // namespace web_app
diff --git a/chrome/browser/apps/app_shim/web_app_shim_manager_delegate_mac.h b/chrome/browser/apps/app_shim/web_app_shim_manager_delegate_mac.h new file mode 100644 index 0000000..eaf42b4d --- /dev/null +++ b/chrome/browser/apps/app_shim/web_app_shim_manager_delegate_mac.h
@@ -0,0 +1,48 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_APPS_APP_SHIM_WEB_APP_SHIM_MANAGER_DELEGATE_MAC_H_ +#define CHROME_BROWSER_APPS_APP_SHIM_WEB_APP_SHIM_MANAGER_DELEGATE_MAC_H_ + +#include "chrome/browser/apps/app_shim/app_shim_manager_mac.h" + +namespace web_app { + +class WebAppShimManagerDelegate : public apps::AppShimManager::Delegate { + public: + // AppShimManager::Delegate: + WebAppShimManagerDelegate( + std::unique_ptr<apps::AppShimManager::Delegate> fallback_delegate); + ~WebAppShimManagerDelegate() override; + bool ShowAppWindows(Profile* profile, const AppId& app_id) override; + void CloseAppWindows(Profile* profile, const AppId& app_id) override; + bool AppIsInstalled(Profile* profile, const AppId& app_id) override; + bool AppCanCreateHost(Profile* profile, const AppId& app_id) override; + bool AppUsesRemoteCocoa(Profile* profile, const AppId& app_id) override; + bool AppIsMultiProfile(Profile* profile, const AppId& app_id) override; + void EnableExtension(Profile* profile, + const std::string& extension_id, + base::OnceCallback<void()> callback) override; + void LaunchApp(Profile* profile, + const AppId& app_id, + const std::vector<base::FilePath>& files) override; + void LaunchShim(Profile* profile, + const AppId& app_id, + bool recreate_shims, + apps::ShimLaunchedCallback launched_callback, + apps::ShimTerminatedCallback terminated_callback) override; + bool HasNonBookmarkAppWindowsOpen() override; + + private: + // Return true if |fallback_delegate_| should be used instead of |this|. + bool UseFallback(Profile* profile, const AppId& app_id) const; + + // This is the delegate used by extension-based applications. When they are + // removed, then this may be deleted. + std::unique_ptr<apps::AppShimManager::Delegate> fallback_delegate_; +}; + +} // namespace web_app + +#endif // CHROME_BROWSER_APPS_APP_SHIM_WEB_APP_SHIM_MANAGER_DELEGATE_MAC_H_
diff --git a/chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.cc b/chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.cc index 2e756fbc..ce39442 100644 --- a/chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.cc +++ b/chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.cc
@@ -16,7 +16,6 @@ #include "chrome/browser/ui/extensions/app_launch_params.h" #include "chrome/browser/ui/extensions/extension_enable_flow.h" #include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h" -#include "chrome/browser/ui/user_manager.h" #include "chrome/browser/web_applications/components/web_app_shortcut_mac.h" #include "chrome/browser/web_applications/extensions/web_app_extension_shortcut.h" #include "chrome/browser/web_applications/extensions/web_app_extension_shortcut_mac.h" @@ -93,28 +92,6 @@ ExtensionAppShimManagerDelegate::ExtensionAppShimManagerDelegate() = default; ExtensionAppShimManagerDelegate::~ExtensionAppShimManagerDelegate() = default; -Profile* ExtensionAppShimManagerDelegate::ProfileForPath( - const base::FilePath& full_path) { - ProfileManager* profile_manager = g_browser_process->profile_manager(); - Profile* profile = profile_manager->GetProfileByPath(full_path); - - // Use IsValidProfile to check if the profile has been created. - return profile && profile_manager->IsValidProfile(profile) ? profile - : nullptr; -} - -void ExtensionAppShimManagerDelegate::LoadProfileAsync( - const base::FilePath& full_path, - base::OnceCallback<void(Profile*)> callback) { - ProfileManager* profile_manager = g_browser_process->profile_manager(); - profile_manager->LoadProfileByPath(full_path, false, std::move(callback)); -} - -bool ExtensionAppShimManagerDelegate::IsProfileLockedForPath( - const base::FilePath& full_path) { - return profiles::IsProfileLocked(full_path); -} - bool ExtensionAppShimManagerDelegate::ShowAppWindows( Profile* profile, const web_app::AppId& app_id) { @@ -179,15 +156,6 @@ return extension->is_hosted_app() && extension->from_bookmark(); } -std::unique_ptr<AppShimHost> ExtensionAppShimManagerDelegate::CreateHost( - AppShimHost::Client* client, - const base::FilePath& profile_path, - const web_app::AppId& app_id, - bool use_remote_cocoa) { - return std::make_unique<AppShimHost>(client, app_id, profile_path, - use_remote_cocoa); -} - void ExtensionAppShimManagerDelegate::EnableExtension( Profile* profile, const web_app::AppId& app_id, @@ -226,24 +194,6 @@ } } -void ExtensionAppShimManagerDelegate::OpenAppURLInBrowserWindow( - const base::FilePath& profile_path, - const GURL& url) { - Profile* profile = - profile_path.empty() ? nullptr : ProfileForPath(profile_path); - if (!profile) - profile = g_browser_process->profile_manager()->GetLastUsedProfile(); - if (!profile) - return; - Browser* browser = - new Browser(Browser::CreateParams(Browser::TYPE_NORMAL, profile, true)); - browser->window()->Show(); - NavigateParams params(browser, url, ui::PAGE_TRANSITION_AUTO_BOOKMARK); - params.tabstrip_add_types = TabStripModel::ADD_ACTIVE; - params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; - Navigate(¶ms); -} - void ExtensionAppShimManagerDelegate::LaunchShim( Profile* profile, const web_app::AppId& app_id, @@ -251,11 +201,7 @@ apps::ShimLaunchedCallback launched_callback, apps::ShimTerminatedCallback terminated_callback) { const Extension* extension = MaybeGetAppExtension(profile, app_id); - if (!extension) { - std::move(launched_callback).Run(base::Process()); - return; - } - + DCHECK(extension); // Only force recreation of shims when RemoteViews is in use (that is, for // PWAs). Otherwise, shims may be created unexpectedly. // https://crbug.com/941160 @@ -276,15 +222,6 @@ } } -void ExtensionAppShimManagerDelegate::LaunchUserManager() { - UserManager::Show(base::FilePath(), - profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION); -} - -void ExtensionAppShimManagerDelegate::MaybeTerminate() { - apps::AppShimTerminationManager::Get()->MaybeTerminate(); -} - bool ExtensionAppShimManagerDelegate::HasNonBookmarkAppWindowsOpen() { return AppWindowRegistryUtil::IsAppWindowVisibleInAnyProfile(0); }
diff --git a/chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.h b/chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.h index 5402998..d641c44 100644 --- a/chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.h +++ b/chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.h
@@ -14,10 +14,6 @@ // AppShimManager::Delegate: ExtensionAppShimManagerDelegate(); ~ExtensionAppShimManagerDelegate() override; - Profile* ProfileForPath(const base::FilePath& path) override; - void LoadProfileAsync(const base::FilePath& path, - base::OnceCallback<void(Profile*)> callback) override; - bool IsProfileLockedForPath(const base::FilePath& path) override; bool ShowAppWindows(Profile* profile, const web_app::AppId& app_id) override; void CloseAppWindows(Profile* profile, const web_app::AppId& app_id) override; bool AppIsInstalled(Profile* profile, const web_app::AppId& app_id) override; @@ -27,25 +23,17 @@ const web_app::AppId& app_id) override; bool AppIsMultiProfile(Profile* profile, const web_app::AppId& app_id) override; - std::unique_ptr<AppShimHost> CreateHost(AppShimHost::Client* client, - const base::FilePath& profile_path, - const web_app::AppId& app_id, - bool use_remote_cocoa) override; void EnableExtension(Profile* profile, const std::string& extension_id, base::OnceCallback<void()> callback) override; void LaunchApp(Profile* profile, const web_app::AppId& app_id, const std::vector<base::FilePath>& files) override; - void OpenAppURLInBrowserWindow(const base::FilePath& profile_path, - const GURL& url) override; void LaunchShim(Profile* profile, const web_app::AppId& app_id, bool recreate_shims, ShimLaunchedCallback launched_callback, ShimTerminatedCallback terminated_callback) override; - void LaunchUserManager() override; - void MaybeTerminate() override; bool HasNonBookmarkAppWindowsOpen() override; };
diff --git a/chrome/browser/browser_process_platform_part_mac.mm b/chrome/browser/browser_process_platform_part_mac.mm index f9704811..36e8161 100644 --- a/chrome/browser/browser_process_platform_part_mac.mm +++ b/chrome/browser/browser_process_platform_part_mac.mm
@@ -4,13 +4,16 @@ #include "chrome/browser/browser_process_platform_part_mac.h" +#include "base/feature_list.h" #include "base/mac/foundation_util.h" #include "base/metrics/histogram_macros.h" #include "base/time/time.h" #import "chrome/browser/app_controller_mac.h" #include "chrome/browser/apps/app_shim/app_shim_manager_mac.h" +#include "chrome/browser/apps/app_shim/web_app_shim_manager_delegate_mac.h" #include "chrome/browser/apps/platform_apps/extension_app_shim_manager_delegate_mac.h" #include "chrome/browser/chrome_browser_application_mac.h" +#include "chrome/common/chrome_features.h" #include "components/metal_util/test_shader.h" namespace { @@ -71,8 +74,21 @@ } void BrowserProcessPlatformPart::PreMainMessageLoopRun() { + // Create two AppShimManager::Delegates -- one for extensions-based apps + // (which will be deprecatedin 2020), and one for web apps (PWAs and + // bookmark apps). The WebAppShimManagerDelegate will defer to the + // ExtensionAppShimManagerDelegate passed to it for extension-based apps. + // When extension-based apps are deprecated, the + // ExtensionAppShimManagerDelegate may be changed to nullptr here. + std::unique_ptr<apps::AppShimManager::Delegate> app_shim_manager_delegate = + std::make_unique<apps::ExtensionAppShimManagerDelegate>(); + if (base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions)) { + app_shim_manager_delegate = + std::make_unique<web_app::WebAppShimManagerDelegate>( + std::move(app_shim_manager_delegate)); + } app_shim_manager_ = std::make_unique<apps::AppShimManager>( - std::make_unique<apps::ExtensionAppShimManagerDelegate>()); + std::move(app_shim_manager_delegate)); // AppShimListener can not simply be reset, otherwise destroying the old // domain socket will cause the just-created socket to be unlinked.
diff --git a/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc b/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc index 1127656a..192ac33 100644 --- a/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/select_to_speak_browsertest.cc
@@ -16,7 +16,6 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/memory/weak_ptr.h" -#include "base/strings/pattern.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/accessibility/speech_monitor.h" #include "chrome/browser/profiles/profile.h" @@ -74,7 +73,7 @@ ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); } - SpeechMonitor speech_monitor_; + SpeechMonitor sm_; std::unique_ptr<ui::test::EventGenerator> generator_; gfx::Rect GetWebContentsBounds() const { @@ -140,8 +139,8 @@ return browser()->tab_strip_model()->GetActiveWebContents(); } - void ExecuteJavaScriptInForeground(const std::string& script) { - CHECK(content::ExecuteScript(GetWebContents(), script)); + void ExecuteJavaScriptAsync(const std::string& script) { + content::ExecuteScriptAsync(GetWebContents(), script); } private: @@ -176,8 +175,8 @@ generator_->ReleaseLeftButton(); generator_->ReleaseKey(ui::VKEY_LWIN, 0 /* flags */); - EXPECT_TRUE( - base::MatchPattern(speech_monitor_.GetNextUtterance(), "Status tray*")); + sm_.ExpectSpeechPattern("Status tray*"); + sm_.Replay(); } IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, ActivatesWithTapOnSelectToSpeakTray) { @@ -199,8 +198,8 @@ bounds.y() + bounds.height()); generator_->ReleaseLeftButton(); - EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(), - "This is some text*")); + sm_.ExpectSpeechPattern("This is some text*"); + sm_.Replay(); } IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SelectToSpeakTrayNotSpoken) { @@ -218,8 +217,9 @@ // The next should be the first thing spoken -- the tray was not spoken. ActivateSelectToSpeakInWindowBounds( "data:text/html;charset=utf-8,<p>This is some text</p>"); - EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(), - "This is some text*")); + + sm_.ExpectSpeechPattern("This is some text*"); + sm_.Replay(); } IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SmoothlyReadsAcrossInlineUrl) { @@ -230,9 +230,8 @@ // Should combine nodes in a paragraph into one utterance. // Includes some wildcards between words because there may be extra // spaces. Spaces are not pronounced, so extra spaces do not impact output. - EXPECT_TRUE( - base::MatchPattern(speech_monitor_.GetNextUtterance(), - "This is some text*with a node*in the middle*")); + sm_.ExpectSpeechPattern("This is some text*with a node*in the middle*"); + sm_.Replay(); } IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SmoothlyReadsAcrossMultipleLines) { @@ -245,9 +244,8 @@ // spaces, for example at line wraps. Extra wildcards included to // reduce flakyness in case wrapping is not consistent. // Spaces are not pronounced, so extra spaces do not impact output. - EXPECT_TRUE( - base::MatchPattern(speech_monitor_.GetNextUtterance(), - "This is some*text*with*a*node*in*the*middle*")); + sm_.ExpectSpeechPattern("This is some*text*with*a*node*in*the*middle*"); + sm_.Replay(); } IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, SmoothlyReadsAcrossFormattedText) { @@ -259,9 +257,8 @@ // Should combine nodes in a paragraph into one utterance. // Includes some wildcards between words because there may be extra // spaces. Spaces are not pronounced, so extra spaces do not impact output. - EXPECT_TRUE( - base::MatchPattern(speech_monitor_.GetNextUtterance(), - "This is some text*with a node*in the middle*")); + sm_.ExpectSpeechPattern("This is some text*with a node*in the middle*"); + sm_.Replay(); } IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, @@ -269,8 +266,9 @@ // Bold or formatted text ActivateSelectToSpeakInWindowBounds( "data:text/html;charset=utf-8,<canvas>This is some text</canvas>"); - EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(), - "This is some text*")); + + sm_.ExpectSpeechPattern("This is some text*"); + sm_.Replay(); } IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, BreaksAtParagraphBounds) { @@ -279,10 +277,9 @@ "<p>Second paragraph</p></div>"); // Should keep each paragraph as its own utterance. - EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(), - "First paragraph*")); - EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(), - "Second paragraph*")); + sm_.ExpectSpeechPattern("First paragraph*"); + sm_.ExpectSpeechPattern("Second paragraph*"); + sm_.Replay(); } IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, LanguageBoundsIgnoredByDefault) { @@ -293,9 +290,8 @@ "<span lang='en-US'>The first paragraph</span>" "<span lang='fr-FR'>la deuxième paragraphe</span></div>"); - EXPECT_TRUE( - base::MatchPattern(speech_monitor_.GetNextUtterance(), - "The first paragraph* la deuxième paragraphe*")); + sm_.ExpectSpeechPattern("The first paragraph* la deuxième paragraphe*"); + sm_.Replay(); } IN_PROC_BROWSER_TEST_F(SelectToSpeakTestWithLanguageDetection, @@ -305,15 +301,9 @@ "<span lang='en-US'>The first paragraph</span>" "<span lang='fr-FR'>la deuxième paragraphe</span></div>"); - SpeechMonitorUtterance result1 = - speech_monitor_.GetNextUtteranceWithLanguage(); - EXPECT_TRUE(base::MatchPattern(result1.text, "The first paragraph*")); - EXPECT_EQ("en-US", result1.lang); - - SpeechMonitorUtterance result2 = - speech_monitor_.GetNextUtteranceWithLanguage(); - EXPECT_TRUE(base::MatchPattern(result2.text, "la deuxième paragraphe*")); - EXPECT_EQ("fr-FR", result2.lang); + sm_.ExpectSpeechPatternWithLocale("The first paragraph*", "en-US"); + sm_.ExpectSpeechPatternWithLocale("la deuxième paragraphe*", "fr-FR"); + sm_.Replay(); } // Flaky test. https://crbug.com/950049 @@ -399,15 +389,16 @@ "<p>Second paragraph is longer than 300 pixels and will wrap when " "resized</p></div>"); - EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(), - "First paragraph*")); + sm_.ExpectSpeechPattern("First paragraph*"); // Resize before second is spoken. If resizing caused errors finding the // inlineTextBoxes in the node, speech would be stopped early. - ExecuteJavaScriptInForeground( - "document.getElementById('resize').style.width='100px'"); - EXPECT_TRUE( - base::MatchPattern(speech_monitor_.GetNextUtterance(), "*when*resized*")); + sm_.Call([this]() { + ExecuteJavaScriptAsync( + "document.getElementById('resize').style.width='100px'"); + }); + sm_.ExpectSpeechPattern("*when*resized*"); + sm_.Replay(); } IN_PROC_BROWSER_TEST_F(SelectToSpeakTest, WorksWithStickyKeys) { @@ -429,11 +420,12 @@ bounds.y() + bounds.height()); generator_->ReleaseLeftButton(); - EXPECT_TRUE(base::MatchPattern(speech_monitor_.GetNextUtterance(), - "This is some text*")); + sm_.ExpectSpeechPattern("This is some text*"); // Reset state. - AccessibilityManager::Get()->EnableStickyKeys(false); + sm_.Call([]() { AccessibilityManager::Get()->EnableStickyKeys(false); }); + + sm_.Replay(); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/accessibility/speech_monitor.cc b/chrome/browser/chromeos/accessibility/speech_monitor.cc index 0d84ff4..6516aa3 100644 --- a/chrome/browser/chromeos/accessibility/speech_monitor.cc +++ b/chrome/browser/chromeos/accessibility/speech_monitor.cc
@@ -12,12 +12,9 @@ namespace chromeos { namespace { -const char kChromeVoxEnabledMessage[] = "ChromeVox spoken feedback is ready"; -const char kChromeVoxAlertMessage[] = "Alert"; -const char kChromeVoxUpdate1[] = "chrome vox Updated Press chrome vox o,"; -const char kChromeVoxUpdate2[] = "n to learn more about chrome vox Next."; constexpr int kPrintExpectationDelayMs = 3000; + } // namespace SpeechMonitor::SpeechMonitor() { @@ -31,52 +28,6 @@ CHECK(replay_called_) << "Expectation was made, but Replay() not called."; } -std::string SpeechMonitor::GetNextUtterance() { - return GetNextUtteranceWithLanguage().text; -} - -SpeechMonitorUtterance SpeechMonitor::GetNextUtteranceWithLanguage() { - if (utterance_queue_.empty()) { - loop_runner_ = new content::MessageLoopRunner(); - loop_runner_->Run(); - loop_runner_.reset(); - } - SpeechMonitorUtterance result = utterance_queue_.front(); - utterance_queue_.pop_front(); - return result; -} - -bool SpeechMonitor::SkipChromeVoxEnabledMessage() { - return SkipChromeVoxMessage(kChromeVoxEnabledMessage); -} - -bool SpeechMonitor::DidStop() { - return did_stop_; -} - -void SpeechMonitor::BlockUntilStop() { - if (!did_stop_) { - loop_runner_ = new content::MessageLoopRunner(); - loop_runner_->Run(); - loop_runner_.reset(); - } -} - -bool SpeechMonitor::SkipChromeVoxMessage(const std::string& message) { - while (true) { - if (utterance_queue_.empty()) { - loop_runner_ = new content::MessageLoopRunner(); - loop_runner_->Run(); - loop_runner_.reset(); - } - SpeechMonitorUtterance result = utterance_queue_.front(); - utterance_queue_.pop_front(); - if (result.text == message) - return true; - } - return false; -} - bool SpeechMonitor::PlatformImplAvailable() { return true; } @@ -95,7 +46,6 @@ } bool SpeechMonitor::StopSpeaking() { - did_stop_ = true; return true; } @@ -114,21 +64,8 @@ void SpeechMonitor::WillSpeakUtteranceWithVoice( content::TtsUtterance* utterance, const content::VoiceData& voice_data) { - // Blacklist some phrases. - // Filter out empty utterances which can be used to trigger a start event from - // tts as an earcon sync. - if (utterance->GetText() == "" || - utterance->GetText() == kChromeVoxAlertMessage || - utterance->GetText() == kChromeVoxUpdate1 || - utterance->GetText() == kChromeVoxUpdate2) - return; - - VLOG(0) << "Speaking " << utterance->GetText(); utterance_queue_.emplace_back(utterance->GetText(), utterance->GetLang()); delay_for_last_utterance_ms_ = CalculateUtteranceDelayMS(); - if (loop_runner_.get()) - loop_runner_->Quit(); - MaybeContinueReplay(); } @@ -183,11 +120,19 @@ void SpeechMonitor::ExpectSpeechPattern(const std::string& pattern, const base::Location& location) { + ExpectSpeechPatternWithLocale(pattern, "", location); +} + +void SpeechMonitor::ExpectSpeechPatternWithLocale( + const std::string& pattern, + const std::string& locale, + const base::Location& location) { CHECK(!replay_loop_runner_.get()); - replay_queue_.push_back({[this, pattern]() { + replay_queue_.push_back({[this, pattern, locale]() { for (auto it = utterance_queue_.begin(); it != utterance_queue_.end(); it++) { - if (base::MatchPattern(it->text, pattern)) { + if (base::MatchPattern(it->text, pattern) && + (locale.empty() || it->lang == locale)) { // Erase all utterances that came before the // match as well as the match itself. utterance_queue_.erase(
diff --git a/chrome/browser/chromeos/accessibility/speech_monitor.h b/chrome/browser/chromeos/accessibility/speech_monitor.h index eb319a6..368de795 100644 --- a/chrome/browser/chromeos/accessibility/speech_monitor.h +++ b/chrome/browser/chromeos/accessibility/speech_monitor.h
@@ -25,35 +25,13 @@ }; // For testing purpose installs itself as the platform speech synthesis engine, -// allowing it to intercept all speech calls, and then provides a method to -// block until the next utterance is spoken. +// allowing it to intercept all speech calls. Provides an api to make +// asynchronous function calls and expectations about resulting speech. class SpeechMonitor : public content::TtsPlatform { public: SpeechMonitor(); virtual ~SpeechMonitor(); - // Blocing api. - // Use the following apis to write a synchronous test e.g. - // DoSomething(); - // EXPECT_EQ("foo", speech_monitor_.GetNextUtterance()); - - // Blocks until the next utterance is spoken, and returns its text. - std::string GetNextUtterance(); - // Blocks until the next utterance is spoken, and returns its text. - SpeechMonitorUtterance GetNextUtteranceWithLanguage(); - - // Wait for next utterance and return true if next utterance is ChromeVox - // enabled message. - bool SkipChromeVoxEnabledMessage(); - bool SkipChromeVoxMessage(const std::string& message); - - // Returns true if StopSpeaking() was called on TtsController. - bool DidStop(); - - // Blocks until StopSpeaking() is called on TtsController. - void BlockUntilStop(); - - // Non-blocking api. // Use these apis if you want to write an async test e.g. // sm_.ExpectSpeech("foo"); // sm_.Call([this]() { DoSomething(); }) @@ -67,6 +45,10 @@ const base::Location& location = FROM_HERE); void ExpectSpeechPattern(const std::string& pattern, const base::Location& location = FROM_HERE); + void ExpectSpeechPatternWithLocale( + const std::string& pattern, + const std::string& locale, + const base::Location& location = FROM_HERE); void ExpectNextSpeechIsNot(const std::string& text, const base::Location& location = FROM_HERE); void ExpectNextSpeechIsNotPattern(const std::string& pattern, @@ -111,17 +93,17 @@ void MaybeContinueReplay(); void MaybePrintExpectations(); - scoped_refptr<content::MessageLoopRunner> loop_runner_; // Our list of utterances and specified language. base::circular_deque<SpeechMonitorUtterance> utterance_queue_; - bool did_stop_ = false; + std::string error_; - // Delayed utterances. // Calculates the milliseconds elapsed since the last call to Speak(). double CalculateUtteranceDelayMS(); + // Stores the milliseconds elapsed since the last call to Speak(). double delay_for_last_utterance_ms_; + // Stores the last time Speak() was called. std::chrono::steady_clock::time_point time_of_last_utterance_;
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_app_list_browsertest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_app_list_browsertest.cc index 055e0effa..37f144a 100644 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_app_list_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_app_list_browsertest.cc
@@ -8,15 +8,12 @@ #include "ash/app_list/test/test_search_result.h" #include "ash/app_list/views/app_list_view.h" #include "ash/shell.h" -#include "base/strings/pattern.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.h" -#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" #include "chrome/common/chrome_switches.h" #include "chrome/grit/generated_resources.h" #include "chromeos/constants/chromeos_switches.h" -#include "components/account_id/account_id.h" #include "components/user_manager/user_names.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" @@ -104,8 +101,8 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackAppListTest, LauncherStateTransition) { EnableChromeVox(); - EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); - + sm_.Call( + [this]() { EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); }); sm_.ExpectSpeechPattern("Launcher"); sm_.ExpectSpeech("Button"); sm_.ExpectSpeech("Shelf"); @@ -138,8 +135,8 @@ DisabledFullscreenExpandButton) { EnableChromeVox(); - EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); - + sm_.Call( + [this]() { EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); }); sm_.ExpectSpeech("Shelf"); // Press space on the launcher button in shelf, this opens peeking launcher. @@ -175,8 +172,8 @@ EnableChromeVox(); - EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); - + sm_.Call( + [this]() { EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); }); sm_.ExpectSpeech("Press Search plus Space to activate"); // Press space on the launcher button in shelf, this opens peeking // launcher. @@ -212,8 +209,8 @@ EnableChromeVox(); - EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); - + sm_.Call( + [this]() { EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); }); sm_.ExpectSpeech("Press Search plus Space to activate"); // Press space on the launcher button in shelf, this opens peeking // launcher. @@ -257,10 +254,12 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackAppListTest, NavigateAppLauncher) { EnableChromeVox(); - // Add one app to the applist. - PopulateApps(1); + sm_.Call([this]() { + // Add one app to the applist. + PopulateApps(1); - EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); + EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); + }); // Wait for it to say "Launcher", "Button", "Shelf", "Tool bar". sm_.ExpectSpeechPattern("Launcher");
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc index 201bab8..00ae998c 100644 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_browsertest.cc
@@ -17,38 +17,25 @@ #include "ash/system/status_area_widget.h" #include "ash/system/unified/unified_system_tray.h" #include "base/bind.h" -#include "base/bind_helpers.h" #include "base/command_line.h" #include "base/macros.h" -#include "base/strings/pattern.h" -#include "base/strings/string_util.h" #include "base/task/post_task.h" #include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/login/login_manager_test.h" -#include "chrome/browser/chromeos/login/test/js_checker.h" -#include "chrome/browser/chromeos/login/ui/login_display_host.h" -#include "chrome/browser/chromeos/login/ui/webui_login_view.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/test/base/interactive_test_utils.h" -#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/ui_test_utils.h" #include "chromeos/constants/chromeos_switches.h" -#include "components/account_id/account_id.h" #include "components/user_manager/user_names.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/tts_controller.h" -#include "content/public/common/url_constants.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" #include "extensions/browser/extension_host.h" @@ -161,36 +148,23 @@ void LoggedInSpokenFeedbackTest::EnableChromeVox() { // Test setup. - // Enable ChromeVox, skip welcome message/notification, and disable earcons. + // Enable ChromeVox, wait for something to be spoken, and disable earcons. ASSERT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled()); AccessibilityManager::Get()->EnableSpokenFeedback(true); - EXPECT_TRUE(sm_.SkipChromeVoxEnabledMessage()); - DisableEarcons(); -} - -void LoggedInSpokenFeedbackTest::PressRepeatedlyUntilUtterance( - ui::KeyboardCode key, - const std::string& expected_utterance) { - // This helper function is needed when you want to poll for something - // that happens asynchronously. Keep pressing |key|, until - // the speech feedback that follows is |expected_utterance|. - // Note that this doesn't work if pressing that key doesn't speak anything - // at all before the asynchronous event occurred. - while (true) { - SendKeyPress(key); - const std::string& utterance = sm_.GetNextUtterance(); - if (utterance == expected_utterance) - break; - } + sm_.ExpectSpeechPattern("*"); + sm_.Call([this]() { DisableEarcons(); }); } IN_PROC_BROWSER_TEST_F(LoggedInSpokenFeedbackTest, AddBookmark) { EnableChromeVox(); - chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR); + + sm_.Call( + [this]() { chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR); }); // Create a bookmark with title "foo". - chrome::ExecuteCommand(browser(), IDC_BOOKMARK_THIS_TAB); + sm_.Call( + [this]() { chrome::ExecuteCommand(browser(), IDC_BOOKMARK_THIS_TAB); }); sm_.ExpectSpeech("Bookmark name"); sm_.ExpectSpeech("about:blank"); @@ -241,7 +215,9 @@ IN_PROC_BROWSER_TEST_F(LoggedInSpokenFeedbackTest, NavigateNotificationCenter) { EnableChromeVox(); - EXPECT_TRUE(PerformAcceleratorAction(ash::TOGGLE_MESSAGE_CENTER_BUBBLE)); + sm_.Call([this]() { + EXPECT_TRUE(PerformAcceleratorAction(ash::TOGGLE_MESSAGE_CENTER_BUBBLE)); + }); sm_.ExpectSpeech( "Quick Settings, Press search plus left to access the notification " "center., window"); @@ -288,21 +264,25 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, EnableSpokenFeedback) { EnableChromeVox(); + sm_.Replay(); } IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, FocusToolbar) { EnableChromeVox(); - chrome::ExecuteCommand(browser(), IDC_FOCUS_TOOLBAR); - while (sm_.GetNextUtterance() != "Reload") { - } - EXPECT_EQ("Button", sm_.GetNextUtterance()); + sm_.Call([this]() { chrome::ExecuteCommand(browser(), IDC_FOCUS_TOOLBAR); }); + sm_.ExpectSpeech("Reload"); + sm_.ExpectSpeech("Button"); + + sm_.Replay(); } IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, TypeInOmnibox) { EnableChromeVox(); - ui_test_utils::NavigateToURL( - browser(), GURL("data:text/html;charset=utf-8,<p>unused</p>")); + sm_.Call([this]() { + ui_test_utils::NavigateToURL( + browser(), GURL("data:text/html;charset=utf-8,<p>unused</p>")); + }); sm_.Call([this]() { SendKeyPressWithControl(ui::VKEY_L); }); sm_.ExpectSpeech("Address and search bar"); @@ -334,22 +314,18 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, FocusShelf) { EnableChromeVox(); - EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); - while (true) { - std::string utterance = sm_.GetNextUtterance(); - if (base::MatchPattern(utterance, "Launcher")) - break; - } - EXPECT_EQ("Button", sm_.GetNextUtterance()); + sm_.Call( + [this]() { EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); }); + sm_.ExpectSpeechPattern("Launcher"); + sm_.ExpectSpeech("Button"); + sm_.ExpectSpeech("Shelf"); + sm_.ExpectSpeech("Tool bar"); + sm_.ExpectSpeech(", window"); + sm_.ExpectSpeech("Press Search plus Space to activate"); - EXPECT_EQ("Shelf", sm_.GetNextUtterance()); - EXPECT_EQ("Tool bar", sm_.GetNextUtterance()); - EXPECT_EQ(", window", sm_.GetNextUtterance()); - EXPECT_EQ("Press Search plus Space to activate", sm_.GetNextUtterance()); - - SendKeyPress(ui::VKEY_TAB); - EXPECT_TRUE(base::MatchPattern(sm_.GetNextUtterance(), "*")); - EXPECT_TRUE(base::MatchPattern(sm_.GetNextUtterance(), "Button")); + sm_.Call([this]() { SendKeyPress(ui::VKEY_TAB); }); + sm_.ExpectSpeechPattern("Button"); + sm_.Replay(); } // Verifies that pressing right arrow button with search button should move @@ -362,9 +338,11 @@ // when an extension is enabled, the ShelfItems which are not recorded as // pinned apps in user preference will be removed. EnableChromeVox(); - controller->CreateAppShortcutLauncherItem( - ash::ShelfID("FakeApp"), controller->shelf_model()->item_count(), - base::ASCIIToUTF16(title)); + sm_.Call([controller, title]() { + controller->CreateAppShortcutLauncherItem( + ash::ShelfID("FakeApp"), controller->shelf_model()->item_count(), + base::ASCIIToUTF16(title)); + }); // Focus on the shelf. sm_.Call([this]() { PerformAcceleratorAction(ash::FOCUS_SHELF); }); @@ -396,31 +374,35 @@ // pinned apps in user preference will be removed. EnableChromeVox(); - ui_test_utils::NavigateToURL( - browser(), - GURL("data:text/html;charset=utf-8,<button autofocus>Click me</button>")); + sm_.Call([this]() { + ui_test_utils::NavigateToURL(browser(), + GURL("data:text/html;charset=utf-8,<button " + "autofocus>Click me</button>")); + }); sm_.ExpectSpeech("Click me"); - // Add three Shelf buttons. Wait for the change on ShelfModel to reach ash. - ChromeLauncherController* controller = ChromeLauncherController::instance(); - const int base_index = controller->shelf_model()->item_count(); - const std::string title("MockApp"); - const std::string id("FakeApp"); - const int insert_app_num = 3; - for (int i = 0; i < insert_app_num; i++) { - std::string app_title = title + base::NumberToString(i); - std::string app_id = id + base::NumberToString(i); - controller->CreateAppShortcutLauncherItem( - ash::ShelfID(app_id), base_index + i, base::ASCIIToUTF16(app_title)); - } + sm_.Call([this]() { + // Add three Shelf buttons. Wait for the change on ShelfModel to reach ash. + ChromeLauncherController* controller = ChromeLauncherController::instance(); + const int base_index = controller->shelf_model()->item_count(); + const std::string title("MockApp"); + const std::string id("FakeApp"); + const int insert_app_num = 3; + for (int i = 0; i < insert_app_num; i++) { + std::string app_title = title + base::NumberToString(i); + std::string app_id = id + base::NumberToString(i); + controller->CreateAppShortcutLauncherItem( + ash::ShelfID(app_id), base_index + i, base::ASCIIToUTF16(app_title)); + } - // Enable the function of speaking text under mouse. - ash::EventRewriterController::Get()->SetSendMouseEventsToDelegate(true); + // Enable the function of speaking text under mouse. + ash::EventRewriterController::Get()->SetSendMouseEventsToDelegate(true); - // Focus on the Shelf because voice text for focusing on Shelf is fixed. Wait - // until voice announcements are finished. - EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); + // Focus on the Shelf because voice text for focusing on Shelf is fixed. + // Wait until voice announcements are finished. + EXPECT_TRUE(PerformAcceleratorAction(ash::FOCUS_SHELF)); + }); sm_.ExpectSpeechPattern("Launcher"); // Hover mouse on the Shelf button. Verifies that text under mouse is spoken. @@ -446,15 +428,13 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, OpenStatusTray) { EnableChromeVox(); - EXPECT_TRUE(PerformAcceleratorAction(ash::TOGGLE_SYSTEM_TRAY_BUBBLE)); - while (true) { - std::string utterance = sm_.GetNextUtterance(); - // TODO: this seems like a regression. - if (base::MatchPattern(utterance, - "Quick Settings, Press search plus left to access " - "the notification center., window")) - break; - } + sm_.Call([this]() { + EXPECT_TRUE(PerformAcceleratorAction(ash::TOGGLE_SYSTEM_TRAY_BUBBLE)); + }); + sm_.ExpectSpeech( + "Quick Settings, Press search plus left to access the notification " + "center., window"); + sm_.Replay(); } // Fails on ASAN. See http://crbug.com/776308 . (Note MAYBE_ doesn't work well @@ -511,9 +491,11 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, OverviewMode) { EnableChromeVox(); - ui_test_utils::NavigateToURL( - browser(), - GURL("data:text/html;charset=utf-8,<button autofocus>Click me</button>")); + sm_.Call([this]() { + ui_test_utils::NavigateToURL(browser(), + GURL("data:text/html;charset=utf-8,<button " + "autofocus>Click me</button>")); + }); sm_.ExpectSpeech("Click me"); @@ -533,14 +515,16 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, ChromeVoxFindInPage) { EnableChromeVox(); - ui_test_utils::NavigateToURL( - browser(), - GURL("data:text/html;charset=utf-8,<button autofocus>Click me</button>")); + sm_.Call([this]() { + ui_test_utils::NavigateToURL(browser(), + GURL("data:text/html;charset=utf-8,<button " + "autofocus>Click me</button>")); + }); sm_.ExpectSpeech("Click me"); // Press Search+/ to enter ChromeVox's "find in page". - SendKeyPressWithSearch(ui::VKEY_OEM_2); + sm_.Call([this]() { SendKeyPressWithSearch(ui::VKEY_OEM_2); }); sm_.ExpectSpeech("Find in page"); sm_.Replay(); } @@ -548,11 +532,12 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, ChromeVoxNavigateAndSelect) { EnableChromeVox(); - ui_test_utils::NavigateToURL(browser(), - GURL("data:text/html;charset=utf-8," - "<h1>Title</h1>" - "<button autofocus>Click me</button>")); - + sm_.Call([this]() { + ui_test_utils::NavigateToURL(browser(), + GURL("data:text/html;charset=utf-8," + "<h1>Title</h1>" + "<button autofocus>Click me</button>")); + }); sm_.ExpectSpeech("Click me"); // Press Search+Left to navigate to the previous item. @@ -575,10 +560,11 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, ChromeVoxStickyMode) { EnableChromeVox(); - ui_test_utils::NavigateToURL( - browser(), - GURL("data:text/html;charset=utf-8,<button autofocus>Click me</button>")); - + sm_.Call([this]() { + ui_test_utils::NavigateToURL(browser(), + GURL("data:text/html;charset=utf-8,<button " + "autofocus>Click me</button>")); + }); sm_.ExpectSpeech("Click me"); // Press the sticky-key sequence: Search Search. @@ -597,7 +583,7 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, TouchExploreStatusTray) { EnableChromeVox(); - SimulateTouchScreenInChromeVox(); + sm_.Call([this]() { SimulateTouchScreenInChromeVox(); }); // Send an accessibility hover event on the system tray, which is // what we get when you tap it on a touch screen when ChromeVox is on. @@ -617,108 +603,42 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, ChromeVoxNextTabRecovery) { EnableChromeVox(); - ui_test_utils::NavigateToURL( - browser(), GURL("data:text/html;charset=utf-8," - "<button id='b1' autofocus>11</button>" - "<button>22</button>" - "<button>33</button>" - "<h1>Middle</h1>" - "<button>44</button>" - "<button>55</button>" - "<div id=console aria-live=polite></div>" - "<script>" - "var b1 = document.getElementById('b1');" - "b1.addEventListener('blur', function() {" - " document.getElementById('console').innerText = " - "'button lost focus';" - "});" - "</script>")); - while ("Button" != sm_.GetNextUtterance()) { - } + sm_.Call([this]() { + ui_test_utils::NavigateToURL( + browser(), GURL("data:text/html;charset=utf-8," + "<button id='b1' autofocus>11</button>" + "<button>22</button>" + "<button>33</button>" + "<h1>Middle</h1>" + "<button>44</button>" + "<button>55</button>" + "<div id=console aria-live=polite></div>" + "<script>" + "var b1 = document.getElementById('b1');" + "b1.addEventListener('blur', function() {" + " document.getElementById('console').innerText = " + "'button lost focus';" + "});" + "</script>")); + }); + sm_.ExpectSpeech("Button"); // Press Search+H to go to the next heading - SendKeyPressWithSearch(ui::VKEY_H); + sm_.Call([this]() { SendKeyPressWithSearch(ui::VKEY_H); }); sm_.ExpectSpeech("Middle"); + // To ensure that the setSequentialFocusNavigationStartingPoint has // executed before pressing Tab, the page has an event handler waiting // for the 'blur' event on the button, and when it loses focus it // triggers a live region announcement that we wait for, here. sm_.ExpectSpeech("button lost focus"); + // Now we know that focus has left the button, so the sequential focus // navigation starting point must be on the heading. Press Tab and // ensure that we land on the first link past the heading. sm_.Call([this]() { SendKeyPress(ui::VKEY_TAB); }); sm_.ExpectSpeech("44"); - sm_.Replay(); -} - -// -// Spoken feedback tests that run only in guest mode. -// - -class GuestSpokenFeedbackTest : public LoggedInSpokenFeedbackTest { - protected: - GuestSpokenFeedbackTest() {} - ~GuestSpokenFeedbackTest() override {} - - void SetUpCommandLine(base::CommandLine* command_line) override { - command_line->AppendSwitch(chromeos::switches::kGuestSession); - command_line->AppendSwitch(::switches::kIncognito); - command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user"); - command_line->AppendSwitchASCII( - switches::kLoginUser, user_manager::GuestAccountId().GetUserEmail()); - } - - private: - DISALLOW_COPY_AND_ASSIGN(GuestSpokenFeedbackTest); -}; - -IN_PROC_BROWSER_TEST_F(GuestSpokenFeedbackTest, FocusToolbar) { - EnableChromeVox(); - chrome::ExecuteCommand(browser(), IDC_FOCUS_TOOLBAR); - sm_.ExpectSpeech("Reload"); - sm_.ExpectSpeech("Button"); - sm_.Replay(); -} - -// -// Spoken feedback tests of the out-of-box experience. -// - -class OobeSpokenFeedbackTest : public LoginManagerTest { - protected: - OobeSpokenFeedbackTest() - : LoginManagerTest(false, true /* should_initialize_webui */) {} - ~OobeSpokenFeedbackTest() override {} - - void SetUpCommandLine(base::CommandLine* command_line) override { - LoginManagerTest::SetUpCommandLine(command_line); - // Many bots don't have keyboard/mice which triggers the HID detection - // dialog in the OOBE. Avoid confusing the tests with that. - command_line->AppendSwitch(chromeos::switches::kDisableHIDDetectionOnOOBE); - } - - SpeechMonitor sm_; - - private: - DISALLOW_COPY_AND_ASSIGN(OobeSpokenFeedbackTest); -}; - -IN_PROC_BROWSER_TEST_F(OobeSpokenFeedbackTest, SpokenFeedbackInOobe) { - ui_controls::EnableUIControls(); - ASSERT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled()); - AccessibilityManager::Get()->EnableSpokenFeedback(true); - - // The Let's go button gets initial focus. - sm_.ExpectSpeech("Let's go"); - - sm_.Call([]() { - ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( - nullptr, ui::VKEY_TAB, false, false, false, false)); - }); - sm_.ExpectSpeech("Shut down"); - sm_.ExpectSpeech("Button"); sm_.Replay(); } @@ -726,9 +646,10 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, MoveByCharacterPhoneticSpeechAndHints) { EnableChromeVox(); - ui_test_utils::NavigateToURL( - browser(), GURL("data:text/html,<button autofocus>Click me</button>")); - sm_.ExpectSpeech("Web Content"); + sm_.Call([this]() { + ui_test_utils::NavigateToURL( + browser(), GURL("data:text/html,<button autofocus>Click me</button>")); + }); sm_.ExpectSpeech("Click me"); sm_.ExpectSpeech("Button"); sm_.ExpectSpeech("Press Search plus Space to activate"); @@ -788,8 +709,10 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, ResetTtsSettings) { EnableChromeVox(); - ui_test_utils::NavigateToURL( - browser(), GURL("data:text/html,<button autofocus>Click me</button>")); + sm_.Call([this]() { + ui_test_utils::NavigateToURL( + browser(), GURL("data:text/html,<button autofocus>Click me</button>")); + }); sm_.ExpectSpeech("Click me"); @@ -818,9 +741,11 @@ IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, SmartStickyMode) { EnableChromeVox(); - ui_test_utils::NavigateToURL(browser(), - GURL("data:text/html,<p>start</p><input " - "autofocus type='text'><p>end</p>")); + sm_.Call([this]() { + ui_test_utils::NavigateToURL(browser(), + GURL("data:text/html,<p>start</p><input " + "autofocus type='text'><p>end</p>")); + }); // The input is autofocused. sm_.ExpectSpeech("Edit text"); @@ -870,4 +795,45 @@ sm_.Replay(); } +// +// Spoken feedback tests of the out-of-box experience. +// + +class OobeSpokenFeedbackTest : public LoginManagerTest { + protected: + OobeSpokenFeedbackTest() + : LoginManagerTest(false, true /* should_initialize_webui */) {} + ~OobeSpokenFeedbackTest() override {} + + void SetUpCommandLine(base::CommandLine* command_line) override { + LoginManagerTest::SetUpCommandLine(command_line); + // Many bots don't have keyboard/mice which triggers the HID detection + // dialog in the OOBE. Avoid confusing the tests with that. + command_line->AppendSwitch(chromeos::switches::kDisableHIDDetectionOnOOBE); + } + + SpeechMonitor sm_; + + private: + DISALLOW_COPY_AND_ASSIGN(OobeSpokenFeedbackTest); +}; + +IN_PROC_BROWSER_TEST_F(OobeSpokenFeedbackTest, SpokenFeedbackInOobe) { + ui_controls::EnableUIControls(); + ASSERT_FALSE(AccessibilityManager::Get()->IsSpokenFeedbackEnabled()); + AccessibilityManager::Get()->EnableSpokenFeedback(true); + + // The Let's go button gets initial focus. + sm_.ExpectSpeech("Let's go"); + + sm_.Call([]() { + ASSERT_TRUE(ui_test_utils::SendKeyPressToWindowSync( + nullptr, ui::VKEY_TAB, false, false, false, false)); + }); + sm_.ExpectSpeech("Shut down"); + sm_.ExpectSpeech("Button"); + + sm_.Replay(); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc b/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc index b92ec21..7f73379b 100644 --- a/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc +++ b/chrome/browser/chromeos/login/configuration_based_oobe_browsertest.cc
@@ -80,18 +80,6 @@ fake_policy_dir_.GetPath()); } - void SetUpInProcessBrowserTestFixture() override { - OobeBaseTest::SetUpInProcessBrowserTestFixture(); - OobeConfiguration::set_skip_check_for_testing(true); - std::unique_ptr<chromeos::DBusThreadManagerSetter> dbus_setter = - chromeos::DBusThreadManager::GetSetterForTesting(); - - fake_update_engine_client_ = new chromeos::FakeUpdateEngineClient(); - - dbus_setter->SetUpdateEngineClient( - std::unique_ptr<chromeos::UpdateEngineClient>( - fake_update_engine_client_)); - } void SetUpCommandLine(base::CommandLine* command_line) override { // File name is based on the test name. @@ -136,8 +124,6 @@ } protected: - // Owned by DBusThreadManagerSetter - chromeos::FakeUpdateEngineClient* fake_update_engine_client_; std::unique_ptr<base::AutoReset<bool>> branded_build_override_; base::ScopedTempDir fake_policy_dir_; @@ -279,7 +265,7 @@ update_engine::StatusResult status; status.set_current_operation(update_engine::Operation::DOWNLOADING); status.set_progress(0.1); - fake_update_engine_client_->set_default_status(status); + update_engine_client()->set_default_status(status); LoadConfiguration(); OobeScreenWaiter(UpdateView::kScreenId).Wait();
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc b/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc index 513e273..0fd8cb34 100644 --- a/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc +++ b/chrome/browser/chromeos/login/enrollment/enrollment_local_policy_server_browsertest.cc
@@ -788,8 +788,12 @@ }; // TODO(https://crbug.com/995784): Slow on MSAN builds. -// TODO(https://crbug.com/1062248): Flakey on linux-chromeos-dbg -IN_PROC_BROWSER_TEST_F(EnrollmentRecoveryTest, DISABLED_Success) { +#if defined(MEMORY_SANITIZER) +#define MAYBE_Success DISABLED_Success +#else +#define MAYBE_Success Success +#endif +IN_PROC_BROWSER_TEST_F(EnrollmentRecoveryTest, MAYBE_Success) { test::SkipToEnrollmentOnRecovery(); ASSERT_TRUE(StartupUtils::IsDeviceRegistered()); @@ -815,8 +819,12 @@ } // TODO(https://crbug.com/995784): Slow on MSAN builds. -// TODO(https://crbug.com/1062248): Flakey on linux-chromeos-dbg -IN_PROC_BROWSER_TEST_F(EnrollmentRecoveryTest, DISABLED_DifferentDomain) { +#if defined(MEMORY_SANITIZER) +#define MAYBE_DifferentDomain DISABLED_DifferentDomain +#else +#define MAYBE_DifferentDomain DifferentDomain +#endif +IN_PROC_BROWSER_TEST_F(EnrollmentRecoveryTest, MAYBE_DifferentDomain) { test::SkipToEnrollmentOnRecovery(); ASSERT_TRUE(StartupUtils::IsDeviceRegistered());
diff --git a/chrome/browser/chromeos/login/login_ui_hide_supervised_users_browsertest.cc b/chrome/browser/chromeos/login/login_ui_hide_supervised_users_browsertest.cc index 1af1269..4587f20 100644 --- a/chrome/browser/chromeos/login/login_ui_hide_supervised_users_browsertest.cc +++ b/chrome/browser/chromeos/login/login_ui_hide_supervised_users_browsertest.cc
@@ -4,11 +4,11 @@ #include <vector> +#include "ash/public/cpp/login_screen_test_api.h" #include "base/stl_util.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/chromeos/login/login_manager_test.h" #include "chrome/browser/chromeos/login/startup_utils.h" -#include "chrome/browser/chromeos/login/test/js_checker.h" #include "components/account_id/account_id.h" #include "components/user_manager/user_manager_base.h" @@ -34,7 +34,8 @@ class LoginUIHideSupervisedUsersTest : public LoginManagerTest { public: LoginUIHideSupervisedUsersTest() - : LoginManagerTest(false, true /* should_initialize_webui */) { + : LoginManagerTest(false, false /* should_initialize_webui */) { + set_force_webui_login(false); for (size_t i = 0; i < base::size(kTestUsers); ++i) { test_users_.emplace_back(AccountId::FromUserEmailGaiaId( kTestUsers[i].email, kTestUsers[i].gaia_id)); @@ -53,6 +54,7 @@ void SetUpInProcessBrowserTestFixture() override { scoped_feature_list_.InitAndEnableFeature( user_manager::kHideSupervisedUsers); + LoginUIHideSupervisedUsersTest::SetUpInProcessBrowserTestFixture(); } private: @@ -67,6 +69,7 @@ void SetUpInProcessBrowserTestFixture() override { scoped_feature_list_.InitAndDisableFeature( user_manager::kHideSupervisedUsers); + LoginUIHideSupervisedUsersTest::SetUpInProcessBrowserTestFixture(); } private: @@ -86,16 +89,9 @@ IN_PROC_BROWSER_TEST_F(LoginUIHideSupervisedUsersEnabledTest, SupervisedUserHidden) { // Only the regular users should be displayed on the login screen. - test::OobeJS().ExpectEQ( - "document.querySelectorAll('.pod:not(#user-pod-template)').length", 2); - test::OobeJS().ExpectEQ( - std::string("document.querySelectorAll('.pod:not(#user-pod-template)')[0]" - ".user.emailAddress"), - std::string(test_users_[0].GetUserEmail())); - test::OobeJS().ExpectEQ( - std::string("document.querySelectorAll('.pod:not(#user-pod-template)')[1]" - ".user.emailAddress"), - std::string(test_users_[1].GetUserEmail())); + EXPECT_EQ(2, ash::LoginScreenTestApi::GetUsersCount()); + EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(test_users_[0])); + EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(test_users_[1])); } IN_PROC_BROWSER_TEST_F(LoginUIHideSupervisedUsersDisabledTest, @@ -110,23 +106,10 @@ // HideSupervisedUsers feature flag is *not* enabled. IN_PROC_BROWSER_TEST_F(LoginUIHideSupervisedUsersDisabledTest, SupervisedUserDisplayed) { - test::OobeJS().ExpectEQ( - "document.querySelectorAll('.pod:not(#user-pod-template)').length", 3); - test::OobeJS().ExpectEQ( - std::string("document.querySelectorAll('.pod:not(#user-pod-template)')[0]" - ".user.emailAddress"), - std::string(test_users_[0].GetUserEmail())); - test::OobeJS().ExpectEQ( - std::string("document.querySelectorAll('.pod:not(#user-pod-template)')[1]" - ".user.emailAddress"), - std::string(test_users_[1].GetUserEmail())); - - // Emails are not displayed for Supervised users, but there is an - // empty DOM element for the email address. - test::OobeJS().ExpectEQ( - std::string("document.querySelectorAll('.pod:not(#user-pod-template)')[2]" - ".user.emailAddress"), - std::string()); + EXPECT_EQ(3, ash::LoginScreenTestApi::GetUsersCount()); + EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(test_users_[0])); + EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(test_users_[1])); + EXPECT_TRUE(ash::LoginScreenTestApi::FocusUser(test_users_[2])); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/reset_browsertest.cc b/chrome/browser/chromeos/login/reset_browsertest.cc index 1092b31..526fa7e 100644 --- a/chrome/browser/chromeos/login/reset_browsertest.cc +++ b/chrome/browser/chromeos/login/reset_browsertest.cc
@@ -197,16 +197,6 @@ OobeBaseTest::SetUpCommandLine(command_line); } - void SetUpInProcessBrowserTestFixture() override { - std::unique_ptr<DBusThreadManagerSetter> dbus_setter = - chromeos::DBusThreadManager::GetSetterForTesting(); - update_engine_client_ = new FakeUpdateEngineClient; - dbus_setter->SetUpdateEngineClient( - std::unique_ptr<UpdateEngineClient>(update_engine_client_)); - - OobeBaseTest::SetUpInProcessBrowserTestFixture(); - } - // Simulates reset screen request from OOBE UI. void InvokeResetScreen() { test::ExecuteOobeJS("cr.ui.Oobe.handleAccelerator('reset');"); @@ -215,8 +205,6 @@ ExpectConfirmationDialogClosed(); } - FakeUpdateEngineClient* update_engine_client_ = nullptr; - private: DISALLOW_COPY_AND_ASSIGN(ResetOobeTest); }; @@ -334,7 +322,7 @@ ClickResetButton(); EXPECT_EQ(0, FakePowerManagerClient::Get()->num_request_restart_calls()); EXPECT_EQ(1, FakeSessionManagerClient::Get()->start_device_wipe_call_count()); - EXPECT_EQ(0, update_engine_client_->rollback_call_count()); + EXPECT_EQ(0, update_engine_client()->rollback_call_count()); } IN_PROC_BROWSER_TEST_F(ResetOobeTest, RequestAndCancleResetOnWelcomeScreen) { @@ -349,7 +337,7 @@ EXPECT_EQ(0, FakePowerManagerClient::Get()->num_request_restart_calls()); EXPECT_EQ(0, FakeSessionManagerClient::Get()->start_device_wipe_call_count()); - EXPECT_EQ(0, update_engine_client_->rollback_call_count()); + EXPECT_EQ(0, update_engine_client()->rollback_call_count()); } // TODO(http://crbug.com/990362): Times out on MSAN buildbots.
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.cc b/chrome/browser/chromeos/login/test/oobe_base_test.cc index 55dd83b..371eef82 100644 --- a/chrome/browser/chromeos/login/test/oobe_base_test.cc +++ b/chrome/browser/chromeos/login/test/oobe_base_test.cc
@@ -24,6 +24,8 @@ #include "chrome/browser/ui/webui/signin/signin_utils.h" #include "chrome/common/chrome_switches.h" #include "chromeos/constants/chromeos_switches.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_update_engine_client.h" #include "chromeos/dbus/shill/fake_shill_manager_client.h" #include "components/policy/core/common/policy_switches.h" #include "components/user_manager/fake_user_manager.h" @@ -71,7 +73,23 @@ MixinBasedInProcessBrowserTest::CreatedBrowserMainParts(browser_main_parts); } +void OobeBaseTest::SetUpInProcessBrowserTestFixture() { + MixinBasedInProcessBrowserTest::SetUpInProcessBrowserTestFixture(); + + // UpdateEngineClientStubImpl have logic that simulates state changes + // based on timer. It is nice simulation for chromeos-on-linux, but + // may lead to flakiness in debug/*SAN tests. + // Set up FakeUpdateEngineClient that does not have any timer-based logic. + std::unique_ptr<DBusThreadManagerSetter> dbus_setter = + chromeos::DBusThreadManager::GetSetterForTesting(); + update_engine_client_ = new FakeUpdateEngineClient; + dbus_setter->SetUpdateEngineClient( + std::unique_ptr<UpdateEngineClient>(update_engine_client_)); +} + void OobeBaseTest::SetUpOnMainThread() { + ShillManagerClient::Get()->GetTestInterface()->SetupDefaultEnvironment(); + host_resolver()->AddRule("*", "127.0.0.1"); test::UserSessionManagerTestApi session_manager_test_api(
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.h b/chrome/browser/chromeos/login/test/oobe_base_test.h index 9dff976..155bba1 100644 --- a/chrome/browser/chromeos/login/test/oobe_base_test.h +++ b/chrome/browser/chromeos/login/test/oobe_base_test.h
@@ -20,6 +20,8 @@ namespace chromeos { +class FakeUpdateEngineClient; + // Base class for OOBE, login, SAML and Kiosk tests. class OobeBaseTest : public MixinBasedInProcessBrowserTest { public: @@ -34,6 +36,7 @@ // MixinBasedInProcessBrowserTest:: void SetUp() override; void SetUpCommandLine(base::CommandLine* command_line) override; + void SetUpInProcessBrowserTestFixture() override; void CreatedBrowserMainParts( content::BrowserMainParts* browser_main_parts) override; void SetUpOnMainThread() override; @@ -45,6 +48,10 @@ // Returns chrome://oobe WebUI. content::WebUI* GetLoginUI(); + FakeUpdateEngineClient* update_engine_client() { + return update_engine_client_; + } + void WaitForOobeUI(); void WaitForGaiaPageLoad(); void WaitForGaiaPageLoadAndPropertyUpdate(); @@ -67,6 +74,8 @@ // Waits for login_screen_load_observer_ and resets it afterwards. void MaybeWaitForLoginScreenLoad(); + FakeUpdateEngineClient* update_engine_client_ = nullptr; + std::unique_ptr<content::WindowedNotificationObserver> login_screen_load_observer_;
diff --git a/chrome/browser/chromeos/login/test/oobe_screens_utils.cc b/chrome/browser/chromeos/login/test/oobe_screens_utils.cc index 11b24c1..cb966ca 100644 --- a/chrome/browser/chromeos/login/test/oobe_screens_utils.cc +++ b/chrome/browser/chromeos/login/test/oobe_screens_utils.cc
@@ -55,6 +55,10 @@ } void TapNetworkSelectionNext() { + test::OobeJS() + .CreateEnabledWaiter(true /* enabled */, + {"oobe-network-md", "nextButton"}) + ->Wait(); test::OobeJS().TapOnPath({"oobe-network-md", "nextButton"}); }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 08c2447..110874a 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1242,6 +1242,11 @@ "expiry_milestone": 90 }, { + "name": "enable-cros-ime-emoji-suggest-addition", + "owners": [ "myy", "essential-inputs-team@google.com" ], + "expiry_milestone": 90 + }, + { "name": "enable-cros-ime-input-logic-fst", "owners": [ "essential-inputs-team@google.com" ], "expiry_milestone": 85
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 73ff791..a30f412 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3471,6 +3471,11 @@ const char kImeAssistPersonalInfoDescription[] = "Enable auto-complete suggestions on personal infomation for native IME."; +const char kImeEmojiSuggestAdditionName[] = + "Enable emoji suggestion (addition)"; +const char kImeEmojiSuggestAdditionDescription[] = + "Enable emoji suggestion as addition to the text written for native IME."; + const char kImeInputLogicFstName[] = "Enable FST Input Logic on IME"; const char kImeInputLogicFstDescription[] = "Enable FST Input Logic to replace the IME legacy input logic on NaCl";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 22af89b..f5202b3f 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2016,6 +2016,9 @@ extern const char kImeAssistPersonalInfoName[]; extern const char kImeAssistPersonalInfoDescription[]; +extern const char kImeEmojiSuggestAdditionName[]; +extern const char kImeEmojiSuggestAdditionDescription[]; + extern const char kImeInputLogicFstName[]; extern const char kImeInputLogicFstDescription[];
diff --git a/chrome/browser/media/router/media_router_metrics.cc b/chrome/browser/media/router/media_router_metrics.cc index 18649cd2..275b66d9 100644 --- a/chrome/browser/media/router/media_router_metrics.cc +++ b/chrome/browser/media/router/media_router_metrics.cc
@@ -131,6 +131,10 @@ // static const char MediaRouterMetrics::kHistogramCloseLatency[] = "MediaRouter.Ui.Action.CloseLatency"; +const char MediaRouterMetrics::kHistogramCloudPrefAtDialogOpen[] = + "MediaRouter.Cloud.PrefAtDialogOpen"; +const char MediaRouterMetrics::kHistogramCloudPrefAtInit[] = + "MediaRouter.Cloud.PrefAtInit"; const char MediaRouterMetrics::kHistogramDialParsingError[] = "MediaRouter.Dial.ParsingError"; const char MediaRouterMetrics::kHistogramDialFetchAppInfo[] = @@ -314,6 +318,16 @@ } // static +void MediaRouterMetrics::RecordCloudPrefAtDialogOpen(bool enabled) { + base::UmaHistogramBoolean(kHistogramCloudPrefAtDialogOpen, enabled); +} + +// static +void MediaRouterMetrics::RecordCloudPrefAtInit(bool enabled) { + base::UmaHistogramBoolean(kHistogramCloudPrefAtInit, enabled); +} + +// static void MediaRouterMetrics::RecordDialogActivationLocationAndCastMode( MediaRouterDialogOpenOrigin activation_location, MediaCastMode cast_mode,
diff --git a/chrome/browser/media/router/media_router_metrics.h b/chrome/browser/media/router/media_router_metrics.h index 9d7b3607..50a3e15a 100644 --- a/chrome/browser/media/router/media_router_metrics.h +++ b/chrome/browser/media/router/media_router_metrics.h
@@ -128,6 +128,8 @@ // UMA histogram names. static const char kHistogramCloseLatency[]; + static const char kHistogramCloudPrefAtDialogOpen[]; + static const char kHistogramCloudPrefAtInit[]; static const char kHistogramDialParsingError[]; static const char kHistogramDialFetchAppInfo[]; static const char kHistogramIconClickLocation[]; @@ -224,6 +226,14 @@ // Recorded whenever the browser is initialized. static void RecordIconStateAtInit(bool is_pinned); + // Records the pref value to enable the cloud services. Recorded whenever the + // Cast dialog is opened. + static void RecordCloudPrefAtDialogOpen(bool enabled); + + // Records the pref value to enable the cloud services. Recorded whenever the + // browser is initialized. + static void RecordCloudPrefAtInit(bool enabled); + // Recorded whenever a Cast session is started from the Cast dialog. Records // how the dialog was opened, and the Cast mode of the started session. static void RecordDialogActivationLocationAndCastMode(
diff --git a/chrome/browser/media/router/media_router_metrics_unittest.cc b/chrome/browser/media/router/media_router_metrics_unittest.cc index 9ed8b957..d8560bf 100644 --- a/chrome/browser/media/router/media_router_metrics_unittest.cc +++ b/chrome/browser/media/router/media_router_metrics_unittest.cc
@@ -285,4 +285,16 @@ MediaRouterMetrics::kHistogramUiIconStateAtInit); } +TEST(MediaRouterMetricsTest, RecordCloudPrefAtDialogOpen) { + TestRecordBooleanMetric( + base::BindRepeating(&MediaRouterMetrics::RecordCloudPrefAtDialogOpen), + MediaRouterMetrics::kHistogramCloudPrefAtDialogOpen); +} + +TEST(MediaRouterMetricsTest, RecordCloudPrefAtInit) { + TestRecordBooleanMetric( + base::BindRepeating(&MediaRouterMetrics::RecordCloudPrefAtInit), + MediaRouterMetrics::kHistogramCloudPrefAtInit); +} + } // namespace media_router
diff --git a/chrome/browser/prerender/isolated/isolated_prerender_tab_helper.cc b/chrome/browser/prerender/isolated/isolated_prerender_tab_helper.cc index b924409..6fa5b90 100644 --- a/chrome/browser/prerender/isolated/isolated_prerender_tab_helper.cc +++ b/chrome/browser/prerender/isolated/isolated_prerender_tab_helper.cc
@@ -8,6 +8,11 @@ #include "base/bind.h" #include "base/feature_list.h" +#include "base/metrics/histogram.h" +#include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" +#include "base/optional.h" +#include "base/time/time.h" #include "chrome/browser/navigation_predictor/navigation_predictor_keyed_service_factory.h" #include "chrome/browser/net/prediction_options.h" #include "chrome/browser/prerender/isolated/isolated_prerender_features.h" @@ -41,6 +46,36 @@ #include "services/network/public/mojom/network_service.mojom.h" #include "url/origin.h" +namespace { + +base::Optional<base::TimeDelta> GetTotalPrefetchTime( + network::mojom::URLResponseHead* head) { + DCHECK(head); + + base::Time start = head->request_time; + base::Time end = head->response_time; + + if (start.is_null() || end.is_null()) + return base::nullopt; + + return end - start; +} + +base::Optional<base::TimeDelta> GetPrefetchConnectTime( + network::mojom::URLResponseHead* head) { + DCHECK(head); + + base::TimeTicks start = head->load_timing.connect_timing.connect_start; + base::TimeTicks end = head->load_timing.connect_timing.connect_end; + + if (start.is_null() || end.is_null()) + return base::nullopt; + + return end - start; +} + +} // namespace + IsolatedPrerenderTabHelper::CurrentPageLoad::CurrentPageLoad() = default; IsolatedPrerenderTabHelper::CurrentPageLoad::~CurrentPageLoad() = default; @@ -238,6 +273,9 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(PrefetchingActive()); + base::UmaHistogramSparse("IsolatedPrerender.Prefetch.Mainframe.NetError", + std::abs(page_->url_loader->NetError())); + if (page_->url_loader->NetError() == net::OK && body && page_->url_loader->ResponseInfo()) { network::mojom::URLResponseHeadPtr head = @@ -262,7 +300,32 @@ std::unique_ptr<std::string> body) { DCHECK(!head->was_fetched_via_cache); + if (!head->headers) + return; + + UMA_HISTOGRAM_COUNTS_10M("IsolatedPrerender.Prefetch.Mainframe.BodyLength", + body->size()); + + base::Optional<base::TimeDelta> total_time = GetTotalPrefetchTime(head.get()); + if (total_time) { + UMA_HISTOGRAM_CUSTOM_TIMES("IsolatedPrerender.Prefetch.Mainframe.TotalTime", + *total_time, + base::TimeDelta::FromMilliseconds(10), + base::TimeDelta::FromSeconds(30), 100); + } + + base::Optional<base::TimeDelta> connect_time = + GetPrefetchConnectTime(head.get()); + if (connect_time) { + UMA_HISTOGRAM_TIMES("IsolatedPrerender.Prefetch.Mainframe.ConnectTime", + *connect_time); + } + int response_code = head->headers->response_code(); + + base::UmaHistogramSparse("IsolatedPrerender.Prefetch.Mainframe.RespCode", + response_code); + if (response_code < 200 || response_code >= 300) { return; }
diff --git a/chrome/browser/prerender/isolated/isolated_prerender_tab_helper_unittest.cc b/chrome/browser/prerender/isolated/isolated_prerender_tab_helper_unittest.cc index 13be092..f2dcf83 100644 --- a/chrome/browser/prerender/isolated/isolated_prerender_tab_helper_unittest.cc +++ b/chrome/browser/prerender/isolated/isolated_prerender_tab_helper_unittest.cc
@@ -49,6 +49,11 @@ #include "url/origin.h" namespace { + +const int kTotalTimeDuration = 1337; + +const int kConnectTimeDuration = 123; + const char kHTMLMimeType[] = "text/html"; const char kHTMLBody[] = R"( @@ -57,6 +62,7 @@ <head></head> <body></body> </html>)"; + } // namespace class TestIsolatedPrerenderTabHelper : public IsolatedPrerenderTabHelper { @@ -178,6 +184,17 @@ ASSERT_TRUE(request); auto head = network::CreateURLResponseHead(http_status); + + head->response_time = base::Time::Now(); + head->request_time = head->response_time - + base::TimeDelta::FromMilliseconds(kTotalTimeDuration); + + head->load_timing.connect_timing.connect_end = + base::TimeTicks::Now() - base::TimeDelta::FromMinutes(2); + head->load_timing.connect_timing.connect_start = + head->load_timing.connect_timing.connect_end - + base::TimeDelta::FromMilliseconds(kConnectTimeDuration); + head->mime_type = mime_type; for (const std::string& header : headers) { head->headers->AddHeader(header); @@ -349,6 +366,7 @@ } TEST_F(IsolatedPrerenderTabHelperTest, 2XXOnly) { + base::HistogramTester histogram_tester; base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders); @@ -360,9 +378,23 @@ MakeResponseAndWait(net::HTTP_NOT_FOUND, net::OK, kHTMLMimeType, /*headers=*/{}, kHTMLBody); EXPECT_EQ(PrefetchedResponseSize(), 0U); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.NetError", net::OK, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.RespCode", net::HTTP_NOT_FOUND, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), + 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.ConnectTime", kConnectTimeDuration, + 1); } TEST_F(IsolatedPrerenderTabHelperTest, NetErrorOKOnly) { + base::HistogramTester histogram_tester; base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders); @@ -374,9 +406,22 @@ MakeResponseAndWait(net::HTTP_OK, net::ERR_FAILED, kHTMLMimeType, /*headers=*/{}, kHTMLBody); EXPECT_EQ(PrefetchedResponseSize(), 0U); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.NetError", + std::abs(net::ERR_FAILED), 1); + histogram_tester.ExpectTotalCount( + "IsolatedPrerender.Prefetch.Mainframe.RespCode", 0); + histogram_tester.ExpectTotalCount( + "IsolatedPrerender.Prefetch.Mainframe.BodyLength", 0); + histogram_tester.ExpectTotalCount( + "IsolatedPrerender.Prefetch.Mainframe.TotalTime", 0); + histogram_tester.ExpectTotalCount( + "IsolatedPrerender.Prefetch.Mainframe.ConnectTime", 0); } TEST_F(IsolatedPrerenderTabHelperTest, NonHTML) { + base::HistogramTester histogram_tester; base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders); @@ -384,11 +429,23 @@ GURL prediction_url("https://www.cat-food.com/"); MakeNavigationPrediction(web_contents(), doc_url, {prediction_url}); + std::string body = "console.log('Hello world');"; VerifyCommonRequestState(prediction_url); MakeResponseAndWait(net::HTTP_OK, net::OK, "application/javascript", - /*headers=*/{}, - /*body=*/"console.log('Hello world');"); + /*headers=*/{}, body); EXPECT_EQ(PrefetchedResponseSize(), 0U); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.NetError", net::OK, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.BodyLength", body.size(), 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.ConnectTime", kConnectTimeDuration, + 1); } TEST_F(IsolatedPrerenderTabHelperTest, UserSettingDisabled) { @@ -408,6 +465,7 @@ } TEST_F(IsolatedPrerenderTabHelperTest, SuccessCase) { + base::HistogramTester histogram_tester; base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders); @@ -432,6 +490,19 @@ EXPECT_EQ(resp->network_isolation_key(), request.trusted_params.value().network_isolation_key); VerifyNIK(resp->network_isolation_key()); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.NetError", net::OK, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), + 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.ConnectTime", kConnectTimeDuration, + 1); } TEST_F(IsolatedPrerenderTabHelperTest, LimitedNumberOfPrefetches_Zero) { @@ -449,6 +520,7 @@ TEST_F(IsolatedPrerenderTabHelperTest, NumberOfPrefetches_UnlimitedByExperiment) { + base::HistogramTester histogram_tester; base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeatureWithParameters( features::kIsolatePrerenders, {{"max_srp_prefetches", "-1"}}); @@ -471,9 +543,31 @@ MakeResponseAndWait(net::HTTP_OK, net::OK, kHTMLMimeType, {}, kHTMLBody); EXPECT_EQ(RequestCount(), 0); + + histogram_tester.ExpectBucketCount( + "IsolatedPrerender.Prefetch.Mainframe.NetError", net::OK, 2); + histogram_tester.ExpectBucketCount( + "IsolatedPrerender.Prefetch.Mainframe.NetError", + std::abs(net::ERR_FAILED), 1); + histogram_tester.ExpectTotalCount( + "IsolatedPrerender.Prefetch.Mainframe.NetError", 3); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.RespCode", net::HTTP_OK, 2); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), + 2); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 2); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.ConnectTime", kConnectTimeDuration, + 2); } TEST_F(IsolatedPrerenderTabHelperTest, NumberOfPrefetches_UnlimitedByCmdLine) { + base::HistogramTester histogram_tester; base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders); @@ -498,9 +592,31 @@ MakeResponseAndWait(net::HTTP_OK, net::OK, kHTMLMimeType, {}, kHTMLBody); EXPECT_EQ(RequestCount(), 0); + + histogram_tester.ExpectBucketCount( + "IsolatedPrerender.Prefetch.Mainframe.NetError", net::OK, 2); + histogram_tester.ExpectBucketCount( + "IsolatedPrerender.Prefetch.Mainframe.NetError", + std::abs(net::ERR_FAILED), 1); + histogram_tester.ExpectTotalCount( + "IsolatedPrerender.Prefetch.Mainframe.NetError", 3); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.RespCode", net::HTTP_OK, 2); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), + 2); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 2); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.ConnectTime", kConnectTimeDuration, + 2); } TEST_F(IsolatedPrerenderTabHelperTest, LimitedNumberOfPrefetches) { + base::HistogramTester histogram_tester; base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeatureWithParameters( features::kIsolatePrerenders, {{"max_srp_prefetches", "2"}}); @@ -521,6 +637,27 @@ MakeResponseAndWait(net::HTTP_OK, net::OK, kHTMLMimeType, {}, kHTMLBody); EXPECT_EQ(RequestCount(), 0); + + histogram_tester.ExpectBucketCount( + "IsolatedPrerender.Prefetch.Mainframe.NetError", net::OK, 1); + histogram_tester.ExpectBucketCount( + "IsolatedPrerender.Prefetch.Mainframe.NetError", + std::abs(net::ERR_FAILED), 1); + histogram_tester.ExpectTotalCount( + "IsolatedPrerender.Prefetch.Mainframe.NetError", 2); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), + 1); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.ConnectTime", kConnectTimeDuration, + 1); } TEST_F(IsolatedPrerenderTabHelperTest, PrefetchingNotStartedWhileInvisible) { @@ -538,6 +675,7 @@ } TEST_F(IsolatedPrerenderTabHelperTest, PrefetchingPausedWhenInvisible) { + base::HistogramTester histogram_tester; base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders); @@ -556,6 +694,19 @@ // But no more prefetches should start when hidden. EXPECT_EQ(RequestCount(), 0); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.NetError", net::OK, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), + 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.ConnectTime", kConnectTimeDuration, + 1); } TEST_F(IsolatedPrerenderTabHelperTest, PrefetchingRestartedWhenVisible) { @@ -657,7 +808,20 @@ std::vector<std::string> final_headers, const std::string& final_body) { auto final_head = network::CreateURLResponseHead(final_status); + + final_head->response_time = base::Time::Now(); + final_head->request_time = + final_head->response_time - + base::TimeDelta::FromMilliseconds(kTotalTimeDuration); + + final_head->load_timing.connect_timing.connect_end = + base::TimeTicks::Now() - base::TimeDelta::FromMinutes(2); + final_head->load_timing.connect_timing.connect_start = + final_head->load_timing.connect_timing.connect_end - + base::TimeDelta::FromMilliseconds(kConnectTimeDuration); + final_head->mime_type = kHTMLMimeType; + for (const std::string& header : final_headers) { final_head->headers->AddHeader(header); } @@ -719,6 +883,7 @@ } TEST_F(IsolatedPrerenderTabHelperRedirectTest, SuccessfulRedirect) { + base::HistogramTester histogram_tester; GURL doc_url("https://www.google.com/search?q=cats"); GURL prediction_url("https://www.cat-food.com/"); GURL redirect_url("https://redirect-here.com"); @@ -742,4 +907,17 @@ network::mojom::URLResponseHeadPtr head = resp->TakeHead(); EXPECT_TRUE(head->headers->HasHeaderValue("X-Testing", "Hello World")); + + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.NetError", net::OK, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), + 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1); + histogram_tester.ExpectUniqueSample( + "IsolatedPrerender.Prefetch.Mainframe.ConnectTime", kConnectTimeDuration, + 1); }
diff --git a/chrome/browser/resources/management/management_ui.html b/chrome/browser/resources/management/management_ui.html index 649a89a..57fdf8e7 100644 --- a/chrome/browser/resources/management/management_ui.html +++ b/chrome/browser/resources/management/management_ui.html
@@ -83,13 +83,12 @@ } section { - @apply --cr-section; align-items: flex-start; - border-top: none; + display: flex; flex-direction: column; justify-content: center; - padding-bottom: 12px; - padding-top: 12px; + min-height: var(--cr-section-min-height); + padding: 12px var(--cr-section-padding); } section:not(.page-subtitle) h2 {
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn index 8de3c7a..e05a258 100644 --- a/chrome/browser/resources/settings/BUILD.gn +++ b/chrome/browser/resources/settings/BUILD.gn
@@ -248,6 +248,7 @@ "printing_page:closure_compile_module", "privacy_page:closure_compile_module", "reset_page:closure_compile_module", + "safety_check_page:closure_compile_module", "search_engines_page:closure_compile_module", "search_page:closure_compile_module", "settings_main:closure_compile_module", @@ -425,6 +426,7 @@ "printing_page:polymer3_elements", "privacy_page:polymer3_elements", "reset_page:polymer3_elements", + "safety_check_page:polymer3_elements", "search_engines_page:polymer3_elements", "search_page:polymer3_elements", "settings_main:polymer3_elements",
diff --git a/chrome/browser/resources/settings/autofill_page/BUILD.gn b/chrome/browser/resources/settings/autofill_page/BUILD.gn index 214d460..9a5034e1 100644 --- a/chrome/browser/resources/settings/autofill_page/BUILD.gn +++ b/chrome/browser/resources/settings/autofill_page/BUILD.gn
@@ -358,6 +358,7 @@ js_library("password_manager_proxy.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/autofill_page/password_manager_proxy.m.js" ] deps = [ "//ui/webui/resources/js:cr.m" ] + externs_list = [ "$externs_path/passwords_private.js" ] extra_deps = [ ":modulize" ] }
diff --git a/chrome/browser/resources/settings/basic_page/BUILD.gn b/chrome/browser/resources/settings/basic_page/BUILD.gn index dc2d39f4..7d71448 100644 --- a/chrome/browser/resources/settings/basic_page/BUILD.gn +++ b/chrome/browser/resources/settings/basic_page/BUILD.gn
@@ -52,7 +52,6 @@ js_file = "basic_page.js" html_file = "basic_page.html" html_type = "dom-module" - ignore_imports = [ "chrome/browser/resources/settings/safety_check_page/safety_check_page.html" ] auto_imports = settings_auto_imports + [ "chrome/browser/resources/settings/page_visibility.html|PageVisibility", "chrome/browser/resources/settings/route.html|routes",
diff --git a/chrome/browser/resources/settings/safety_check_page/BUILD.gn b/chrome/browser/resources/settings/safety_check_page/BUILD.gn index 586591b..83cad05 100644 --- a/chrome/browser/resources/settings/safety_check_page/BUILD.gn +++ b/chrome/browser/resources/settings/safety_check_page/BUILD.gn
@@ -3,13 +3,14 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("//tools/polymer/polymer.gni") +import("//ui/webui/resources/tools/js_modulizer.gni") +import("../settings.gni") js_type_check("closure_compile") { deps = [ ":safety_check_browser_proxy", ":safety_check_page", - "..:lifetime_browser_proxy", - "../autofill_page:password_manager_proxy", ] } @@ -33,3 +34,65 @@ js_library("safety_check_browser_proxy") { deps = [ "//ui/webui/resources/js:cr" ] } + +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ + ":safety_check_browser_proxy.m", + ":safety_check_page.m", + ] +} + +js_library("safety_check_browser_proxy.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/safety_check_page/safety_check_browser_proxy.m.js" ] + deps = [ "//ui/webui/resources/js:cr.m" ] + extra_deps = [ ":modulize" ] +} + +js_library("safety_check_page.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/safety_check_page/safety_check_page.m.js" ] + deps = [ + ":safety_check_browser_proxy.m", + "..:hats_browser_proxy.m", + "..:lifetime_browser_proxy.m", + "..:open_window_proxy.m", + "..:route.m", + "..:router.m", + "../autofill_page:password_manager_proxy.m", + "//third_party/polymer/v3_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:i18n_behavior.m", + "//ui/webui/resources/js:web_ui_listener_behavior.m", + ] + extra_deps = [ ":safety_check_page_module" ] +} + +group("polymer3_elements") { + public_deps = [ + ":modulize", + ":safety_check_page_module", + ] +} + +polymer_modulizer("safety_check_page") { + js_file = "safety_check_page.js" + html_file = "safety_check_page.html" + html_type = "dom-module" + auto_imports = settings_auto_imports + [ + "chrome/browser/resources/settings/route.html|routes", + "chrome/browser/resources/settings/router.html|Router", + "chrome/browser/resources/settings/autofill_page/password_manager_proxy.html|PasswordManagerImpl,PasswordManagerProxy", + "chrome/browser/resources/settings/lifetime_browser_proxy.html|LifetimeBrowserProxy,LifetimeBrowserProxyImpl", + "chrome/browser/resources/settings/hats_browser_proxy.html|HatsBrowserProxyImpl", + "chrome/browser/resources/settings/open_window_proxy.html|OpenWindowProxyImpl", + "chrome/browser/resources/settings/safety_check_page/safety_check_browser_proxy.html|SafetyCheckBrowserProxy,SafetyCheckBrowserProxyImpl,SafetyCheckExtensionsStatus,SafetyCheckPasswordsStatus,SafetyCheckUpdatesStatus,SafetyCheckSafeBrowsingStatus,SafetyCheckCallbackConstants", + "ui/webui/resources/html/assert.html|assertNotReached", + ] + namespace_rewrites = settings_namespace_rewrites +} + +js_modulizer("modulize") { + input_files = [ "safety_check_browser_proxy.js" ] + namespace_rewrites = settings_namespace_rewrites +}
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_browser_proxy.js b/chrome/browser/resources/settings/safety_check_page/safety_check_browser_proxy.js index f33a744..f24fdb2 100644 --- a/chrome/browser/resources/settings/safety_check_page/safety_check_browser_proxy.js +++ b/chrome/browser/resources/settings/safety_check_page/safety_check_browser_proxy.js
@@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// clang-format off +// #import {addSingletonGetter,sendWithPromise} from 'chrome://resources/js/cr.m.js'; +// clang-format on + /** * @fileoverview A helper object used by the "SafetyCheck" to interact with * the browser. @@ -14,7 +18,7 @@ * chrome/browser/ui/webui/settings/safety_check_handler.cc * @enum {string} */ - const SafetyCheckCallbackConstants = { + /* #export */ const SafetyCheckCallbackConstants = { UPDATES_CHANGED: 'safety-check-updates-status-changed', PASSWORDS_CHANGED: 'safety-check-passwords-status-changed', SAFE_BROWSING_CHANGED: 'safety-check-safe-browsing-status-changed', @@ -27,7 +31,7 @@ * chrome/browser/ui/webui/settings/safety_check_handler.h * @enum {number} */ - const SafetyCheckUpdatesStatus = { + /* #export */ const SafetyCheckUpdatesStatus = { CHECKING: 0, UPDATED: 1, UPDATING: 2, @@ -43,7 +47,7 @@ * chrome/browser/ui/webui/settings/safety_check_handler.h * @enum {number} */ - const SafetyCheckPasswordsStatus = { + /* #export */ const SafetyCheckPasswordsStatus = { CHECKING: 0, SAFE: 1, COMPROMISED: 2, @@ -60,7 +64,7 @@ * chrome/browser/ui/webui/settings/safety_check_handler.h * @enum {number} */ - const SafetyCheckSafeBrowsingStatus = { + /* #export */ const SafetyCheckSafeBrowsingStatus = { CHECKING: 0, ENABLED: 1, DISABLED: 2, @@ -74,7 +78,7 @@ * chrome/browser/ui/webui/settings/safety_check_handler.h * @enum {number} */ - const SafetyCheckExtensionsStatus = { + /* #export */ const SafetyCheckExtensionsStatus = { CHECKING: 0, ERROR: 1, NO_BLOCKLISTED_EXTENSIONS: 2, @@ -85,7 +89,7 @@ }; /** @interface */ - class SafetyCheckBrowserProxy { + /* #export */ class SafetyCheckBrowserProxy { /** Run the safety check. */ runSafetyCheck() {} @@ -99,7 +103,7 @@ } /** @implements {settings.SafetyCheckBrowserProxy} */ - class SafetyCheckBrowserProxyImpl { + /* #export */ class SafetyCheckBrowserProxyImpl { /** @override */ runSafetyCheck() { chrome.send('performSafetyCheck'); @@ -113,13 +117,14 @@ cr.addSingletonGetter(SafetyCheckBrowserProxyImpl); + // #cr_define_end return { + SafetyCheckCallbackConstants, SafetyCheckUpdatesStatus, SafetyCheckPasswordsStatus, SafetyCheckSafeBrowsingStatus, SafetyCheckExtensionsStatus, SafetyCheckBrowserProxy, SafetyCheckBrowserProxyImpl, - SafetyCheckCallbackConstants, }; });
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_page.js b/chrome/browser/resources/settings/safety_check_page/safety_check_page.js index a1b2edc..e1d41aa 100644 --- a/chrome/browser/resources/settings/safety_check_page/safety_check_page.js +++ b/chrome/browser/resources/settings/safety_check_page/safety_check_page.js
@@ -294,7 +294,7 @@ * @return {boolean} */ shouldShowParentButton_: function() { - return this.parentStatus_ == ParentStatus.BEFORE; + return this.parentStatus_ === ParentStatus.BEFORE; }, /** @@ -302,7 +302,7 @@ * @return {boolean} */ shouldShowParentIconButton_: function() { - return this.parentStatus_ == ParentStatus.AFTER; + return this.parentStatus_ === ParentStatus.AFTER; }, /** @private */ @@ -357,7 +357,7 @@ * @return {?string} */ getChildUiIconSrc_: function(childUiStatus) { - if (childUiStatus == ChildUiStatus.RUNNING) { + if (childUiStatus === ChildUiStatus.RUNNING) { return 'chrome://resources/images/throbber_small.svg'; } return null; @@ -409,7 +409,7 @@ * @return {boolean} */ shouldShowUpdatesButton_: function() { - return this.updatesStatus_ == settings.SafetyCheckUpdatesStatus.RELAUNCH; + return this.updatesStatus_ === settings.SafetyCheckUpdatesStatus.RELAUNCH; }, /** @@ -417,7 +417,7 @@ * @return {boolean} */ shouldShowUpdatesManagedIcon_: function() { - return this.updatesStatus_ == + return this.updatesStatus_ === settings.SafetyCheckUpdatesStatus.DISABLED_BY_ADMIN; }, @@ -485,7 +485,7 @@ * @return {boolean} */ shouldShowPasswordsButton_: function() { - return this.passwordsStatus_ == + return this.passwordsStatus_ === settings.SafetyCheckPasswordsStatus.COMPROMISED; }, @@ -556,7 +556,7 @@ * @return {boolean} */ shouldShowSafeBrowsingButton_: function() { - return this.safeBrowsingStatus_ == + return this.safeBrowsingStatus_ === settings.SafetyCheckSafeBrowsingStatus.DISABLED; }, @@ -661,7 +661,7 @@ * @return {boolean} */ shouldShowExtensionsManagedIcon_: function() { - return this.extensionsStatus_ == + return this.extensionsStatus_ === settings.SafetyCheckExtensionsStatus.BLOCKLISTED_REENABLED_ALL_BY_ADMIN; },
diff --git a/chrome/browser/resources/settings/settings.gni b/chrome/browser/resources/settings/settings.gni index 1df3a070..085d02bf 100644 --- a/chrome/browser/resources/settings/settings.gni +++ b/chrome/browser/resources/settings/settings.gni
@@ -89,6 +89,12 @@ "settings.Ctap2Status|Ctap2Status", "settings.Credential|Credential", "settings.MetricsReporting|MetricsReporting", + "settings.SafetyCheckBrowserProxy|SafetyCheckBrowserProxy", + "settings.SafetyCheckCallbackConstants|SafetyCheckCallbackConstants", + "settings.SafetyCheckExtensionsStatus|SafetyCheckExtensionsStatus", + "settings.SafetyCheckPasswordsStatus|SafetyCheckPasswordsStatus", + "settings.SafetyCheckSafeBrowsingStatus|SafetyCheckSafeBrowsingStatus", + "settings.SafetyCheckUpdatesStatus|SafetyCheckUpdatesStatus", "settings.SITE_EXCEPTION_WILDCARD|SITE_EXCEPTION_WILDCARD", "settings.SiteSettingSource|SiteSettingSource", "settings.SiteSettingsPrefsBrowserProxy|SiteSettingsPrefsBrowserProxy",
diff --git a/chrome/browser/resources/settings/settings.js b/chrome/browser/resources/settings/settings.js index 4f2b358..6d4caa5a 100644 --- a/chrome/browser/resources/settings/settings.js +++ b/chrome/browser/resources/settings/settings.js
@@ -16,6 +16,7 @@ import './on_startup_page/startup_urls_page.m.js'; import './prefs/prefs.m.js'; import './privacy_page/privacy_page.m.js'; +import './safety_check_page/safety_check_page.m.js'; import './site_favicon.m.js'; import './search_page/search_page.m.js'; import './settings_main/settings_main.m.js'; @@ -42,6 +43,7 @@ export {CrSettingsPrefs} from './prefs/prefs_types.m.js'; export {ExtensionControlBrowserProxyImpl} from './extension_control_browser_proxy.m.js'; export {getSearchManager, SearchRequest, setSearchManagerForTesting} from './search_settings.m.js'; +export {HatsBrowserProxyImpl} from './hats_browser_proxy.m.js'; export {LifetimeBrowserProxyImpl} from './lifetime_browser_proxy.m.js'; export {MetricsBrowserProxyImpl, PrivacyElementInteractions} from './metrics_browser_proxy.m.js'; export {OnStartupBrowserProxy, OnStartupBrowserProxyImpl} from './on_startup_page/on_startup_browser_proxy.m.js'; @@ -58,3 +60,4 @@ export {Route, Router} from './router.m.js'; export {SearchEnginesBrowserProxyImpl} from './search_engines_page/search_engines_browser_proxy.m.js'; export {PrivacyPageBrowserProxyImpl, SecureDnsMode, SecureDnsUiManagementMode} from './privacy_page/privacy_page_browser_proxy.m.js'; +export {SafetyCheckBrowserProxy, SafetyCheckBrowserProxyImpl, SafetyCheckCallbackConstants, SafetyCheckExtensionsStatus, SafetyCheckSafeBrowsingStatus, SafetyCheckPasswordsStatus, SafetyCheckUpdatesStatus} from './safety_check_page/safety_check_browser_proxy.m.js';
diff --git a/chrome/browser/resources/settings/settings_resources_v3.grdp b/chrome/browser/resources/settings/settings_resources_v3.grdp index f8ad2c2f..42bfe74 100644 --- a/chrome/browser/resources/settings/settings_resources_v3.grdp +++ b/chrome/browser/resources/settings/settings_resources_v3.grdp
@@ -547,6 +547,14 @@ file="${root_gen_dir}/chrome/browser/resources/settings/router.m.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_BROWSER_PROXY_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_browser_proxy.m.js" + use_base_dir="false" + type="BINDATA" /> + <include name="IDR_SETTINGS_SAFETY_CHECK_PAGE_SAFETY_CHECK_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/safety_check_page/safety_check_page.m.js" + use_base_dir="false" + type="BINDATA" /> <include name="IDR_SETTINGS_SEARCH_ENGINES_BROWSER_PROXY_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/search_engines_page/search_engines_browser_proxy.m.js" use_base_dir="false"
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc index 850d10b7..932f9e3 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc
@@ -2333,48 +2333,46 @@ chromeos::SpeechMonitor speech_monitor; // Enable ChromeVox. - { ASSERT_FALSE( chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled()); chromeos::AccessibilityManager::Get()->EnableSpokenFeedback(true); - EXPECT_TRUE(speech_monitor.SkipChromeVoxEnabledMessage()); - - // Disable earcons (https://crbug.com/396507). - const std::string script("ChromeVox.earcons.playEarcon = function() {};"); - extensions::ExtensionHost* host = - extensions::ProcessManager::Get(browser()->profile()) - ->GetBackgroundHostForExtension( - extension_misc::kChromeVoxExtensionId); - ASSERT_TRUE(content::ExecuteScript(host->host_contents(), script)); - } ash::RootWindowController* controller = ash::Shell::GetRootWindowControllerWithDisplayId( display::Screen::GetScreen()->GetPrimaryDisplay().id()); - - // Gesture tap at the home button. views::View* home_button = ash::ShelfTestApi().GetHomeButton(); ui::test::EventGenerator event_generator(controller->GetRootWindow()); - event_generator.GestureTapAt(home_button->GetBoundsInScreen().CenterPoint()); + auto* generator_ptr = &event_generator; - ASSERT_EQ("Launcher", speech_monitor.GetNextUtterance()); - ASSERT_EQ("Button", speech_monitor.GetNextUtterance()); - ASSERT_EQ("Shelf", speech_monitor.GetNextUtterance()); - ASSERT_EQ("Tool bar", speech_monitor.GetNextUtterance()); - ASSERT_EQ(", window", speech_monitor.GetNextUtterance()); + // Wait for ChromeVox to start reading anything. + speech_monitor.ExpectSpeechPattern("*"); + speech_monitor.Call([generator_ptr, home_button]() { + // Gesture tap at the home button. + generator_ptr->GestureTapAt(home_button->GetBoundsInScreen().CenterPoint()); + }); + speech_monitor.ExpectSpeech("Launcher"); + speech_monitor.ExpectSpeech("Button"); + speech_monitor.ExpectSpeech("Shelf"); + speech_monitor.ExpectSpeech("Tool bar"); + speech_monitor.ExpectSpeech(", window"); - // Hotseat is expected to be extended if spoken feedback is enabled. - ASSERT_EQ(ash::HotseatState::kExtended, - controller->shelf()->shelf_layout_manager()->hotseat_state()); + speech_monitor.Call([controller]() { + // Hotseat is expected to be extended if spoken feedback is enabled. + ASSERT_EQ(ash::HotseatState::kExtended, + controller->shelf()->shelf_layout_manager()->hotseat_state()); + }); - // Press the search + right. Expects that the browser icon receives the - // accessibility focus and the hotseat remains in kExtended state. - event_generator.PressKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN); + speech_monitor.Call([generator_ptr]() { + // Press the search + right. Expects that the browser icon receives the + // accessibility focus and the hotseat remains in kExtended state. + generator_ptr->PressKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN); + }); const int browser_index = ash::ShelfModel::Get()->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT); - EXPECT_EQ( - base::UTF16ToASCII(ash::ShelfModel::Get()->items()[browser_index].title), - speech_monitor.GetNextUtterance()); + speech_monitor.ExpectSpeech( + base::UTF16ToASCII(ash::ShelfModel::Get()->items()[browser_index].title)); + speech_monitor.Replay(); + EXPECT_EQ(ash::HotseatState::kExtended, controller->shelf()->shelf_layout_manager()->hotseat_state());
diff --git a/chrome/browser/ui/toolbar/media_router_action_controller.cc b/chrome/browser/ui/toolbar/media_router_action_controller.cc index 112bec6..48b5361 100644 --- a/chrome/browser/ui/toolbar/media_router_action_controller.cc +++ b/chrome/browser/ui/toolbar/media_router_action_controller.cc
@@ -152,6 +152,9 @@ if (profile_->IsRegularProfile()) { media_router::MediaRouterMetrics::RecordIconStateAtInit( MediaRouterActionController::GetAlwaysShowActionPref(profile_)); + media_router::MediaRouterMetrics::RecordCloudPrefAtInit( + profile_->GetPrefs()->GetBoolean( + prefs::kMediaRouterEnableCloudServices)); } }
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_metrics.cc b/chrome/browser/ui/views/media_router/cast_dialog_metrics.cc index 1f64e31..abaf6e7 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_metrics.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_metrics.cc
@@ -19,6 +19,8 @@ is_icon_pinned_( profile->GetPrefs()->GetBoolean(prefs::kShowCastIconInToolbar)) { MediaRouterMetrics::RecordIconStateAtDialogOpen(is_icon_pinned_); + MediaRouterMetrics::RecordCloudPrefAtDialogOpen( + profile->GetPrefs()->GetBoolean(prefs::kMediaRouterEnableCloudServices)); } CastDialogMetrics::~CastDialogMetrics() = default;
diff --git a/chrome/browser/ui/views/media_router/cast_dialog_metrics_unittest.cc b/chrome/browser/ui/views/media_router/cast_dialog_metrics_unittest.cc index 7ed589b0..290e5f69 100644 --- a/chrome/browser/ui/views/media_router/cast_dialog_metrics_unittest.cc +++ b/chrome/browser/ui/views/media_router/cast_dialog_metrics_unittest.cc
@@ -109,6 +109,16 @@ /* is_pinned */ true, 1); } +TEST_F(CastDialogMetricsTest, RecordCloudPref) { + // When a dialog is opened after enabling the cloud services, that should be + // recorded. + profile_.GetPrefs()->SetBoolean(prefs::kMediaRouterEnableCloudServices, true); + CastDialogMetrics metrics_with_cloud_pref_enabled{ + init_time, MediaRouterDialogOpenOrigin::PAGE, &profile_}; + tester_.ExpectBucketCount(MediaRouterMetrics::kHistogramCloudPrefAtDialogOpen, + /* enabled */ true, 1); +} + TEST_F(CastDialogMetricsTest, RecordDialogActivationLocationAndCastMode) { constexpr int kSinkIndex = 4; metrics_.OnSinksLoaded(sink_load_time);
diff --git a/chrome/browser/ui/webui/help/version_updater_mac.mm b/chrome/browser/ui/webui/help/version_updater_mac.mm index ea5960a..4550497 100644 --- a/chrome/browser/ui/webui/help/version_updater_mac.mm +++ b/chrome/browser/ui/webui/help/version_updater_mac.mm
@@ -176,7 +176,6 @@ break; case kAutoupdatePromoting: -#if 1 // TODO(mark): KSRegistration currently handles the promotion // synchronously, meaning that the main thread's loop doesn't spin, // meaning that animations and other updates to the window won't occur @@ -185,10 +184,6 @@ // visual feedback while promotion is in progress, but it should complete // (or fail) very quickly. http://b/2290009. return; -#endif - status = CHECKING; - enable_promote_button = false; - break; case kAutoupdateRegisterFailed: enable_promote_button = false;
diff --git a/chrome/browser/upboarding/query_tiles/android/java/res/layout/query_tile_view.xml b/chrome/browser/upboarding/query_tiles/android/java/res/layout/query_tile_view.xml index a0dcc21f..647198c 100644 --- a/chrome/browser/upboarding/query_tiles/android/java/res/layout/query_tile_view.xml +++ b/chrome/browser/upboarding/query_tiles/android/java/res/layout/query_tile_view.xml
@@ -2,22 +2,25 @@ <!-- Copyright 2020 The Chromium Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<LinearLayout +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="86dp" android:layout_height="86dp" android:orientation="vertical"> + <org.chromium.ui.widget.ChromeImageView android:id="@+id/thumbnail" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_horizontal" android:scaleType="centerCrop" + android:src="@drawable/chrome_sync_logo" android:importantForAccessibility="no"/> <TextView android:id="@+id/title" - android:layout_width="match_parent" - android:layout_height="wrap_content"/> -</LinearLayout> + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerInParent="true"/> +</RelativeLayout> \ No newline at end of file
diff --git a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileCoordinator.java b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileCoordinator.java index d2de76fe..f95f12ef 100644 --- a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileCoordinator.java +++ b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileCoordinator.java
@@ -4,12 +4,35 @@ package org.chromium.chrome.browser.query_tiles; +import android.graphics.Bitmap; import android.view.View; +import org.chromium.base.Callback; + +import java.util.List; + /** * The top level coordinator for the query tiles UI. */ public interface QueryTileCoordinator { /** @return A {@link View} representing this coordinator. */ View getView(); -} + + /** + * Sets a list of tiles to be displayed. + * @param tiles The list of tiles to be displayed. + */ + void setTiles(List<Tile> tiles); + + /** A helper interface to support retrieving {@link Bitmap}s asynchronously. */ + @FunctionalInterface + interface TileVisualsProvider { + /** + * Called to get the visuals required for showing the tile. The result consists a list of + * bitmaps, as the UI might use more than one bitmap to represent the tile. + * @param tile The {@link Tile} to get the {@link Bitmap} for. + * @param callback A {@link Callback} that will be notified on completion. + */ + void getVisuals(Tile tile, Callback<List<Bitmap>> callback); + } +} \ No newline at end of file
diff --git a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileCoordinatorFactory.java b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileCoordinatorFactory.java index dd99f00b..4e18f8e 100644 --- a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileCoordinatorFactory.java +++ b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/QueryTileCoordinatorFactory.java
@@ -7,6 +7,7 @@ import android.content.Context; import org.chromium.base.Callback; +import org.chromium.chrome.browser.query_tiles.QueryTileCoordinator.TileVisualsProvider; import org.chromium.chrome.browser.query_tiles.list.QueryTileCoordinatorImpl; /** @@ -16,12 +17,11 @@ /** * Creates a {@link QueryTileCoordinator}. * @param context The context associated with the current activity. - * @param tileProvider The {@link TileProvider} to provide tiles. - * @param visibilityCallback A callback to show/hide the query tile section + * @param tileClickCallback A callback to be invoked when a tile is clicked. * @return A {@link QueryTileCoordinator}. */ - public static QueryTileCoordinator create( - Context context, TileProvider tileProvider, Callback<Boolean> visibilityCallback) { - return new QueryTileCoordinatorImpl(context, tileProvider, visibilityCallback); + public static QueryTileCoordinator create(Context context, Callback<Tile> tileClickCallback, + TileVisualsProvider tileVisualsProvider) { + return new QueryTileCoordinatorImpl(context, tileClickCallback, tileVisualsProvider); } -} +} \ No newline at end of file
diff --git a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/TileProvider.java b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/TileProvider.java index 8ca0b79..7ae2796 100644 --- a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/TileProvider.java +++ b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/TileProvider.java
@@ -23,10 +23,10 @@ void getQueryTiles(Callback<List<Tile>> callback); /** - * Called to retrieve thumbnail for the given tile id. + * Called to retrieve visuals for the given tile id. * @param id The ID for a given tile. * @param callback The {@link Callback} to be run after fetching the thumbnail. Returns null if - * no thumbnail was found. + * no visuals were found. */ - void getThumbnail(String id, Callback<Bitmap> callback); + void getVisuals(String id, Callback<List<Bitmap>> callback); } \ No newline at end of file
diff --git a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/bridges/TileProviderBridge.java b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/bridges/TileProviderBridge.java index 2820e18..5042991 100644 --- a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/bridges/TileProviderBridge.java +++ b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/bridges/TileProviderBridge.java
@@ -46,9 +46,9 @@ } @Override - public void getThumbnail(String id, Callback<Bitmap> callback) { + public void getVisuals(String id, Callback<List<Bitmap>> callback) { if (mNativeTileProviderBridge == 0) return; - TileProviderBridgeJni.get().getThumbnail(mNativeTileProviderBridge, this, id, callback); + TileProviderBridgeJni.get().getVisuals(mNativeTileProviderBridge, this, id, callback); } @CalledByNative @@ -68,7 +68,7 @@ interface Natives { void getQueryTiles(long nativeTileProviderBridge, TileProviderBridge caller, Callback<List<Tile>> callback); - void getThumbnail(long nativeTileProviderBridge, TileProviderBridge caller, String id, - Callback<Bitmap> callback); + void getVisuals(long nativeTileProviderBridge, TileProviderBridge caller, String id, + Callback<List<Bitmap>> callback); } } \ No newline at end of file
diff --git a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/list/QueryTileCoordinatorImpl.java b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/list/QueryTileCoordinatorImpl.java index 688633f..06116bf5 100644 --- a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/list/QueryTileCoordinatorImpl.java +++ b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/list/QueryTileCoordinatorImpl.java
@@ -5,13 +5,13 @@ package org.chromium.chrome.browser.query_tiles.list; import android.content.Context; -import android.graphics.Bitmap; import android.view.View; import org.chromium.base.Callback; import org.chromium.chrome.browser.query_tiles.QueryTileCoordinator; import org.chromium.chrome.browser.query_tiles.Tile; -import org.chromium.chrome.browser.query_tiles.TileProvider; + +import java.util.List; /** * The top level coordinator for the query tiles UI. @@ -19,20 +19,15 @@ public class QueryTileCoordinatorImpl implements QueryTileCoordinator { private final TileListModel mModel; private final TileListView mView; - private final TileProvider mTileProvider; - private final Callback<Boolean> mVisibilityCallback; /** Constructor. */ - public QueryTileCoordinatorImpl( - Context context, TileProvider tileProvider, Callback<Boolean> visibilityCallback) { - mTileProvider = tileProvider; - mVisibilityCallback = visibilityCallback; + public QueryTileCoordinatorImpl(Context context, Callback<Tile> tileClickCallback, + TileVisualsProvider visualsProvider) { mModel = new TileListModel(); mView = new TileListView(context, mModel); - mModel.getProperties().set(TileListProperties.CLICK_CALLBACK, this::onQueryTileClicked); - mModel.getProperties().set(TileListProperties.VISUALS_CALLBACK, this::getVisuals); - onQueryTileClicked(null); + mModel.getProperties().set(TileListProperties.CLICK_CALLBACK, tileClickCallback); + mModel.getProperties().set(TileListProperties.VISUALS_CALLBACK, visualsProvider); } @Override @@ -40,18 +35,8 @@ return mView.getView(); } - private void onQueryTileClicked(Tile tile) { - if (tile != null) { - mModel.set(tile.children); - } else { - mTileProvider.getQueryTiles(tiles -> { - mModel.set(tiles); - mVisibilityCallback.onResult(!tiles.isEmpty()); - }); - } - } - - private void getVisuals(Tile tile, Callback<Bitmap> callback) { - mTileProvider.getThumbnail(tile.id, callback); + @Override + public void setTiles(List<Tile> tiles) { + mModel.set(tiles); } }
diff --git a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/list/TileListProperties.java b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/list/TileListProperties.java index 02acd12..f65234c 100644 --- a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/list/TileListProperties.java +++ b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/list/TileListProperties.java
@@ -4,9 +4,8 @@ package org.chromium.chrome.browser.query_tiles.list; -import android.graphics.Bitmap; - import org.chromium.base.Callback; +import org.chromium.chrome.browser.query_tiles.QueryTileCoordinator.TileVisualsProvider; import org.chromium.chrome.browser.query_tiles.Tile; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey; @@ -17,21 +16,13 @@ * properties that are effectively shared across all list items like callbacks. */ interface TileListProperties { - /** A helper interface to support retrieving {@link Bitmap} asynchronously. */ - @FunctionalInterface - interface VisualsProvider { - /** - * @param tile The {@link Tile} to get the {@link Bitmap} for. - * @param callback A {@link Callback} that will be notified on completion. - */ - void getVisuals(Tile tile, Callback<Bitmap> callback); - } /** The callback to run when a {@link Tile} is clicked on the UI. */ WritableObjectPropertyKey<Callback<Tile>> CLICK_CALLBACK = new WritableObjectPropertyKey<>(); /** The provider to retrieve expensive visuals for a {@link Tile}. */ - WritableObjectPropertyKey<VisualsProvider> VISUALS_CALLBACK = new WritableObjectPropertyKey<>(); + WritableObjectPropertyKey<TileVisualsProvider> VISUALS_CALLBACK = + new WritableObjectPropertyKey<>(); PropertyKey[] ALL_KEYS = new PropertyKey[] {CLICK_CALLBACK, VISUALS_CALLBACK}; -} +} \ No newline at end of file
diff --git a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/list/TileViewHolder.java b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/list/TileViewHolder.java index 4a383872..7c2c90f 100644 --- a/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/list/TileViewHolder.java +++ b/chrome/browser/upboarding/query_tiles/android/java/src/org/chromium/chrome/browser/query_tiles/list/TileViewHolder.java
@@ -47,8 +47,10 @@ v -> { properties.get(TileListProperties.CLICK_CALLBACK).onResult(tile); }); final ImageView thumbnail = itemView.findViewById(R.id.thumbnail); - properties.get(TileListProperties.VISUALS_CALLBACK) - .getVisuals(tile, thumbnail::setImageBitmap); + properties.get(TileListProperties.VISUALS_CALLBACK).getVisuals(tile, bitmaps -> { + thumbnail.setImageBitmap( + (bitmaps == null || bitmaps.isEmpty()) ? null : bitmaps.get(0)); + }); } /**
diff --git a/chrome/browser/upboarding/query_tiles/android/javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionTest.java b/chrome/browser/upboarding/query_tiles/android/javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionTest.java index 0c4c009..0a5615d8 100644 --- a/chrome/browser/upboarding/query_tiles/android/javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionTest.java +++ b/chrome/browser/upboarding/query_tiles/android/javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionTest.java
@@ -74,7 +74,7 @@ } @Override - public void getThumbnail(String id, Callback<Bitmap> callback) { + public void getVisuals(String id, Callback<List<Bitmap>> callback) { callback.onResult(null); } }
diff --git a/chrome/browser/upboarding/query_tiles/android/tile_provider_bridge.cc b/chrome/browser/upboarding/query_tiles/android/tile_provider_bridge.cc index 1417ca7..e971c1535 100644 --- a/chrome/browser/upboarding/query_tiles/android/tile_provider_bridge.cc +++ b/chrome/browser/upboarding/query_tiles/android/tile_provider_bridge.cc
@@ -98,10 +98,10 @@ &RunGetTilesCallback, ScopedJavaGlobalRef<jobject>(jcallback))); } -void TileProviderBridge::GetThumbnail(JNIEnv* env, - const JavaParamRef<jobject>& jcaller, - const JavaParamRef<jstring>& jid, - const JavaParamRef<jobject>& jcallback) { +void TileProviderBridge::GetVisuals(JNIEnv* env, + const JavaParamRef<jobject>& jcaller, + const JavaParamRef<jstring>& jid, + const JavaParamRef<jobject>& jcallback) { std::string tile_id = ConvertJavaStringToUTF8(env, jid); tile_service_->GetVisuals( tile_id, base::BindOnce(&RunGeVisualsCallback,
diff --git a/chrome/browser/upboarding/query_tiles/android/tile_provider_bridge.h b/chrome/browser/upboarding/query_tiles/android/tile_provider_bridge.h index aa34e453..95d1a83 100644 --- a/chrome/browser/upboarding/query_tiles/android/tile_provider_bridge.h +++ b/chrome/browser/upboarding/query_tiles/android/tile_provider_bridge.h
@@ -32,10 +32,10 @@ const JavaParamRef<jobject>& jcaller, const JavaParamRef<jobject>& jcallback); - void GetThumbnail(JNIEnv* env, - const JavaParamRef<jobject>& jcaller, - const JavaParamRef<jstring>& jid, - const JavaParamRef<jobject>& jcallback); + void GetVisuals(JNIEnv* env, + const JavaParamRef<jobject>& jcaller, + const JavaParamRef<jstring>& jid, + const JavaParamRef<jobject>& jcallback); private: // A reference to the Java counterpart of this class. See
diff --git a/chrome/services/local_search_service/index_impl.cc b/chrome/services/local_search_service/index_impl.cc index f636953..4d48712a 100644 --- a/chrome/services/local_search_service/index_impl.cc +++ b/chrome/services/local_search_service/index_impl.cc
@@ -156,7 +156,10 @@ int32_t max_results, FindCallback callback) { std::vector<local_search_service::Result> results; - const auto response = Find(query, max_latency_in_ms, max_results, &results); + // TODO(jiameng): |max_latency| isn't supported yet. We're + // temporarily ignoring it before the next cl removes the async call. + const auto response = + Find(query, max_results < 0 ? 0u : max_results, &results); mojom::ResponseStatus mresponse = mojom::ResponseStatus::UNKNOWN_ERROR; switch (response) { @@ -197,8 +200,7 @@ local_search_service::ResponseStatus IndexImpl::Find( const base::string16& query, - int32_t max_latency_in_ms, - int32_t max_results, + uint32_t max_results, std::vector<local_search_service::Result>* results) { DCHECK(results); results->clear(); @@ -209,7 +211,7 @@ return local_search_service::ResponseStatus::kEmptyIndex; } - *results = GetSearchResults(query); + *results = GetSearchResults(query, max_results); return local_search_service::ResponseStatus::kSuccess; } @@ -250,7 +252,8 @@ } std::vector<local_search_service::Result> IndexImpl::GetSearchResults( - const base::string16& query) const { + const base::string16& query, + uint32_t max_results) const { std::vector<local_search_service::Result> results; const TokenizedString tokenized_query(query); @@ -272,6 +275,9 @@ } std::sort(results.begin(), results.end(), CompareResults); + if (results.size() > max_results && max_results > 0u) { + results.resize(max_results); + } return results; }
diff --git a/chrome/services/local_search_service/index_impl.h b/chrome/services/local_search_service/index_impl.h index 2dc4583..75eff5d4fe 100644 --- a/chrome/services/local_search_service/index_impl.h +++ b/chrome/services/local_search_service/index_impl.h
@@ -114,10 +114,10 @@ int32_t max_latency_in_ms, int32_t max_results, FindCallback callback) override; + // Zero |max_results| means no max. local_search_service::ResponseStatus Find( const base::string16& query, - int32_t max_latency_in_ms, - int32_t max_results, + uint32_t max_results, std::vector<local_search_service::Result>* results); void SetSearchParams(mojom::SearchParamsPtr search_params, @@ -133,7 +133,8 @@ private: // Returns all search results for a given query. std::vector<local_search_service::Result> GetSearchResults( - const base::string16& query) const; + const base::string16& query, + uint32_t max_results) const; // A map from key to tokenized search-tags. std::map<std::string, std::vector<std::unique_ptr<TokenizedString>>> data_;
diff --git a/chrome/services/local_search_service/index_impl_unittest.cc b/chrome/services/local_search_service/index_impl_unittest.cc index 66036d3..6206140 100644 --- a/chrome/services/local_search_service/index_impl_unittest.cc +++ b/chrome/services/local_search_service/index_impl_unittest.cc
@@ -137,4 +137,21 @@ } } +TEST_F(IndexImplTest, MaxResults) { + const std::map<std::string, std::vector<std::string>> data_to_register = { + {"id1", {"Clash Of Clan"}}, {"id2", {"famous"}}}; + std::vector<mojom::DataPtr> data = CreateTestData(data_to_register); + AddOrUpdateAndCheck(index_remote_.get(), std::move(data)); + GetSizeAndCheck(index_remote_.get(), 2u); + mojom::SearchParamsPtr search_params = mojom::SearchParams::New(); + search_params->relevance_threshold = 0.0; + SetSearchParamsAndCheck(index_remote_.get(), std::move(search_params)); + + FindAndCheck(index_remote_.get(), "CC", /*max_latency_in_ms=*/-1, + /*max_results=*/-1, mojom::ResponseStatus::SUCCESS, + {"id1", "id2"}); + FindAndCheck(index_remote_.get(), "CC", /*max_latency_in_ms=*/-1, + /*max_results=*/1, mojom::ResponseStatus::SUCCESS, {"id1"}); +} + } // namespace local_search_service
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index 538476e53..0fd5c8c 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -258,6 +258,7 @@ "$root_gen_dir/chrome/test/data/webui/settings/protocol_handlers_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/recent_site_permissions_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/reset_page_test.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/safety_check_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/search_engines_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/search_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/search_settings_test.m.js", @@ -285,6 +286,7 @@ "$root_gen_dir/chrome/test/data/webui/settings/site_settings_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/sync_test_util.m.js", "$root_gen_dir/chrome/test/data/webui/settings/test_extension_control_browser_proxy.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/test_hats_browser_proxy.m.js", "$root_gen_dir/chrome/test/data/webui/settings/test_languages_browser_proxy.m.js", "$root_gen_dir/chrome/test/data/webui/settings/test_lifetime_browser_proxy.m.js", "$root_gen_dir/chrome/test/data/webui/settings/test_open_window_proxy.m.js",
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn index 16803db..9e6e964 100644 --- a/chrome/test/data/webui/settings/BUILD.gn +++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -53,6 +53,7 @@ "protocol_handlers_tests.js", "recent_site_permissions_test.js", "reset_page_test.js", + "safety_check_page_test.js", "search_engines_page_test.js", "search_page_test.js", "search_settings_test.js", @@ -81,6 +82,7 @@ "sync_test_util.js", "test_about_page_browser_proxy.js", "test_extension_control_browser_proxy.js", + "test_hats_browser_proxy.js", "test_languages_browser_proxy.js", "test_lifetime_browser_proxy.js", "test_local_data_browser_proxy.js",
diff --git a/chrome/test/data/webui/settings/cr_settings_interactive_ui_tests.js b/chrome/test/data/webui/settings/cr_settings_interactive_ui_tests.js index 666aa47f..981bd16 100644 --- a/chrome/test/data/webui/settings/cr_settings_interactive_ui_tests.js +++ b/chrome/test/data/webui/settings/cr_settings_interactive_ui_tests.js
@@ -132,8 +132,8 @@ ]), }; -// Fails on Mac10.13 Tests (dbg) (see crbug/1063844). -GEN('#if !(defined(OS_MACOSX) && !defined(NDEBUG))'); +// Flaky on Mac (see https://crbug.com/1065154). +GEN('#if !defined(OS_MACOSX)'); TEST_F('SettingsUIInteractiveTest', 'All', function() { mocha.run(); });
diff --git a/chrome/test/data/webui/settings/cr_settings_v3_browsertest.js b/chrome/test/data/webui/settings/cr_settings_v3_browsertest.js index b538bc18..cc933050 100644 --- a/chrome/test/data/webui/settings/cr_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_v3_browsertest.js
@@ -9,6 +9,7 @@ GEN('#include "services/network/public/cpp/features.h"'); GEN('#include "build/branding_buildflags.h"'); +GEN('#include "chrome/common/chrome_features.h"'); GEN('#include "components/autofill/core/common/autofill_features.h"'); GEN('#include "components/password_manager/core/common/password_manager_features.h"'); @@ -211,6 +212,26 @@ }); // eslint-disable-next-line no-var +var CrSettingsSafetyCheckPageV3Test = class extends CrSettingsV3BrowserTest { + /** @override */ + get browsePreload() { + return 'chrome://settings/test_loader.html?module=settings/safety_check_page_test.m.js'; + } + + /** @override */ + get featureList() { + const list = super.featureList; + list.enabled.push('features::kPrivacySettingsRedesign'); + list.enabled.push('password_manager::features::kPasswordCheck'); + return list; + } +}; + +TEST_F('CrSettingsSafetyCheckPageV3Test', 'All', function() { + mocha.run(); +}); + +// eslint-disable-next-line no-var var CrSettingsSiteListV3Test = class extends CrSettingsV3BrowserTest { /** @override */ get browsePreload() {
diff --git a/chrome/test/data/webui/settings/safety_check_page_test.js b/chrome/test/data/webui/settings/safety_check_page_test.js index 5d0a859..fb99673 100644 --- a/chrome/test/data/webui/settings/safety_check_page_test.js +++ b/chrome/test/data/webui/settings/safety_check_page_test.js
@@ -2,6 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// clang-format off +// #import {HatsBrowserProxyImpl, LifetimeBrowserProxyImpl, OpenWindowProxyImpl, PasswordManagerImpl, PasswordManagerProxy, Router, routes, SafetyCheckBrowserProxy, SafetyCheckBrowserProxyImpl, SafetyCheckCallbackConstants, SafetyCheckExtensionsStatus, SafetyCheckPasswordsStatus, SafetyCheckSafeBrowsingStatus, SafetyCheckUpdatesStatus} from 'chrome://settings/settings.js'; +// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {TestBrowserProxy} from 'chrome://test/test_browser_proxy.m.js'; +// #import {TestHatsBrowserProxy} from 'chrome://test/settings/test_hats_browser_proxy.m.js'; +// #import {TestLifetimeBrowserProxy} from 'chrome://test/settings/test_lifetime_browser_proxy.m.js'; +// #import {TestPasswordManagerProxy} from 'chrome://test/settings/test_password_manager_proxy.m.js'; +// #import {TestOpenWindowProxy} from 'chrome://test/settings/test_open_window_proxy.m.js'; +// clang-format on + suite('SafetyCheckUiTests', function() { /** @type {?settings.LifetimeBrowserProxy} */ let lifetimeBrowserProxy = null;
diff --git a/chrome/test/data/webui/settings/test_hats_browser_proxy.js b/chrome/test/data/webui/settings/test_hats_browser_proxy.js index ec74b8e..909cbb8 100644 --- a/chrome/test/data/webui/settings/test_hats_browser_proxy.js +++ b/chrome/test/data/webui/settings/test_hats_browser_proxy.js
@@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// #import {TestBrowserProxy} from 'chrome://test/test_browser_proxy.m.js'; + /** @implements {settings.HatsBrowserProxy} */ -class TestHatsBrowserProxy extends TestBrowserProxy { +/* #export */ class TestHatsBrowserProxy extends TestBrowserProxy { constructor() { super([ 'tryShowSurvey', @@ -14,4 +16,4 @@ tryShowSurvey() { this.methodCalled('tryShowSurvey'); } -} \ No newline at end of file +}
diff --git a/chromecast/browser/webview/client/webview.cc b/chromecast/browser/webview/client/webview.cc index bd97207..038b7e8 100644 --- a/chromecast/browser/webview/client/webview.cc +++ b/chromecast/browser/webview/client/webview.cc
@@ -10,6 +10,8 @@ #include "base/files/file_descriptor_watcher_posix.h" #include "base/logging.h" #include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" #include "base/threading/thread_task_runner_handle.h" #include "chromecast/browser/webview/proto/webview.pb.h" #include "third_party/grpc/src/include/grpcpp/grpcpp.h" @@ -22,7 +24,13 @@ namespace { constexpr int kGrpcMaxReconnectBackoffMs = 1000; -constexpr int kWebviewId = 10; + +constexpr char kCreateCommand[] = "create"; +constexpr char kDestroyCommand[] = "destroy"; +constexpr char kListCommand[] = "list"; +constexpr char kNavigateCommand[] = "navigate"; +constexpr char kResizeCommand[] = "resize"; +constexpr char kPositionCommand[] = "position"; void FrameCallback(void* data, wl_callback* callback, uint32_t time) { WebviewClient* webview_client = static_cast<WebviewClient*>(data); @@ -42,6 +50,10 @@ using chromecast::webview::WebviewRequest; using chromecast::webview::WebviewResponse; +WebviewClient::Webview::Webview() {} + +WebviewClient::Webview::~Webview() {} + WebviewClient::WebviewClient() : task_runner_(base::ThreadTaskRunnerHandle::Get()), file_descriptor_watcher_(task_runner_) {} @@ -59,8 +71,8 @@ void WebviewClient::Run(const InitParams& params, const std::string& channel_directory) { - webview_surface_.reset(static_cast<wl_surface*>( - wl_compositor_create_surface(globals_.compositor.get()))); + drm_format_ = params.drm_format; + bo_usage_ = params.bo_usage; // Roundtrip to wait for display configuration. wl_display_roundtrip(display_.get()); @@ -72,48 +84,8 @@ stub_ = chromecast::webview::PlatformViewsService::NewStub( ::grpc::CreateCustomChannel(std::string("unix:" + channel_directory), ::grpc::InsecureChannelCredentials(), args)); - std::unique_ptr<::grpc::ClientContext> context = - std::make_unique<::grpc::ClientContext>(); - client_ = stub_->CreateWebview(context.get()); - WebviewRequest request; - request.mutable_create()->set_webview_id(kWebviewId); - request.mutable_create()->set_window_id(kWebviewId); - - if (!client_->Write(request)) { - LOG(ERROR) << ("Failed to create webview"); - return; - } - - WebviewResponse response; - if (!client_->Read(&response)) { - LOG(ERROR) << "Failed to read webview creation response"; - return; - } - - wl_webview_surface_.reset(wl_subcompositor_get_subsurface( - globals_.subcompositor.get(), webview_surface_.get(), surface_.get())); - wl_subsurface_set_sync(wl_webview_surface_.get()); - aura_surface.reset(zaura_shell_get_aura_surface(globals_.aura_shell.get(), - webview_surface_.get())); - - if (!aura_surface) { - LOG(ERROR) << "No aura surface"; - return; - } - - zaura_surface_set_client_surface_id(aura_surface.get(), kWebviewId); - - WebviewRequest resize_request; - resize_request.mutable_resize()->set_width(size_.height()); - resize_request.mutable_resize()->set_height(size_.width()); - - if (!client_->Write(resize_request)) { - LOG(ERROR) << ("Resize request failed"); - return; - } - - std::cout << "Enter URL, q to quit: "; + std::cout << "Enter command: "; std::cout.flush(); task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebviewClient::Paint, base::Unretained(this))); @@ -144,7 +116,70 @@ buffer_callbacks_.push_back(std::move(buffer_callback)); buffers_.push_back(std::move(buffer)); } - webview_buffer_ = CreateBuffer(size_, params.drm_format, params.bo_usage); +} + +void WebviewClient::CreateWebview(const std::vector<std::string>& tokens) { + if (tokens.size() != 2) { + LOG(ERROR) << "Usage: create [ID]"; + return; + } + + int id; + if (!base::StringToInt(tokens[1], &id)) { + LOG(ERROR) << "ID is not an int"; + return; + } else if (webviews_.find(id) != webviews_.end()) { + LOG(ERROR) << "Webview with ID " << tokens[1] << " already exists"; + return; + } + + std::unique_ptr<Webview> webview = std::make_unique<Webview>(); + + webview->buffer = CreateBuffer(gfx::Size(1, 1), drm_format_, bo_usage_); + + webview->surface.reset(static_cast<wl_surface*>( + wl_compositor_create_surface(globals_.compositor.get()))); + + webview->context = std::make_unique<::grpc::ClientContext>(); + webview->client = stub_->CreateWebview(webview->context.get()); + + WebviewRequest request; + request.mutable_create()->set_webview_id(id); + request.mutable_create()->set_window_id(id); + if (!webview->client->Write(request)) { + LOG(ERROR) << ("Failed to create webview"); + return; + } + + WebviewResponse response; + if (!webview->client->Read(&response)) { + LOG(ERROR) << "Failed to read webview creation response"; + return; + } + + webview->subsurface.reset(wl_subcompositor_get_subsurface( + globals_.subcompositor.get(), webview->surface.get(), surface_.get())); + wl_subsurface_set_sync(webview->subsurface.get()); + + std::unique_ptr<zaura_surface> aura_surface; + aura_surface.reset(zaura_shell_get_aura_surface(globals_.aura_shell.get(), + webview->surface.get())); + if (!aura_surface) { + LOG(ERROR) << "No aura surface"; + return; + } + zaura_surface_set_client_surface_id(aura_surface.get(), id); + + webviews_[id] = std::move(webview); +} + +void WebviewClient::DestroyWebview(const std::vector<std::string>& tokens) { + int id; + if (tokens.size() != 2 || !base::StringToInt(tokens[1], &id)) { + LOG(ERROR) << "Usage: destroy [ID]"; + return; + } + webviews_.erase(id); } void WebviewClient::HandleMode(void* data, @@ -187,18 +222,41 @@ void WebviewClient::InputCallback() { std::string request; - std::cin >> request; + getline(std::cin, request); if (request == "q") { run_loop_.Quit(); return; } - SendNavigationRequest(request); - std::cout << "Enter URL, q to quit: "; + std::vector<std::string> tokens = SplitString( + request, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + + if (tokens.size() == 0) + return; + + if (tokens[0] == kCreateCommand) + CreateWebview(tokens); + else if (tokens[0] == kDestroyCommand) + DestroyWebview(tokens); + else if (tokens[0] == kListCommand) + ListActiveWebviews(); + else if (tokens[1] == kNavigateCommand) + SendNavigationRequest(tokens); + else if (tokens[1] == kResizeCommand) + SendResizeRequest(tokens); + else if (tokens[1] == kPositionCommand) + SetPosition(tokens); + + std::cout << "Enter command: "; std::cout.flush(); } +void WebviewClient::ListActiveWebviews() { + for (const auto& pair : webviews_) + std::cout << pair.first << std::endl; +} + void WebviewClient::Paint() { Buffer* buffer = DequeueBuffer(); @@ -216,18 +274,21 @@ surface_size_.height()); wl_surface_attach(surface_.get(), buffer->buffer.get(), 0, 0); - wl_surface_set_buffer_scale(webview_surface_.get(), scale_); - wl_surface_damage(webview_surface_.get(), 0, 0, surface_size_.width(), - surface_size_.height()); - wl_surface_attach(webview_surface_.get(), webview_buffer_->buffer.get(), 0, - 0); - // Set up frame callbacks. frame_callback_.reset(wl_surface_frame(surface_.get())); static wl_callback_listener frame_listener = {FrameCallback}; wl_callback_add_listener(frame_callback_.get(), &frame_listener, this); - wl_surface_commit(webview_surface_.get()); + for (const auto& pair : webviews_) { + Webview* webview = pair.second.get(); + wl_surface_set_buffer_scale(webview->surface.get(), scale_); + wl_surface_damage(webview->surface.get(), 0, 0, surface_size_.width(), + surface_size_.height()); + wl_surface_attach(webview->surface.get(), webview->buffer->buffer.get(), 0, + 0); + wl_surface_commit(webview->surface.get()); + } + wl_surface_commit(surface_.get()); wl_display_flush(display_.get()); } @@ -237,15 +298,58 @@ FROM_HERE, base::BindOnce(&WebviewClient::Paint, base::Unretained(this))); } -void WebviewClient::SendNavigationRequest(const std::string& URL) { - WebviewRequest load_url_request; - load_url_request.mutable_navigate()->set_url(URL); +void WebviewClient::SendNavigationRequest( + const std::vector<std::string>& tokens) { + int id; + if (tokens.size() != 3 || !base::StringToInt(tokens[0], &id) || + webviews_.find(id) == webviews_.end()) { + LOG(ERROR) << "Usage: [ID] navigate [URL]"; + return; + } - if (!client_->Write(load_url_request)) { + const auto& webview = webviews_[id]; + WebviewRequest load_url_request; + load_url_request.mutable_navigate()->set_url(tokens[2]); + if (!webview->client->Write(load_url_request)) { LOG(ERROR) << ("Navigation request send failed"); } } +void WebviewClient::SendResizeRequest(const std::vector<std::string>& tokens) { + int id, width, height; + if (tokens.size() != 4 || !base::StringToInt(tokens[0], &id) || + webviews_.find(id) == webviews_.end() || + !base::StringToInt(tokens[2], &width) || + !base::StringToInt(tokens[3], &height)) { + LOG(ERROR) << "Usage: [ID] resize [WIDTH] [HEIGHT]"; + return; + } + + const auto& webview = webviews_[id]; + WebviewRequest resize_request; + resize_request.mutable_resize()->set_width(width); + resize_request.mutable_resize()->set_height(height); + if (!webview->client->Write(resize_request)) { + LOG(ERROR) << ("Resize request failed"); + return; + } + webview->buffer = + CreateBuffer(gfx::Size(width, height), drm_format_, bo_usage_); +} + +void WebviewClient::SetPosition(const std::vector<std::string>& tokens) { + int id, x, y; + if (tokens.size() != 4 || !base::StringToInt(tokens[0], &id) || + webviews_.find(id) == webviews_.end() || + !base::StringToInt(tokens[2], &x) || !base::StringToInt(tokens[3], &y)) { + LOG(ERROR) << "Usage: [ID] position [X] [Y]"; + return; + } + + const auto& webview = webviews_[id]; + wl_subsurface_set_position(webview->subsurface.get(), x, y); +} + void WebviewClient::TakeExclusiveAccess() { while (wl_display_prepare_read(display_.get()) == -1) { if (wl_display_dispatch_pending(display_.get()) == -1) {
diff --git a/chromecast/browser/webview/client/webview.h b/chromecast/browser/webview/client/webview.h index d81b16f5..7ac400d 100644 --- a/chromecast/browser/webview/client/webview.h +++ b/chromecast/browser/webview/client/webview.h
@@ -5,7 +5,9 @@ #ifndef CHROMECAST_BROWSER_WEBVIEW_CLIENT_WEBVIEW_H_ #define CHROMECAST_BROWSER_WEBVIEW_CLIENT_WEBVIEW_H_ +#include <map> #include <string> +#include <vector> #include "base/files/file_descriptor_watcher_posix.h" #include "base/run_loop.h" @@ -32,7 +34,22 @@ void SchedulePaint(); private: + using WebviewRequestResponseClient = + ::grpc::ClientReaderWriterInterface<chromecast::webview::WebviewRequest, + chromecast::webview::WebviewResponse>; + struct Webview { + Webview(); + ~Webview(); + std::unique_ptr<ClientBase::Buffer> buffer; + std::unique_ptr<wl_surface> surface; + std::unique_ptr<wl_subsurface> subsurface; + std::unique_ptr<WebviewRequestResponseClient> client; + std::unique_ptr<::grpc::ClientContext> context; + }; + void AllocateBuffers(const InitParams& params); + void CreateWebview(const std::vector<std::string>& tokens); + void DestroyWebview(const std::vector<std::string>& tokens); void HandleMode(void* data, struct wl_output* wl_output, uint32_t flags, @@ -40,22 +57,21 @@ int32_t height, int32_t refresh) override; void InputCallback(); + void ListActiveWebviews(); void Paint(); - using WebviewRequestResponseClient = - ::grpc::ClientReaderWriterInterface<chromecast::webview::WebviewRequest, - chromecast::webview::WebviewResponse>; - void SendNavigationRequest(const std::string& URL); + void SendNavigationRequest(const std::vector<std::string>& tokens); + void SendResizeRequest(const std::vector<std::string>& tokens); + void SetPosition(const std::vector<std::string>& tokens); void TakeExclusiveAccess(); void WlDisplayCallback(); - std::unique_ptr<wl_callback> frame_callback_; - std::unique_ptr<wl_callback> subsurface_frame_callback_; - std::unique_ptr<wl_surface> webview_surface_; - std::unique_ptr<wl_subsurface> wl_webview_surface_; - std::unique_ptr<zaura_surface> aura_surface; + int32_t drm_format_ = 0; + int32_t bo_usage_ = 0; + std::map<int, std::unique_ptr<Webview>> webviews_; + + std::unique_ptr<wl_callback> frame_callback_; std::vector<std::unique_ptr<BufferCallback>> buffer_callbacks_; - std::unique_ptr<ClientBase::Buffer> webview_buffer_; const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; std::unique_ptr<base::FileDescriptorWatcher::Controller> stdin_controller_; @@ -65,7 +81,6 @@ base::RunLoop run_loop_; std::unique_ptr<chromecast::webview::PlatformViewsService::Stub> stub_; - std::unique_ptr<WebviewRequestResponseClient> client_; DISALLOW_COPY_AND_ASSIGN(WebviewClient); };
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 5740edcf..f4ba9d0 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -13002.0.0 \ No newline at end of file +13009.0.0 \ No newline at end of file
diff --git a/chromeos/profiles/airmont.afdo.newest.txt b/chromeos/profiles/airmont.afdo.newest.txt index 7df9fd8f..7a9fe22 100644 --- a/chromeos/profiles/airmont.afdo.newest.txt +++ b/chromeos/profiles/airmont.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-airmont-83-4085.6-1584959535-benchmark-83.0.4094.0-r1-redacted.afdo.xz \ No newline at end of file +chromeos-chrome-amd64-airmont-83-4085.6-1584959535-benchmark-83.0.4097.3-r1-redacted.afdo.xz \ No newline at end of file
diff --git a/chromeos/profiles/broadwell.afdo.newest.txt b/chromeos/profiles/broadwell.afdo.newest.txt index 1f42128..4f1762fb 100644 --- a/chromeos/profiles/broadwell.afdo.newest.txt +++ b/chromeos/profiles/broadwell.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-broadwell-83-4044.62-1584958487-benchmark-83.0.4094.0-r1-redacted.afdo.xz \ No newline at end of file +chromeos-chrome-amd64-broadwell-83-4044.62-1584958487-benchmark-83.0.4097.3-r1-redacted.afdo.xz \ No newline at end of file
diff --git a/chromeos/profiles/silvermont.afdo.newest.txt b/chromeos/profiles/silvermont.afdo.newest.txt index 4af967f..c88ada9 100644 --- a/chromeos/profiles/silvermont.afdo.newest.txt +++ b/chromeos/profiles/silvermont.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-silvermont-83-4085.6-1584956258-benchmark-83.0.4094.0-r1-redacted.afdo.xz \ No newline at end of file +chromeos-chrome-amd64-silvermont-83-4085.6-1584956258-benchmark-83.0.4097.3-r1-redacted.afdo.xz \ No newline at end of file
diff --git a/components/metrics/structured/event_base.cc b/components/metrics/structured/event_base.cc index 36e548b..e4e55625 100644 --- a/components/metrics/structured/event_base.cc +++ b/components/metrics/structured/event_base.cc
@@ -9,8 +9,9 @@ namespace metrics { namespace structured { -EventBase::EventBase(uint64_t event_name_hash) - : event_name_hash_(event_name_hash) {} +EventBase::EventBase(uint64_t event_name_hash, uint64_t project_name_hash) + : event_name_hash_(event_name_hash), + project_name_hash_(project_name_hash) {} EventBase::EventBase(const EventBase& other) = default; EventBase::~EventBase() = default;
diff --git a/components/metrics/structured/event_base.h b/components/metrics/structured/event_base.h index ff919d2..d28c0052 100644 --- a/components/metrics/structured/event_base.h +++ b/components/metrics/structured/event_base.h
@@ -54,8 +54,10 @@ uint64_t name_hash() const { return event_name_hash_; } + uint64_t project_name_hash() const { return project_name_hash_; } + protected: - explicit EventBase(uint64_t event_name_hash); + explicit EventBase(uint64_t event_name_hash, uint64_t project_name_hash); void AddStringMetric(uint64_t name_hash, const std::string& value); @@ -65,6 +67,20 @@ // First 8 bytes of the MD5 hash of the event name, as defined in // structured.xml. This is calculated by tools/metrics/structured/codegen.py. uint64_t event_name_hash_; + + // The project name hash is used to to determine which key to use for hashing + // events. The project name comes from this event's definition in + // structured.xml, and is decided by the rules: + // + // - if this event references a project, eg. <event name="..." + // project="...">, use that project's name. + // + // - otherwise, use the event's name. + // + // |project_name_hash_| is the first 8 bytes of the MD5 hash of the project + // name. + uint64_t project_name_hash_; + std::vector<Metric> metrics_; };
diff --git a/components/metrics/structured/key_data.cc b/components/metrics/structured/key_data.cc index 001a2bd..b5954ad 100644 --- a/components/metrics/structured/key_data.cc +++ b/components/metrics/structured/key_data.cc
@@ -63,34 +63,35 @@ KeyData::~KeyData() = default; -base::Optional<std::string> KeyData::ValidateAndGetKey(const uint64_t event) { +base::Optional<std::string> KeyData::ValidateAndGetKey( + const uint64_t project_name_hash) { DCHECK(key_store_); const int now = (base::Time::Now() - base::Time::UnixEpoch()).InDays(); bool key_is_valid = true; - // If the key for |key_path| doesn't exist, initialize new key data. Set the - // last rotation to a uniformly selected day between today and + // If the key for |project_name_hash| doesn't exist, initialize new key data. + // Set the last rotation to a uniformly selected day between today and // |kDefaultRotationPeriod| days ago, to uniformly distribute users amongst // rotation cohorts. - if (!key_store_->GetValue(KeyPath(event), nullptr)) { + if (!key_store_->GetValue(KeyPath(project_name_hash), nullptr)) { const int rotation_seed = base::RandInt(0, kDefaultRotationPeriod - 1); - SetRotationPeriod(event, kDefaultRotationPeriod); - SetLastRotation(event, now - rotation_seed); - SetKey(event, GenerateKey()); + SetRotationPeriod(project_name_hash, kDefaultRotationPeriod); + SetLastRotation(project_name_hash, now - rotation_seed); + SetKey(project_name_hash, GenerateKey()); LogKeyValidation(KeyValidationState::kCreated); key_is_valid = false; } - // If the key for |event| is outdated, generate a new key and write it to - // the |keys| pref store along with updated rotation data. Update the last - // rotation such that the user stays in the same cohort. - const int rotation_period = GetRotationPeriod(event); - const int last_rotation = GetLastRotation(event); + // If the key for |project_name_hash| is outdated, generate a new key and + // write it to the |keys| pref store along with updated rotation data. Update + // the last rotation such that the user stays in the same cohort. + const int rotation_period = GetRotationPeriod(project_name_hash); + const int last_rotation = GetLastRotation(project_name_hash); if (now - last_rotation > rotation_period) { const int new_last_rotation = now - (now - last_rotation) % rotation_period; - SetLastRotation(event, new_last_rotation); - SetKey(event, GenerateKey()); + SetLastRotation(project_name_hash, new_last_rotation); + SetKey(project_name_hash, GenerateKey()); LogKeyValidation(KeyValidationState::kRotated); key_is_valid = false; @@ -101,7 +102,7 @@ } const base::Value* key_json; - if (!(key_store_->GetValue(KeyPath(event), &key_json) && + if (!(key_store_->GetValue(KeyPath(project_name_hash), &key_json) && key_json->is_string())) { LogInternalError(StructuredMetricsError::kMissingKey); return base::nullopt; @@ -117,8 +118,9 @@ } void KeyData::ValidateKeys() { - for (const uint64_t event : metrics::structured::events::kEventNameHashes) { - ValidateAndGetKey(event); + for (const uint64_t project_name_hash : + metrics::structured::events::kProjectNameHashes) { + ValidateAndGetKey(project_name_hash); } } @@ -135,8 +137,8 @@ WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); } -void KeyData::SetKey(const uint64_t event, const std::string& key) { - return key_store_->SetValue(KeyPath(event), +void KeyData::SetKey(const uint64_t project_name_hash, const std::string& key) { + return key_store_->SetValue(KeyPath(project_name_hash), std::make_unique<base::Value>(key), WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); } @@ -163,9 +165,9 @@ return value->GetInt(); } -uint64_t KeyData::UserEventId(const uint64_t event) { +uint64_t KeyData::UserEventId(const uint64_t project_name_hash) { // Retrieve the key for |event|. - const base::Optional<std::string> key = ValidateAndGetKey(event); + const base::Optional<std::string> key = ValidateAndGetKey(project_name_hash); if (!key) { NOTREACHED(); return 0u; @@ -177,11 +179,11 @@ return hash; } -uint64_t KeyData::HashForEventMetric(const uint64_t event, +uint64_t KeyData::HashForEventMetric(const uint64_t project_name_hash, const uint64_t metric, const std::string& value) { - // Retrieve the key for |event|. - const base::Optional<std::string> key = ValidateAndGetKey(event); + // Retrieve the key for |project_name_hash|. + const base::Optional<std::string> key = ValidateAndGetKey(project_name_hash); if (!key) { NOTREACHED(); return 0u;
diff --git a/components/metrics/structured/key_data.h b/components/metrics/structured/key_data.h index a601b32..3c13603 100644 --- a/components/metrics/structured/key_data.h +++ b/components/metrics/structured/key_data.h
@@ -55,30 +55,30 @@ KeyData(const KeyData&) = delete; KeyData& operator=(const KeyData&) = delete; - // Returns a digest of |value| for |metric| in the context of |event|. - // Terminology: a metric is a (name, value) pair, and an event is a bundle of - // metrics. + // Returns a digest of |value| for |metric| in the context of + // |project_name_hash|. Terminology: a metric is a (name, value) pair, and an + // event is a bundle of metrics. // - // - |event| is the uint64 name hash of an event. - // - |metric| is the uint64 name hash of a metric within |event|. + // - |project_name_hash| is the uint64 name hash of an event or project. + // - |metric| is the uint64 name hash of a metric within |project_name_hash|. // - |value| is the string value to hash. // // The result is the HMAC digest of the |value| salted with |metric|, using - // the key for |event|. That is: + // the key for |project_name_hash|. That is: // - // HMAC_SHA256(key(event), concat(value, hex(metric))) + // HMAC_SHA256(key(project_name_hash), concat(value, hex(metric))) // // Returns 0u in case of an error. - uint64_t HashForEventMetric(uint64_t event, + uint64_t HashForEventMetric(uint64_t project_name_hash, uint64_t metric, const std::string& value); - // Returns an ID for this (user, |event|) pair. |event| is the name of an - // event, represented by the first 8 bytes of the MD5 hash of its name defined - // in structured.xml. + // Returns an ID for this (user, |project_name_hash|) pair. + // |project_name_hash| is the name of an event or project, represented by the + // first 8 bytes of the MD5 hash of its name defined in structured.xml. // - // The derived ID is the first 8 bytes of SHA256(key(event)). Returns 0u in - // case of an error. + // The derived ID is the first 8 bytes of SHA256(key(project_name_hash)). + // Returns 0u in case of an error. // // This ID is intended as the only ID for a particular structured metrics // event. However, events are uploaded from the device alongside the UMA @@ -86,7 +86,7 @@ // means events are associated with the client ID when uploaded from the // device. See the class comment of StructuredMetricsProvider for more // details. - uint64_t UserEventId(uint64_t event); + uint64_t UserEventId(uint64_t project_name_hash); private: int GetRotationPeriod(uint64_t event); @@ -97,7 +97,7 @@ // Ensure that a valid key exists for |event|, and return it. Either returns a // string of size |kKeySize| or base::nullopt, which indicates an error. - base::Optional<std::string> ValidateAndGetKey(uint64_t event); + base::Optional<std::string> ValidateAndGetKey(uint64_t project_name_hash); void SetKey(uint64_t event, const std::string& key); // Ensure that valid keys exist for all events.
diff --git a/components/metrics/structured/key_data_unittest.cc b/components/metrics/structured/key_data_unittest.cc index 81bc4b4..8165d96 100644 --- a/components/metrics/structured/key_data_unittest.cc +++ b/components/metrics/structured/key_data_unittest.cc
@@ -45,6 +45,8 @@ constexpr uint64_t kEventOneHash = UINT64_C(15619026293081468407); // The name hash of "TestEventTwo". constexpr uint64_t kEventTwoHash = UINT64_C(15791833939776536363); +// The name hash of "TestProject". +constexpr uint64_t kProjectHash = UINT64_C(17426425568333718899); // The name hash of "TestMetricOne". constexpr uint64_t kMetricOneHash = UINT64_C(637929385654885975); @@ -83,7 +85,7 @@ // Returns the total number of events registered in structured.xml. This is used // to determine how many keys we expect to load or rotate on initialization. int NumberOfEvents() { - return sizeof(metrics::structured::events::kEventNameHashes) / + return sizeof(metrics::structured::events::kProjectNameHashes) / sizeof(uint64_t); } @@ -186,7 +188,7 @@ NumberOfEvents()); const std::string key_one = GetString(KeyPath(kEventOneHash)); - const std::string key_two = GetString(KeyPath(kEventTwoHash)); + const std::string key_two = GetString(KeyPath(kProjectHash)); EXPECT_EQ(key_one.size(), 32ul); EXPECT_EQ(key_two.size(), 32ul);
diff --git a/components/metrics/structured/structured_metrics_provider.cc b/components/metrics/structured/structured_metrics_provider.cc index c7e56bc0..b91964c 100644 --- a/components/metrics/structured/structured_metrics_provider.cc +++ b/components/metrics/structured/structured_metrics_provider.cc
@@ -77,9 +77,9 @@ // Store hashed values as strings, because the JSON parser only retains 53 // bits of precision for ints. This would corrupt the hashes. name_value.SetStringKey( - "value", - base::NumberToString(key_data_->HashForEventMetric( - event.name_hash(), metric.name_hash, metric.string_value))); + "value", base::NumberToString(key_data_->HashForEventMetric( + event.project_name_hash(), metric.name_hash, + metric.string_value))); } else if (metric.type == EventBase::MetricType::kInt) { name_value.SetIntKey("value", metric.int_value); } @@ -87,9 +87,13 @@ metrics.Append(std::move(name_value)); } - // Create an event value containing the metrics and the event name hash. + // Create an event value containing the metrics, the event name hash, and the + // ID that will eventually be used as the profile_event_id of this event. base::Value event_value(base::Value::Type::DICTIONARY); event_value.SetStringKey("name", base::NumberToString(event.name_hash())); + event_value.SetStringKey( + "id", + base::NumberToString(key_data_->UserEventId(event.project_name_hash()))); event_value.SetKey("metrics", std::move(metrics)); // Add the event to |storage_|. @@ -178,7 +182,14 @@ continue; } event_proto->set_event_name_hash(event_name_hash); - event_proto->set_profile_event_id(key_data_->UserEventId(event_name_hash)); + + uint64_t user_event_id; + if (!base::StringToUint64(event.FindKey("id")->GetString(), + &user_event_id)) { + LogInternalError(StructuredMetricsError::kFailedUintConversion); + continue; + } + event_proto->set_profile_event_id(user_event_id); for (const auto& metric : event.FindKey("metrics")->GetList()) { auto* metric_proto = event_proto->add_metrics();
diff --git a/components/metrics/structured/structured_metrics_provider_unittest.cc b/components/metrics/structured/structured_metrics_provider_unittest.cc index edccd45..c00caeb 100644 --- a/components/metrics/structured/structured_metrics_provider_unittest.cc +++ b/components/metrics/structured/structured_metrics_provider_unittest.cc
@@ -35,7 +35,8 @@ // To test that the right values are calculated for hashed metrics, we need to // set up some fake keys that we know the output hashes for. kKeyData contains // the JSON for a simple structured_metrics.json file with keys for the test -// events. +// events. The two keys are ID'd by the name hashes of "TestEventOne" and +// "TestProject", because TestEventTwo is associated with TestProject. // TODO(crbug.com/1016655): Once custom rotation periods have been implemented, // change the large constants to 0. constexpr char kKeyData[] = R"({ @@ -45,7 +46,7 @@ "last_rotation":1000000, "key":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }, - "15791833939776536363":{ + "17426425568333718899":{ "rotation_period":1000000, "last_rotation":1000000, "key":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" @@ -276,7 +277,7 @@ const auto& metric = event.metrics(0); EXPECT_EQ(metric.name_hash(), kMetricThreeHash); EXPECT_EQ(HashToHex(metric.value_hmac()), - // Value of HMAC_256("bbb...b", concat(hex(kMetricOneHash), + // Value of HMAC_256("bbb...b", concat(hex(kProjectHash), // "value three")) "86F0169868588DC7"); }
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 838877b..c9d3b0f 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -5392,7 +5392,9 @@ If this policy is left not set the global default value will be used for all sites either from the 'DefaultWebUsbGuardSetting' policy if it is set, or the user's personal configuration otherwise. - URL patterns in this policy should not clash with ones configured via WebUsbBlockedForUrls. It is unspecified which of the two policies takes precedence if a URL matches with both.''', + URL patterns in this policy should not clash with ones configured via WebUsbBlockedForUrls. It is unspecified which of the two policies takes precedence if a URL matches with both. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'WebUsbBlockedForUrls', @@ -5415,7 +5417,9 @@ If this policy is left not set the global default value will be used for all sites either from the 'DefaultWebUsbGuardSetting' policy if it is set, or the user's personal configuration otherwise. - URL patterns in this policy should not clash with ones configured via WebUsbAskForUrls. It is unspecified which of the two policies takes precedence if a URL matches with both.''', + URL patterns in this policy should not clash with ones configured via WebUsbAskForUrls. It is unspecified which of the two policies takes precedence if a URL matches with both. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'AutoSelectCertificateForUrls', @@ -5508,7 +5512,9 @@ The value must be an array of stringified JSON dictionaries. Each dictionary must have the form <ph name="DEVICE_LOGIN_SCREEN_AUTO_SELECT_CERTIFICATE_FOR_URLS_EXAMPLE">'{ "pattern": "$URL_PATTERN", "filter" : $FILTER }'</ph>, where <ph name="URL_PATTERN_PLACEHOLDER">$URL_PATTERN</ph> is a content setting pattern. <ph name="FILTER_PLACEHOLDER">$FILTER</ph> restricts from which client certificates the browser will automatically select. Independent of the filter, only certificates will be selected that match the server's certificate request. If <ph name="FILTER_PLACEHOLDER">$FILTER</ph> has the form <ph name="JSON_DICTIONARY_EXAMPLE">'{ "ISSUER": { "CN": "$ISSUER_CN" } }'</ph>, additionally only client certificates are selected that are issued by a certificate with the CommonName <ph name="ISSUER_CN_PLACEHOLDER">$ISSUER_CN</ph>. If <ph name="FILTER_PLACEHOLDER">$FILTER</ph> is the empty dictionary {}, the selection of client certificates is not additionally restricted. - If this policy is left not set, no auto-selection will be done for any site.''', + If this policy is left not set, no auto-selection will be done for any site. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'CookiesAllowedForUrls', @@ -5535,7 +5541,9 @@ If this policy is left not set the global default value will be used for all sites either from the 'DefaultCookiesSetting' policy if it is set, or the user's personal configuration otherwise. - See also policies 'CookiesBlockedForUrls' and 'CookiesSessionOnlyForUrls'. Note that there must be no conflicting URL patterns between these three policies - it is unspecified which policy takes precedence.''', + See also policies 'CookiesBlockedForUrls' and 'CookiesSessionOnlyForUrls'. Note that there must be no conflicting URL patterns between these three policies - it is unspecified which policy takes precedence. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'CookiesBlockedForUrls', @@ -5562,7 +5570,9 @@ If this policy is left not set the global default value will be used for all sites either from the 'DefaultCookiesSetting' policy if it is set, or the user's personal configuration otherwise. - See also policies 'CookiesAllowedForUrls' and 'CookiesSessionOnlyForUrls'. Note that there must be no conflicting URL patterns between these three policies - it is unspecified which policy takes precedence.''', + See also policies 'CookiesAllowedForUrls' and 'CookiesSessionOnlyForUrls'. Note that there must be no conflicting URL patterns between these three policies - it is unspecified which policy takes precedence. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'CookiesSessionOnlyForUrls', @@ -5593,7 +5603,9 @@ See also policies 'CookiesAllowedForUrls' and 'CookiesBlockedForUrls'. Note that there must be no conflicting URL patterns between these three policies - it is unspecified which policy takes precedence. - If the "RestoreOnStartup" policy is set to restore URLs from previous sessions this policy will not be respected and cookies will be stored permanently for those sites.''', + If the "RestoreOnStartup" policy is set to restore URLs from previous sessions this policy will not be respected and cookies will be stored permanently for those sites. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'ImagesAllowedForUrls', @@ -5616,7 +5628,9 @@ If this policy is left not set the global default value will be used for all sites either from the 'DefaultImagesSetting' policy if it is set, or the user's personal configuration otherwise. - Note that previously this policy was erroneously enabled on Android, but this functionality has never been fully supported on Android.''', + Note that previously this policy was erroneously enabled on Android, but this functionality has never been fully supported on Android. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'ImagesBlockedForUrls', @@ -5639,7 +5653,9 @@ If this policy is left not set the global default value will be used for all sites either from the 'DefaultImagesSetting' policy if it is set, or the user's personal configuration otherwise. - Note that previously this policy was erroneously enabled on Android, but this functionality has never been fully supported on Android.''', + Note that previously this policy was erroneously enabled on Android, but this functionality has never been fully supported on Android. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'JavaScriptAllowedForUrls', @@ -5660,7 +5676,9 @@ 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to run JavaScript. - If this policy is left not set the global default value will be used for all sites either from the 'DefaultJavaScriptSetting' policy if it is set, or the user's personal configuration otherwise.''', + If this policy is left not set the global default value will be used for all sites either from the 'DefaultJavaScriptSetting' policy if it is set, or the user's personal configuration otherwise. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'JavaScriptBlockedForUrls', @@ -5681,7 +5699,9 @@ 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to run JavaScript. - If this policy is left not set the global default value will be used for all sites either from the 'DefaultJavaScriptSetting' policy if it is set, or the user's personal configuration otherwise.''', + If this policy is left not set the global default value will be used for all sites either from the 'DefaultJavaScriptSetting' policy if it is set, or the user's personal configuration otherwise. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'KeygenAllowedForUrls', @@ -5702,7 +5722,9 @@ 'tags': ['system-security', 'website-sharing', 'local-data-access'], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to use key generation. If a url pattern is in 'KeygenBlockedForUrls', that overrides these exceptions. - If this policy is left not set the global default value will be used for all sites either from the 'DefaultKeygenSetting' policy if it is set, or the user's personal configuration otherwise.''', + If this policy is left not set the global default value will be used for all sites either from the 'DefaultKeygenSetting' policy if it is set, or the user's personal configuration otherwise. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'KeygenBlockedForUrls', @@ -5723,7 +5745,9 @@ 'tags': ['system-security', 'website-sharing', 'local-data-access'], 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to use key generation. If a url pattern is in 'KeygenAllowedForUrls', this policy overrides these exceptions. - If this policy is left not set the global default value will be used for all sites either from the 'DefaultKeygenSetting' policy if it is set, or the user's personal configuration otherwise.''', + If this policy is left not set the global default value will be used for all sites either from the 'DefaultKeygenSetting' policy if it is set, or the user's personal configuration otherwise. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'LegacySameSiteCookieBehaviorEnabled', @@ -5808,7 +5832,9 @@ 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to run the <ph name="FLASH_PLUGIN_NAME">Flash</ph> plugin. - If this policy is left not set the global default value will be used for all sites either from the 'DefaultPluginsSetting' policy if it is set, or the user's personal configuration otherwise.''', + If this policy is left not set the global default value will be used for all sites either from the 'DefaultPluginsSetting' policy if it is set, or the user's personal configuration otherwise. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'PluginsBlockedForUrls', @@ -5829,7 +5855,9 @@ 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to run the <ph name="FLASH_PLUGIN_NAME">Flash</ph> plugin. - If this policy is left not set the global default value will be used for all sites either from the 'DefaultPluginsSetting' policy if it is set, or the user's personal configuration otherwise.''', + If this policy is left not set the global default value will be used for all sites either from the 'DefaultPluginsSetting' policy if it is set, or the user's personal configuration otherwise. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'PopupsAllowedForUrls', @@ -5854,7 +5882,9 @@ 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to open popups. - If this policy is left not set the global default value will be used for all sites either from the 'DefaultPopupsSetting' policy if it is set, or the user's personal configuration otherwise.''', + If this policy is left not set the global default value will be used for all sites either from the 'DefaultPopupsSetting' policy if it is set, or the user's personal configuration otherwise. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'RegisteredProtocolHandlers', @@ -5920,7 +5950,9 @@ 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to open popups. - If this policy is left not set the global default value will be used for all sites either from the 'DefaultPopupsSetting' policy if it is set, or the user's personal configuration otherwise.''', + If this policy is left not set the global default value will be used for all sites either from the 'DefaultPopupsSetting' policy if it is set, or the user's personal configuration otherwise. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'NotificationsAllowedForUrls', @@ -5941,7 +5973,9 @@ 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to display notifications. - If this policy is left not set the global default value will be used for all sites either from the 'DefaultNotificationsSetting' policy if it is set, or the user's personal configuration otherwise.''', + If this policy is left not set the global default value will be used for all sites either from the 'DefaultNotificationsSetting' policy if it is set, or the user's personal configuration otherwise. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'NotificationsBlockedForUrls', @@ -5962,7 +5996,9 @@ 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to display notifications. - If this policy is left not set the global default value will be used for all sites either from the 'DefaultNotificationsSetting' policy if it is set, or the user's personal configuration otherwise.''', + If this policy is left not set the global default value will be used for all sites either from the 'DefaultNotificationsSetting' policy if it is set, or the user's personal configuration otherwise. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'NativeMessagingBlacklist', @@ -9081,6 +9117,8 @@ origin of the requesting URL. If a match is found, access to audio capture devices will be granted without prompt. + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. + NOTE: Until version 45, this policy was only supported in Kiosk mode.''', }, { @@ -9127,6 +9165,8 @@ origin of the requesting URL. If a match is found, access to video capture devices will be granted without prompt. + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns. + NOTE: Until version 45, this policy was only supported in Kiosk mode.''', }, { @@ -15931,27 +15971,13 @@ If autoplay is enabled then videos can play automatically (without user consent) with audio content in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. - A valid URL patterns specifications are: - - - [*.]domain.tld (matches domain.tld and all sub-domains) - - - host (matches an exact hostname) - - - scheme://host:port (supported schemes: http,https) - - - scheme://[*.]domain.tld:port (supported schemes: http,https) - - - file://path (The path has to be an absolute path and start with a '/') - - - a.b.c.d (matches an exact IPv4 ip) - - - [a:b:c:d:e:f:g:h] (matches an exact IPv6 ip) - If the AutoplayAllowed policy is set to True then this policy will have no effect. If the AutoplayAllowed policy is set to False then any URL patterns set in this policy will still be allowed to play. - Note that if <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is running and this policy changes, it will be applied only to new opened tabs. Therefore some tabs might still observe the previous behavior.''', + Note that if <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is running and this policy changes, it will be applied only to new opened tabs. Therefore some tabs might still observe the previous behavior. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'TabUnderAllowed', @@ -19539,7 +19565,9 @@ 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are allowed to display blockable (i.e. active) mixed content (i.e. HTTP content on HTTPS sites) and for which optionally blockable mixed content upgrades will be disabled. - If this policy is left not set blockable mixed content will be blocked and optionally blockable mixed content will be upgraded, and users will be allowed to set exceptions to allow it for specific sites.''', + If this policy is left not set blockable mixed content will be blocked and optionally blockable mixed content will be upgraded, and users will be allowed to set exceptions to allow it for specific sites. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'InsecureContentBlockedForUrls', @@ -19560,7 +19588,9 @@ 'tags': [], 'desc': '''Allows you to set a list of url patterns that specify sites which are not allowed to display blockable (i.e. active) mixed content (i.e. HTTP content on HTTPS sites), and for which optionally blockable (i.e. passive) mixed content will be upgraded. - If this policy is left not set blockable mixed content will be blocked and optionally blockable mixed content will be upgraded, but users will be allowed to set exceptions to allow it for specific sites.''', + If this policy is left not set blockable mixed content will be blocked and optionally blockable mixed content will be upgraded, but users will be allowed to set exceptions to allow it for specific sites. + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''', }, { 'name': 'DeviceWebBasedAttestationAllowedUrls', @@ -19586,7 +19616,9 @@ If this policy is not set or is set to an empty list, no URL is allowed to use remote attestation on the sign-in screen. - URLs must have HTTPS scheme, e.g. "https://example.com".''' + URLs must have HTTPS scheme, e.g. "https://example.com". + + For detailed information on valid url patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''' }, { 'name': 'DeviceShowNumericKeyboardForPassword',
diff --git a/components/security_interstitials/core/ssl_error_ui.cc b/components/security_interstitials/core/ssl_error_ui.cc index eb830c2..c83a9418 100644 --- a/components/security_interstitials/core/ssl_error_ui.cc +++ b/components/security_interstitials/core/ssl_error_ui.cc
@@ -5,6 +5,7 @@ #include "components/security_interstitials/core/ssl_error_ui.h" #include "base/i18n/time_formatting.h" +#include "build/build_config.h" #include "components/security_interstitials/core/common_string_util.h" #include "components/security_interstitials/core/metrics_helper.h" #include "components/security_interstitials/core/ssl_error_options_mask.h" @@ -124,6 +125,18 @@ load_time_data->SetString( "primaryButtonText", l10n_util::GetStringUTF16(IDS_SSL_OVERRIDABLE_SAFETY_BUTTON)); + +// On iOS, offer to close the page instead of navigating to NTP when unable to +// go back. See crbug.com/1058476 for discussion. +#if defined(OS_IOS) + if (!controller()->CanGoBack()) { + load_time_data->SetString( + "primaryButtonText", + l10n_util::GetStringUTF16(IDS_SSL_OVERRIDABLE_CLOSE_PAGE_BUTTON)); + load_time_data->SetBoolean("primary_button_close_page", true); + } +#endif + load_time_data->SetString( "finalParagraph", l10n_util::GetStringFUTF16(IDS_SSL_OVERRIDABLE_PROCEED_PARAGRAPH, url));
diff --git a/components/security_interstitials_strings.grdp b/components/security_interstitials_strings.grdp index 4d96153d..c24f6208 100644 --- a/components/security_interstitials_strings.grdp +++ b/components/security_interstitials_strings.grdp
@@ -140,6 +140,9 @@ <message name="IDS_SSL_OVERRIDABLE_SAFETY_BUTTON" desc="The text for the button that takes the user back to the previous page."> Back to safety </message> + <message name="IDS_SSL_OVERRIDABLE_CLOSE_PAGE_BUTTON" desc="The text for the button that closes the page."> + Close page + </message> <message name="IDS_SSL_OVERRIDABLE_PROCEED_PARAGRAPH" desc="The text for the paragraph at the bottom with the proceed link."> <ph name="BEGIN_LINK"><a href="#" id="proceed-link"></ph>Proceed to <ph name="SITE">$1<ex>example.com</ex></ph> (unsafe)<ph name="END_LINK"></a></ph> </message>
diff --git a/components/security_interstitials_strings_grdp/IDS_SSL_OVERRIDABLE_CLOSE_PAGE_BUTTON.png.sha1 b/components/security_interstitials_strings_grdp/IDS_SSL_OVERRIDABLE_CLOSE_PAGE_BUTTON.png.sha1 new file mode 100644 index 0000000..1f51f7c --- /dev/null +++ b/components/security_interstitials_strings_grdp/IDS_SSL_OVERRIDABLE_CLOSE_PAGE_BUTTON.png.sha1
@@ -0,0 +1 @@ +cecf925e113e7300de0685e91673825a40ede63f \ No newline at end of file
diff --git a/content/browser/accessibility/accessibility_action_browsertest.cc b/content/browser/accessibility/accessibility_action_browsertest.cc index 323ee349..875f7da 100644 --- a/content/browser/accessibility/accessibility_action_browsertest.cc +++ b/content/browser/accessibility/accessibility_action_browsertest.cc
@@ -2,7 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <string> + #include "base/logging.h" +#include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "content/browser/accessibility/browser_accessibility.h" #include "content/browser/accessibility/browser_accessibility_manager.h" @@ -104,10 +107,16 @@ BrowserAccessibility* FindNodeInSubtree(BrowserAccessibility& node, ax::mojom::Role role, const std::string& name_or_value) { - const auto& name = + const std::string& name = node.GetStringAttribute(ax::mojom::StringAttribute::kName); - const auto& value = - node.GetStringAttribute(ax::mojom::StringAttribute::kValue); + // Note that in the case of a text field, "BrowserAccessibility::GetValue" + // has the added functionality of computing the value of an ARIA text box + // from its inner text. + // + // <div contenteditable="true" role="textbox">Hello world.</div> + // Will expose no HTML value attribute, but some screen readers, such as + // Jaws, VoiceOver and Talkback, require one to be computed. + const std::string& value = base::UTF16ToUTF8(node.GetValue()); if (node.GetRole() == role && (name == name_or_value || value == name_or_value)) { return &node;
diff --git a/content/browser/accessibility/accessibility_content_browsertest.cc b/content/browser/accessibility/accessibility_content_browsertest.cc index d556075..302d73b 100644 --- a/content/browser/accessibility/accessibility_content_browsertest.cc +++ b/content/browser/accessibility/accessibility_content_browsertest.cc
@@ -4,6 +4,9 @@ #include "content/browser/accessibility/accessibility_content_browsertest.h" +#include <string> + +#include "base/strings/utf_string_conversions.h" #include "content/browser/accessibility/browser_accessibility.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -108,10 +111,16 @@ BrowserAccessibility* node, const ax::mojom::Role role, const std::string& name_or_value) const { - const auto& name = + const std::string& name = node->GetStringAttribute(ax::mojom::StringAttribute::kName); - const auto& value = - node->GetStringAttribute(ax::mojom::StringAttribute::kValue); + // Note that in the case of a text field, "BrowserAccessibility::GetValue" has + // the added functionality of computing the value of an ARIA text box from its + // inner text. + // + // <div contenteditable="true" role="textbox">Hello world.</div> + // Will expose no HTML value attribute, but some screen readers, such as Jaws, + // VoiceOver and Talkback, require one to be computed. + const std::string& value = base::UTF16ToUTF8(node->GetValue()); if (node->GetRole() == role && (name == name_or_value || value == name_or_value)) { return node;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_android.cc b/content/browser/accessibility/accessibility_tree_formatter_android.cc index 6c4138d..908aabd 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_android.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_android.cc
@@ -131,7 +131,7 @@ dict->SetBoolean("collection_item", android_node->IsCollectionItem()); dict->SetBoolean("disabled", !android_node->IsEnabled()); dict->SetBoolean("dismissable", android_node->IsDismissable()); - dict->SetBoolean("editable_text", android_node->IsEditableText()); + dict->SetBoolean("editable_text", android_node->IsTextField()); dict->SetBoolean("focusable", android_node->IsFocusable()); dict->SetBoolean("focused", android_node->IsFocused()); dict->SetBoolean("has_character_locations", @@ -144,7 +144,7 @@ dict->SetBoolean("link", android_node->IsLink()); dict->SetBoolean("multiline", android_node->IsMultiLine()); dict->SetBoolean("range", android_node->IsRangeType()); - dict->SetBoolean("password", android_node->IsPassword()); + dict->SetBoolean("password", android_node->IsPasswordField()); dict->SetBoolean("scrollable", android_node->IsScrollable()); dict->SetBoolean("selected", android_node->IsSelected()); dict->SetBoolean("interesting", android_node->IsInterestingOnAndroid());
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc index 320407c..7e99ae13 100644 --- a/content/browser/accessibility/accessibility_win_browsertest.cc +++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -112,12 +112,13 @@ const std::wstring& expected_name, int32_t depth, bool* found); - static void CheckTextAtOffset(Microsoft::WRL::ComPtr<IAccessibleText>& object, - LONG offset, - IA2TextBoundaryType boundary_type, - LONG expected_start_offset, - LONG expected_end_offset, - const std::wstring& expected_text); + static void CheckTextAtOffset( + const Microsoft::WRL::ComPtr<IAccessibleText>& object, + LONG offset, + IA2TextBoundaryType boundary_type, + LONG expected_start_offset, + LONG expected_end_offset, + const std::wstring& expected_text); static std::vector<base::win::ScopedVariant> GetAllAccessibleChildren( IAccessible* element); @@ -466,8 +467,8 @@ const std::string& name_or_value) { const std::string& name = node.GetStringAttribute(ax::mojom::StringAttribute::kName); - // Note that "BrowserAccessibility::GetValue" has the - // added functionality of computing the value of an ARIA text box from its + // Note that in the case of a text field, "BrowserAccessibility::GetValue" has + // the added functionality of computing the value of an ARIA text box from its // inner text. // // <div contenteditable="true" role="textbox">Hello world.</div> @@ -573,7 +574,7 @@ // Ensures that the text and the start and end offsets retrieved using // get_textAtOffset match the expected values. void AccessibilityWinBrowserTest::CheckTextAtOffset( - Microsoft::WRL::ComPtr<IAccessibleText>& object, + const Microsoft::WRL::ComPtr<IAccessibleText>& object, LONG offset, IA2TextBoundaryType boundary_type, LONG expected_start_offset,
diff --git a/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc b/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc index 55a4409..b741fa3e 100644 --- a/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc +++ b/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc
@@ -5,6 +5,7 @@ #include "ui/accessibility/platform/ax_platform_node_textprovider_win.h" #include "ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h" +#include "base/strings/utf_string_conversions.h" #include "base/win/scoped_bstr.h" #include "base/win/scoped_safearray.h" #include "base/win/scoped_variant.h" @@ -126,10 +127,16 @@ BrowserAccessibility* FindNodeInSubtree(BrowserAccessibility& node, ax::mojom::Role role, const std::string& name_or_value) { - const auto& name = + const std::string& name = node.GetStringAttribute(ax::mojom::StringAttribute::kName); - const auto& value = - node.GetStringAttribute(ax::mojom::StringAttribute::kValue); + // Note that in the case of a text field, "BrowserAccessibility::GetValue" + // has the added functionality of computing the value of an ARIA text box + // from its inner text. + // + // <div contenteditable="true" role="textbox">Hello world.</div> + // Will expose no HTML value attribute, but some screen readers, such as + // Jaws, VoiceOver and Talkback, require one to be computed. + const std::string& value = base::UTF16ToUTF8(node.GetValue()); if (node.GetRole() == role && (name == name_or_value || value == name_or_value)) { return &node;
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index ae2c706..97c7346c 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -13,6 +13,7 @@ #include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "content/public/common/content_client.h" @@ -395,7 +396,7 @@ } uint32_t BrowserAccessibility::InternalChildCount() const { - if (!node_ || !manager_) + if (!instance_active()) return 0; return node_->GetUnignoredChildCount(); } @@ -404,7 +405,7 @@ uint32_t child_index) const { if (!node_ || !manager_) return nullptr; - auto* child_node = node_->GetUnignoredChildAtIndex(child_index); + ui::AXNode* child_node = node_->GetUnignoredChildAtIndex(child_index); if (!child_node) return nullptr; @@ -414,7 +415,7 @@ BrowserAccessibility* BrowserAccessibility::InternalGetParent() const { if (!node_ || !manager_) return nullptr; - auto* child_node = node_->GetUnignoredParent(); + ui::AXNode* child_node = node_->GetUnignoredParent(); if (!child_node) return nullptr; @@ -426,7 +427,7 @@ } BrowserAccessibility* BrowserAccessibility::InternalGetLastChild() const { - auto* child_node = node_->GetLastUnignoredChild(); + ui::AXNode* child_node = node_->GetLastUnignoredChild(); if (!child_node) return nullptr; @@ -434,7 +435,7 @@ } BrowserAccessibility* BrowserAccessibility::InternalGetNextSibling() const { - auto* child_node = node_->GetNextUnignoredSibling(); + ui::AXNode* child_node = node_->GetNextUnignoredSibling(); if (!child_node) return nullptr; @@ -442,7 +443,7 @@ } BrowserAccessibility* BrowserAccessibility::InternalGetPreviousSibling() const { - auto* child_node = node_->GetPreviousUnignoredSibling(); + ui::AXNode* child_node = node_->GetPreviousUnignoredSibling(); if (!child_node) return nullptr; @@ -1519,7 +1520,7 @@ } gfx::NativeViewAccessible BrowserAccessibility::ChildAtIndex(int index) { - auto* child = PlatformGetChild(index); + BrowserAccessibility* child = PlatformGetChild(index); if (!child) return nullptr; @@ -1527,7 +1528,7 @@ } gfx::NativeViewAccessible BrowserAccessibility::GetFirstChild() { - auto* child = PlatformGetFirstChild(); + BrowserAccessibility* child = PlatformGetFirstChild(); if (!child) return nullptr; @@ -1535,7 +1536,7 @@ } gfx::NativeViewAccessible BrowserAccessibility::GetLastChild() { - auto* child = PlatformGetLastChild(); + BrowserAccessibility* child = PlatformGetLastChild(); if (!child) return nullptr; @@ -1543,7 +1544,7 @@ } gfx::NativeViewAccessible BrowserAccessibility::GetNextSibling() { - auto* sibling = PlatformGetNextSibling(); + BrowserAccessibility* sibling = PlatformGetNextSibling(); if (!sibling) return nullptr; @@ -1551,7 +1552,7 @@ } gfx::NativeViewAccessible BrowserAccessibility::GetPreviousSibling() { - auto* sibling = PlatformGetPreviousSibling(); + BrowserAccessibility* sibling = PlatformGetPreviousSibling(); if (!sibling) return nullptr; @@ -2236,7 +2237,7 @@ int start_offset = 0; for (BrowserAccessibility::PlatformChildIterator it = PlatformChildrenBegin(); it != PlatformChildrenEnd(); ++it) { - auto* child = it.get(); + BrowserAccessibility* child = it.get(); DCHECK(child); ui::TextAttributeList attributes(child->ComputeTextAttributes());
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index 79221e2..ee842a24 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -108,8 +108,6 @@ bool IsDocument() const; - bool IsEditField() const; - bool IsIgnored() const; // Returns true if this object is used only for representing text. @@ -256,8 +254,19 @@ const ui::AXClippingBehavior clipping_behavior, ui::AXOffscreenResult* offscreen_result = nullptr) const; + // Returns the value of a control, such as the value of a text field, a slider + // or a scrollbar. + // + // For text fields, computes the value of the field from its internal + // representation in the accessibility tree if necessary. + // // This is to handle the cases such as ARIA textbox, where the value should - // be calculated from the object's inner text. + // be calculated from the object's inner text, as well as all text fields + // originating from Blink where the HTML value attribute cannot always be + // trusted. + // + // TODO(nektar): Move this method to AXNode when AXNodePosition and + // BrowserAccessibilityPosition are merged into one class. virtual base::string16 GetValue() const; // This is an approximate hit test that only uses the information in @@ -415,11 +424,11 @@ // Return true if the accessible name was explicitly set to "" by the author bool HasExplicitlyEmptyName() const; - // TODO(nektar): Remove this method and use GetInnerText instead. + // TODO(nektar): Remove this method and replace with GetInnerText. std::string ComputeAccessibleNameFromDescendants() const; - // Get text to announce for a live region change if an AT does not implement - // this functionality. + // Get text to announce for a live region change, for ATs that do not + // implement this functionality. std::string GetLiveRegionText() const; // Creates a text position rooted at this object. Does not conver to a @@ -442,11 +451,15 @@ // AXPosition Support - // Returns the text that is present inside this node, where the representation - // of text found in descendant nodes depends on the platform. For example some - // platforms may include descendant text while while other platforms may use a - // special character to represent descendant text. Prefer either GetHypertext - // or GetInnerText so it's clear which API is called. + // Returns the text that is present inside this node, where the + // representation of text found in descendant nodes depends on the platform. + // For example some platforms may include descendant text while while other + // platforms may use a special character to represent descendant text. + // Prefer either GetHypertext or GetInnerText so it's clear which API is + // called. + // + // TODO(nektar): Move this method to AXNode when AXNodePosition and + // BrowserAccessibilityPosition are merged into one class. virtual base::string16 GetText() const; base::string16 GetNameAsString16() const; @@ -629,15 +642,15 @@ ui::AXOffscreenResult* offscreen_result) const; // Return a rect for a 1-width character past the end of text. This is what - // ATs expect when getting the character extents past the last character in a - // line, and equals what the caret bounds would be when past the end of the - // text. + // ATs expect when getting the character extents past the last character in + // a line, and equals what the caret bounds would be when past the end of + // the text. gfx::Rect GetRootFrameHypertextBoundsPastEndOfText( const ui::AXClippingBehavior clipping_behavior, ui::AXOffscreenResult* offscreen_result = nullptr) const; - // Return the bounds of inline text in this node's coordinate system (which is - // relative to its container node specified in AXRelativeBounds). + // Return the bounds of inline text in this node's coordinate system (which + // is relative to its container node specified in AXRelativeBounds). gfx::RectF GetInlineTextRect(const int start_offset, const int end_offset, const int max_length) const; @@ -660,8 +673,8 @@ // Given a set of map of spelling text attributes and a start offset, merge // them into the given map of existing text attributes. Merges the given - // spelling attributes, i.e. document marker information, into the given text - // attributes starting at the given character offset. This is required + // spelling attributes, i.e. document marker information, into the given + // text attributes starting at the given character offset. This is required // because document markers that are present on text leaves need to be // propagated to their parent object for compatibility with Firefox. static void MergeSpellingAndGrammarIntoTextAttributes(
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc index a547985..c12d9effd 100644 --- a/content/browser/accessibility/browser_accessibility_android.cc +++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -4,6 +4,9 @@ #include "content/browser/accessibility/browser_accessibility_android.h" +#include <algorithm> +#include <unordered_map> + #include "base/i18n/break_iterator.h" #include "base/lazy_instance.h" #include "base/numerics/ranges.h" @@ -99,7 +102,7 @@ // Optionally replace entered password text with bullet characters // based on a user preference. - if (IsPassword()) { + if (IsPasswordField()) { auto* manager = static_cast<BrowserAccessibilityManagerAndroid*>(this->manager()); if (manager->ShouldRespectDisplayedPasswordText()) { @@ -108,7 +111,7 @@ // true we should try to expose whatever's actually visually displayed, // whether that's the actual password or dots or whatever. To do this // we rely on the password field's shadow dom. - value = base::UTF8ToUTF16(ComputeAccessibleNameFromDescendants()); + value = BrowserAccessibility::GetInnerText(); } else if (!manager->ShouldExposePasswordText()) { value = base::string16(value.size(), ui::kSecurePasswordBullet); } @@ -252,10 +255,6 @@ return false; // No concept of "dismissable" on the web currently. } -bool BrowserAccessibilityAndroid::IsEditableText() const { - return IsPlainTextField() || IsRichTextField(); -} - bool BrowserAccessibilityAndroid::IsEnabled() const { switch (GetData().GetRestriction()) { case ax::mojom::Restriction::kNone: @@ -327,10 +326,6 @@ return HasState(ax::mojom::State::kMultiline); } -bool BrowserAccessibilityAndroid::IsPassword() const { - return HasState(ax::mojom::State::kProtected); -} - bool BrowserAccessibilityAndroid::IsRangeType() const { return (GetRole() == ax::mojom::Role::kProgressIndicator || GetRole() == ax::mojom::Role::kMeter || @@ -465,7 +460,7 @@ // On Android, contenteditable needs to be handled the same as any // other text field. - if (IsPlainTextField() || IsRichTextField()) + if (IsTextField()) role = ax::mojom::Role::kTextField; return ui::AXRoleToAndroidClassName(role, PlatformGetParent() != nullptr); @@ -1714,9 +1709,9 @@ if (!IsRichTextField() && !IsPlainTextField()) return; - // TODO: using FindTextOnlyObjectsInRange or NextInTreeOrder doesn't - // work because Android's PlatformIsLeafIncludingIgnored implementation - // deliberately excludes a lot of nodes. We need a version of + // TODO(accessibility): using FindTextOnlyObjectsInRange or NextInTreeOrder + // doesn't work because Android's PlatformIsLeafIncludingIgnored + // implementation deliberately excludes a lot of nodes. We need a version of // FindTextOnlyObjectsInRange and/or NextInTreeOrder that only walk // the internal tree. BrowserAccessibility* node = InternalGetFirstChild(); @@ -1769,7 +1764,7 @@ } bool BrowserAccessibilityAndroid::HasNonEmptyValue() const { - return IsEditableText() && !GetValue().empty(); + return IsTextField() && !GetValue().empty(); } bool BrowserAccessibilityAndroid::HasCharacterLocations() const { @@ -1827,18 +1822,15 @@ switch (GetRole()) { case ax::mojom::Role::kDate: case ax::mojom::Role::kDateTime: - case ax::mojom::Role::kTextField: - case ax::mojom::Role::kTextFieldWithComboBox: return true; default: break; } - if (IsPlainTextField() || IsRichTextField()) + if (IsTextField()) return true; - base::string16 value = GetValue(); - if (value.empty()) + if (GetValue().empty()) return false; if (GetRole() == ax::mojom::Role::kPopUpButton) @@ -1850,7 +1842,7 @@ void BrowserAccessibilityAndroid::OnDataChanged() { BrowserAccessibility::OnDataChanged(); - if (IsEditableText()) { + if (IsTextField()) { base::string16 value = GetValue(); if (value != new_value_) { old_value_ = new_value_;
diff --git a/content/browser/accessibility/browser_accessibility_android.h b/content/browser/accessibility/browser_accessibility_android.h index 415a1922..bfccc065 100644 --- a/content/browser/accessibility/browser_accessibility_android.h +++ b/content/browser/accessibility/browser_accessibility_android.h
@@ -8,6 +8,9 @@ #include <stddef.h> #include <stdint.h> +#include <string> +#include <vector> + #include "base/android/scoped_java_ref.h" #include "base/macros.h" #include "base/timer/elapsed_timer.h" @@ -39,7 +42,6 @@ bool IsCollectionItem() const; bool IsContentInvalid() const; bool IsDismissable() const; - bool IsEditableText() const; bool IsEnabled() const; bool IsExpanded() const; bool IsFocusable() const; @@ -49,7 +51,6 @@ bool IsHierarchical() const; bool IsLink() const; bool IsMultiLine() const; - bool IsPassword() const; bool IsRangeType() const; bool IsScrollable() const; bool IsSelected() const;
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index 1573834..17f4660 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -2366,9 +2366,10 @@ return nil; if (ui::IsNameExposedInAXValueForRole([self internalRole])) { - if (!IsSelectedStateRelevant(_owner)) + if (!IsSelectedStateRelevant(_owner)) { return NSStringForStringAttribute(_owner, ax::mojom::StringAttribute::kName); + } // Append the selection state as a string, because VoiceOver will not // automatically report selection state when an individual item is focused. @@ -2544,11 +2545,14 @@ if (![self instanceActive]) return nil; - base::string16 value = _owner->GetValue(); - if (NSMaxRange(range) > value.length()) + base::string16 innerText = _owner->GetValue(); + if (innerText.empty()) + innerText = _owner->GetInnerText(); + if (NSMaxRange(range) > innerText.length()) return nil; - return base::SysUTF16ToNSString(value.substr(range.location, range.length)); + return base::SysUTF16ToNSString( + innerText.substr(range.location, range.length)); } // Retrieves the text inside this object and decorates it with attributes @@ -2558,23 +2562,24 @@ if (![self instanceActive]) return nil; - base::string16 text = _owner->GetValue(); - if (_owner->IsTextOnlyObject() && text.empty()) - text = _owner->GetText(); + base::string16 innerText = _owner->GetValue(); + if (innerText.empty()) + innerText = _owner->GetInnerText(); + if (NSMaxRange(range) > innerText.length()) + return nil; - // We need to get the whole text because a spelling mistake might start or end - // outside our range. - NSString* value = base::SysUTF16ToNSString(text); - NSMutableAttributedString* attributedValue = - [[[NSMutableAttributedString alloc] initWithString:value] autorelease]; - + // We potentially need to add text attributes to the whole inner text because + // a spelling mistake might start or end outside the given range. + NSMutableAttributedString* attributedInnerText = + [[[NSMutableAttributedString alloc] + initWithString:base::SysUTF16ToNSString(innerText)] autorelease]; if (!_owner->IsTextOnlyObject()) { AXPlatformRange ax_range(_owner->CreatePositionAt(0), - _owner->CreatePositionAt(int{text.length()})); - AddMisspelledTextAttributes(ax_range, attributedValue); + _owner->CreatePositionAt(int{innerText.length()})); + AddMisspelledTextAttributes(ax_range, attributedInnerText); } - return [attributedValue attributedSubstringFromRange:range]; + return [attributedInnerText attributedSubstringFromRange:range]; } // Returns the accessibility value for the given attribute. If the value isn't @@ -2616,12 +2621,6 @@ if (![self instanceActive]) return nil; - const std::vector<int> lineBreaks = _owner->GetLineStartOffsets(); - base::string16 value = _owner->GetValue(); - if (_owner->IsTextOnlyObject() && value.empty()) - value = _owner->GetText(); - int valueLength = static_cast<int>(value.size()); - if ([attribute isEqualToString: NSAccessibilityStringForRangeParameterizedAttribute]) { return [self valueForRange:[(NSValue*)parameter rangeValue]]; @@ -2636,6 +2635,7 @@ if ([attribute isEqualToString:NSAccessibilityLineForIndexParameterizedAttribute]) { int lineIndex = [(NSNumber*)parameter intValue]; + const std::vector<int> lineBreaks = _owner->GetLineStartOffsets(); auto iterator = std::upper_bound(lineBreaks.begin(), lineBreaks.end(), lineIndex); return @(std::distance(lineBreaks.begin(), iterator)); @@ -2644,6 +2644,12 @@ if ([attribute isEqualToString:NSAccessibilityRangeForLineParameterizedAttribute]) { int lineIndex = [(NSNumber*)parameter intValue]; + const std::vector<int> lineBreaks = _owner->GetLineStartOffsets(); + base::string16 value = _owner->GetValue(); + if (value.empty()) + value = _owner->GetInnerText(); + int valueLength = static_cast<int>(value.size()); + int lineCount = static_cast<int>(lineBreaks.size()) + 1; if (lineIndex < 0 || lineIndex >= lineCount) return nil; @@ -2802,6 +2808,7 @@ return nil; int textOffset = position->AsTextPosition()->text_offset(); + const std::vector<int> lineBreaks = _owner->GetLineStartOffsets(); const auto iterator = std::upper_bound(lineBreaks.begin(), lineBreaks.end(), textOffset); return @(std::distance(lineBreaks.begin(), iterator)); @@ -2811,6 +2818,7 @@ isEqualToString: NSAccessibilityTextMarkerRangeForLineParameterizedAttribute]) { int lineIndex = [(NSNumber*)parameter intValue]; + const std::vector<int> lineBreaks = _owner->GetLineStartOffsets(); int lineCount = static_cast<int>(lineBreaks.size()) + 1; if (lineIndex < 0 || lineIndex >= lineCount) return nil;
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc index c3251ec..7186298 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.cc +++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -4,6 +4,8 @@ #include "content/browser/accessibility/browser_accessibility_manager_android.h" +#include <vector> + #include "base/i18n/char_iterator.h" #include "content/browser/accessibility/browser_accessibility_android.h" #include "content/browser/accessibility/web_contents_accessibility_android.h" @@ -143,7 +145,7 @@ // character with a dot after a short pause. On Android we don't want to // fire an event for those changes, but we do want to make sure our internal // state is correct, so we call OnDataChanged() and then return. - if (android_node->IsPassword() && original_node != node) { + if (android_node->IsPasswordField() && original_node != node) { android_node->OnDataChanged(); return; } @@ -191,7 +193,7 @@ break; } case ui::AXEventGenerator::Event::VALUE_CHANGED: - if (android_node->IsEditableText() && GetFocus() == node) { + if (android_node->IsTextField() && GetFocus() == node) { wcax->HandleEditableTextChanged(android_node->unique_id()); } else if (android_node->IsSlider()) { wcax->HandleSliderChanged(android_node->unique_id());
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc index b61d447..a8d27bd 100644 --- a/content/browser/accessibility/web_contents_accessibility_android.cc +++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -4,6 +4,11 @@ #include "content/browser/accessibility/web_contents_accessibility_android.h" +#include <memory> +#include <string> +#include <unordered_map> +#include <vector> + #include "base/android/jni_android.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" @@ -633,7 +638,7 @@ if (!node) return false; - return node->IsEditableText(); + return node->IsTextField(); } jboolean WebContentsAccessibilityAndroid::IsFocused( @@ -746,13 +751,13 @@ Java_WebContentsAccessibilityImpl_setAccessibilityNodeInfoBooleanAttributes( env, obj, info, unique_id, node->IsCheckable(), node->IsChecked(), node->IsClickable(), node->IsEnabled(), node->IsFocusable(), - node->IsFocused(), node->IsPassword(), node->IsScrollable(), + node->IsFocused(), node->IsPasswordField(), node->IsScrollable(), node->IsSelected(), node->IsVisibleToUser()); Java_WebContentsAccessibilityImpl_addAccessibilityNodeInfoActions( env, obj, info, unique_id, node->CanScrollForward(), node->CanScrollBackward(), node->CanScrollUp(), node->CanScrollDown(), node->CanScrollLeft(), node->CanScrollRight(), node->IsClickable(), - node->IsEditableText(), node->IsEnabled(), node->IsFocusable(), + node->IsTextField(), node->IsEnabled(), node->IsFocusable(), node->IsFocused(), node->IsCollapsed(), node->IsExpanded(), node->HasNonEmptyValue(), !node->GetInnerText().empty(), node->IsRangeType(), node->IsFormDescendant()); @@ -782,7 +787,7 @@ Java_WebContentsAccessibilityImpl_setAccessibilityNodeInfoText( env, obj, info, base::android::ConvertUTF16ToJavaString(env, node->GetInnerText()), - node->IsLink(), node->IsEditableText(), + node->IsLink(), node->IsTextField(), base::android::ConvertUTF16ToJavaString( env, node->GetInheritedString16Attribute( ax::mojom::StringAttribute::kLanguage)), @@ -800,7 +805,7 @@ bool is_root = node->PlatformGetParent() == NULL; Java_WebContentsAccessibilityImpl_setAccessibilityNodeInfoKitKatAttributes( - env, obj, info, is_root, node->IsEditableText(), + env, obj, info, is_root, node->IsTextField(), base::android::ConvertUTF8ToJavaString(env, node->GetRoleString()), base::android::ConvertUTF16ToJavaString(env, node->GetRoleDescription()), base::android::ConvertUTF16ToJavaString(env, node->GetHint()), @@ -856,8 +861,8 @@ return false; Java_WebContentsAccessibilityImpl_setAccessibilityEventBooleanAttributes( - env, obj, event, node->IsChecked(), node->IsEnabled(), node->IsPassword(), - node->IsScrollable()); + env, obj, event, node->IsChecked(), node->IsEnabled(), + node->IsPasswordField(), node->IsScrollable()); Java_WebContentsAccessibilityImpl_setAccessibilityEventClassName( env, obj, event, base::android::ConvertUTF8ToJavaString(env, node->GetClassName()));
diff --git a/content/browser/renderer_host/media/audio_service_listener.cc b/content/browser/renderer_host/media/audio_service_listener.cc index 9ddbb8e..aa57490 100644 --- a/content/browser/renderer_host/media/audio_service_listener.cc +++ b/content/browser/renderer_host/media/audio_service_listener.cc
@@ -20,69 +20,7 @@ namespace content { -AudioServiceListener::Metrics::Metrics(const base::TickClock* clock) - : clock_(clock), initial_downtime_start_(clock_->NowTicks()) {} - -AudioServiceListener::Metrics::~Metrics() = default; - -void AudioServiceListener::Metrics::ServiceAlreadyRunning() { - LogServiceStartStatus(ServiceStartStatus::kAlreadyStarted); - initial_downtime_start_ = base::TimeTicks(); - started_ = clock_->NowTicks(); -} - -void AudioServiceListener::Metrics::ServiceCreated() { - DCHECK(created_.is_null()); - created_ = clock_->NowTicks(); -} - -void AudioServiceListener::Metrics::ServiceStarted() { - started_ = clock_->NowTicks(); - - // |created_| is uninitialized if OnServiceCreated() was called before the - // listener is initialized with OnInit() call. - if (!created_.is_null()) { - LogServiceStartStatus(ServiceStartStatus::kSuccess); - UMA_HISTOGRAM_TIMES("Media.AudioService.ObservedStartupTime", - started_ - created_); - created_ = base::TimeTicks(); - } - - if (!initial_downtime_start_.is_null()) { - UMA_HISTOGRAM_CUSTOM_TIMES("Media.AudioService.ObservedInitialDowntime", - started_ - initial_downtime_start_, - base::TimeDelta(), base::TimeDelta::FromDays(7), - 50); - initial_downtime_start_ = base::TimeTicks(); - } - - if (!stopped_.is_null()) { - UMA_HISTOGRAM_CUSTOM_TIMES("Media.AudioService.ObservedDowntime2", - started_ - stopped_, base::TimeDelta(), - base::TimeDelta::FromDays(7), 50); - stopped_ = base::TimeTicks(); - } -} - -void AudioServiceListener::Metrics::ServiceStopped() { - stopped_ = clock_->NowTicks(); - - DCHECK(!started_.is_null()); - UMA_HISTOGRAM_CUSTOM_TIMES("Media.AudioService.ObservedUptime", - stopped_ - started_, base::TimeDelta(), - base::TimeDelta::FromDays(7), 50); - - created_ = base::TimeTicks(); - started_ = base::TimeTicks(); -} - -void AudioServiceListener::Metrics::LogServiceStartStatus( - Metrics::ServiceStartStatus status) { - UMA_HISTOGRAM_ENUMERATION("Media.AudioService.ObservedStartStatus", status); -} - -AudioServiceListener::AudioServiceListener() - : metrics_(base::DefaultTickClock::GetInstance()) { +AudioServiceListener::AudioServiceListener() { ServiceProcessHost::AddObserver(this); Init(ServiceProcessHost::GetRunningProcessInfo()); } @@ -102,7 +40,6 @@ for (const auto& info : running_service_processes) { if (info.IsService<audio::mojom::AudioService>()) { process_id_ = info.pid; - metrics_.ServiceAlreadyRunning(); MaybeSetLogFactory(); break; } @@ -116,8 +53,6 @@ return; process_id_ = info.pid; - metrics_.ServiceCreated(); - metrics_.ServiceStarted(); MaybeSetLogFactory(); } @@ -127,7 +62,6 @@ if (!info.IsService<audio::mojom::AudioService>()) return; - metrics_.ServiceStopped(); process_id_ = base::kNullProcessId; log_factory_is_set_ = false; } @@ -138,7 +72,6 @@ if (!info.IsService<audio::mojom::AudioService>()) return; - metrics_.ServiceStopped(); process_id_ = base::kNullProcessId; log_factory_is_set_ = false; }
diff --git a/content/browser/renderer_host/media/audio_service_listener.h b/content/browser/renderer_host/media/audio_service_listener.h index 3c7140c..690f1b9 100644 --- a/content/browser/renderer_host/media/audio_service_listener.h +++ b/content/browser/renderer_host/media/audio_service_listener.h
@@ -17,46 +17,12 @@ #include "content/public/browser/service_process_info.h" #include "mojo/public/cpp/bindings/receiver.h" -namespace base { -class TickClock; -} - namespace content { // Tracks the system's active audio service instance, if any exists. class CONTENT_EXPORT AudioServiceListener : public ServiceProcessHost::Observer { public: - class CONTENT_EXPORT Metrics { - public: - // Matches histogram enum AudioServiceStartStatus, entries (except kMaxEnum) - // must not be renumbered. - enum class ServiceStartStatus { - kAlreadyStarted = 0, - kSuccess = 1, - kFailure = 2, - kMaxValue = kFailure, - }; - - explicit Metrics(const base::TickClock* clock); - ~Metrics(); - - void ServiceAlreadyRunning(); - void ServiceCreated(); - void ServiceStarted(); - void ServiceStopped(); - - private: - void LogServiceStartStatus(ServiceStartStatus status); - - const base::TickClock* clock_; - base::TimeTicks initial_downtime_start_; - base::TimeTicks created_; - base::TimeTicks started_; - base::TimeTicks stopped_; - DISALLOW_COPY_AND_ASSIGN(Metrics); - }; - AudioServiceListener(); ~AudioServiceListener() override; @@ -84,7 +50,6 @@ void MaybeSetLogFactory(); base::ProcessId process_id_ = base::kNullProcessId; - Metrics metrics_; bool log_factory_is_set_ = false; SEQUENCE_CHECKER(owning_sequence_);
diff --git a/content/browser/renderer_host/media/audio_service_listener_unittest.cc b/content/browser/renderer_host/media/audio_service_listener_unittest.cc index e69f80c..e808185 100644 --- a/content/browser/renderer_host/media/audio_service_listener_unittest.cc +++ b/content/browser/renderer_host/media/audio_service_listener_unittest.cc
@@ -6,7 +6,6 @@ #include <utility> -#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_tick_clock.h" #include "base/token.h" @@ -42,106 +41,8 @@ base::test::ScopedFeatureList feature_list_; BrowserTaskEnvironment task_environment_; base::SimpleTestTickClock test_clock; - base::HistogramTester histogram_tester; }; -TEST_F(AudioServiceListenerTest, - ServiceCreatedStartedStopped_LogsStartupTime_LogsUptime) { - AudioServiceListener::Metrics metrics(&test_clock); - metrics.ServiceCreated(); - test_clock.Advance(base::TimeDelta::FromMilliseconds(42)); - metrics.ServiceStarted(); - histogram_tester.ExpectTimeBucketCount( - "Media.AudioService.ObservedStartupTime", - base::TimeDelta::FromMilliseconds(42), 1); - test_clock.Advance(base::TimeDelta::FromDays(2)); - metrics.ServiceStopped(); - histogram_tester.ExpectTimeBucketCount("Media.AudioService.ObservedUptime", - base::TimeDelta::FromDays(2), 1); - - test_clock.Advance(base::TimeDelta::FromHours(5)); - metrics.ServiceCreated(); - metrics.ServiceStarted(); - histogram_tester.ExpectTimeBucketCount("Media.AudioService.ObservedDowntime2", - base::TimeDelta::FromHours(5), 1); -} - -TEST_F(AudioServiceListenerTest, - CreateMetricsStartService_LogsInitialDowntime) { - AudioServiceListener::Metrics metrics(&test_clock); - test_clock.Advance(base::TimeDelta::FromHours(12)); - metrics.ServiceCreated(); - metrics.ServiceStarted(); - histogram_tester.ExpectTimeBucketCount( - "Media.AudioService.ObservedInitialDowntime", - base::TimeDelta::FromHours(12), 1); -} - -TEST_F(AudioServiceListenerTest, ServiceAlreadyRunningStopService_LogsUptime) { - AudioServiceListener::Metrics metrics(&test_clock); - metrics.ServiceAlreadyRunning(); - test_clock.Advance(base::TimeDelta::FromMinutes(42)); - metrics.ServiceStopped(); - histogram_tester.ExpectTimeBucketCount("Media.AudioService.ObservedUptime", - base::TimeDelta::FromMinutes(42), 1); -} - -TEST_F(AudioServiceListenerTest, - ServiceAlreadyRunningCreateService_LogsStartupTime) { - AudioServiceListener::Metrics metrics(&test_clock); - metrics.ServiceAlreadyRunning(); - test_clock.Advance(base::TimeDelta::FromMilliseconds(2)); - metrics.ServiceStopped(); - metrics.ServiceCreated(); - test_clock.Advance(base::TimeDelta::FromMilliseconds(20)); - metrics.ServiceStarted(); - histogram_tester.ExpectTimeBucketCount( - "Media.AudioService.ObservedStartupTime", - base::TimeDelta::FromMilliseconds(20), 1); -} - -// Check that if service was already created and ServiceStarted() is called, -// ObservedStartupTime and ObservedInitialDowntime are not logged and start time -// is reset. -TEST_F(AudioServiceListenerTest, - ServiceAlreadyRunningStartService_ResetStartTime) { - AudioServiceListener::Metrics metrics(&test_clock); - metrics.ServiceAlreadyRunning(); - test_clock.Advance(base::TimeDelta::FromMilliseconds(20)); - metrics.ServiceStarted(); - histogram_tester.ExpectTotalCount("Media.AudioService.ObservedStartupTime", - 0); - histogram_tester.ExpectTotalCount( - "Media.AudioService.ObservedInitialDowntime", 0); - test_clock.Advance(base::TimeDelta::FromMilliseconds(200)); - metrics.ServiceStopped(); - histogram_tester.ExpectTimeBucketCount("Media.AudioService.ObservedUptime", - base::TimeDelta::FromMilliseconds(200), - 1); -} - -TEST_F(AudioServiceListenerTest, StartService_LogStartStatus) { - base::HistogramTester histogram_tester; - AudioServiceListener audio_service_listener; - constexpr base::ProcessId pid(42); - ServiceProcessInfo audio_process_info = MakeFakeAudioServiceProcessInfo(pid); - audio_service_listener.Init({audio_process_info}); - histogram_tester.ExpectBucketCount( - "Media.AudioService.ObservedStartStatus", - static_cast<int>( - AudioServiceListener::Metrics::ServiceStartStatus::kAlreadyStarted), - 1); - audio_service_listener.OnServiceProcessTerminatedNormally(audio_process_info); - - audio_service_listener.OnServiceProcessLaunched(audio_process_info); - histogram_tester.ExpectBucketCount( - "Media.AudioService.ObservedStartStatus", - static_cast<int>( - AudioServiceListener::Metrics::ServiceStartStatus::kSuccess), - 1); - audio_service_listener.OnServiceProcessTerminatedNormally(audio_process_info); -} - TEST_F(AudioServiceListenerTest, OnInitWithAudioService_ProcessIdNotNull) { AudioServiceListener audio_service_listener; constexpr base::ProcessId pid(42);
diff --git a/content/renderer/media/audio/audio_renderer_mixer_manager.cc b/content/renderer/media/audio/audio_renderer_mixer_manager.cc index c2296e4..fe5c686e 100644 --- a/content/renderer/media/audio/audio_renderer_mixer_manager.cc +++ b/content/renderer/media/audio/audio_renderer_mixer_manager.cc
@@ -178,19 +178,6 @@ sink_info.device_id()); base::AutoLock auto_lock(mixers_lock_); - // Update latency map when the mixer is requested, i.e. there is an attempt to - // mix and output audio with a given latency. This is opposite to - // CreateInput() which creates a sink which is probably never used for output. - if (!latency_map_[latency]) { - latency_map_[latency] = 1; - // Log the updated latency map. This can't be done once in the end of the - // renderer lifetime, because the destructor is usually not called. So, - // we'll have a sort of exponential scale here, with a smaller subset - // logged both on its own and as a part of any larger subset. - base::UmaHistogramSparse("Media.Audio.Render.AudioMixing.LatencyMap", - latency_map_.to_ulong()); - } - auto it = mixers_.find(key); if (it != mixers_.end()) { it->second.ref_count++;
diff --git a/content/renderer/media/audio/audio_renderer_mixer_manager.h b/content/renderer/media/audio/audio_renderer_mixer_manager.h index 30c8dd34..33728ee9 100644 --- a/content/renderer/media/audio/audio_renderer_mixer_manager.h +++ b/content/renderer/media/audio/audio_renderer_mixer_manager.h
@@ -151,10 +151,6 @@ AudioRendererMixerMap mixers_; base::Lock mixers_lock_; - // Map of the output latencies encountered throughout mixer manager lifetime. - // Used for UMA histogram logging. - std::bitset<media::AudioLatency::LATENCY_COUNT> latency_map_; - DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerManager); };
diff --git a/ios/chrome/app/application_delegate/BUILD.gn b/ios/chrome/app/application_delegate/BUILD.gn index 956d298..1d835f5d 100644 --- a/ios/chrome/app/application_delegate/BUILD.gn +++ b/ios/chrome/app/application_delegate/BUILD.gn
@@ -47,13 +47,14 @@ "//ios/chrome/browser/crash_report", "//ios/chrome/browser/device_sharing", "//ios/chrome/browser/geolocation", + "//ios/chrome/browser/main:public", + "//ios/chrome/browser/main:test_support", "//ios/chrome/browser/metrics", "//ios/chrome/browser/ntp_snippets", "//ios/chrome/browser/signin", "//ios/chrome/browser/signin:test_support", "//ios/chrome/browser/tabs", "//ios/chrome/browser/u2f", - "//ios/chrome/browser/ui/browser_view", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/main", "//ios/chrome/browser/ui/main/test", @@ -140,6 +141,7 @@ "//ios/chrome/browser/device_sharing", "//ios/chrome/browser/feature_engagement", "//ios/chrome/browser/geolocation", + "//ios/chrome/browser/main:public", "//ios/chrome/browser/metrics", "//ios/chrome/browser/metrics:metrics_internal", "//ios/chrome/browser/net", @@ -148,7 +150,6 @@ "//ios/chrome/browser/tabs", "//ios/chrome/browser/u2f", "//ios/chrome/browser/ui/authentication", - "//ios/chrome/browser/ui/browser_view", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/main", "//ios/chrome/browser/ui/main:scene",
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm index 53292262..0f763ae5 100644 --- a/ios/chrome/app/application_delegate/app_state.mm +++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -34,6 +34,7 @@ #import "ios/chrome/browser/device_sharing/device_sharing_manager.h" #include "ios/chrome/browser/feature_engagement/tracker_factory.h" #import "ios/chrome/browser/geolocation/omnibox_geolocation_config.h" +#import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/metrics/ios_profile_session_durations_service.h" #import "ios/chrome/browser/metrics/ios_profile_session_durations_service_factory.h" #import "ios/chrome/browser/metrics/previous_session_info.h" @@ -41,9 +42,10 @@ #import "ios/chrome/browser/signin/authentication_service_factory.h" #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/ui/authentication/signed_in_accounts_view_controller.h" -#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h" #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/browser_commands.h" +#import "ios/chrome/browser/ui/commands/command_dispatcher.h" +#import "ios/chrome/browser/ui/commands/help_commands.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/main/browser_interface_provider.h" #import "ios/chrome/browser/ui/main/scene_delegate.h" @@ -354,6 +356,8 @@ id<BrowserInterface> currentInterface = _browserLauncher.interfaceProvider.currentInterface; + CommandDispatcher* dispatcher = + currentInterface.browser->GetCommandDispatcher(); if ([_startupInformation startupParameters]) { [UserActivityHandler handleStartupParametersWithTabOpener:tabOpener @@ -369,10 +373,11 @@ if (![tabSwitcher openNewTabFromTabSwitcher]) { OpenNewTabCommand* command = [OpenNewTabCommand commandWithIncognito:currentInterface.incognito]; - [currentInterface.bvc.dispatcher openURLInNewTab:command]; + [HandlerForProtocol(dispatcher, ApplicationCommands) + openURLInNewTab:command]; } } else { - [currentInterface.bvc presentBubblesIfEligible]; + [HandlerForProtocol(dispatcher, HelpCommands) showHelpBubbleIfEligible]; } IOSProfileSessionDurationsService* psdService =
diff --git a/ios/chrome/app/application_delegate/app_state_unittest.mm b/ios/chrome/app/application_delegate/app_state_unittest.mm index 861c544..15e895a5 100644 --- a/ios/chrome/app/application_delegate/app_state_unittest.mm +++ b/ios/chrome/app/application_delegate/app_state_unittest.mm
@@ -24,6 +24,7 @@ #include "ios/chrome/browser/chrome_url_constants.h" #import "ios/chrome/browser/device_sharing/device_sharing_manager.h" #import "ios/chrome/browser/geolocation/omnibox_geolocation_config.h" +#import "ios/chrome/browser/main/test_browser.h" #import "ios/chrome/browser/metrics/ios_profile_session_durations_service.h" #import "ios/chrome/browser/metrics/ios_profile_session_durations_service_factory.h" #include "ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.h" @@ -31,9 +32,9 @@ #import "ios/chrome/browser/signin/authentication_service_fake.h" #include "ios/chrome/browser/system_flags.h" #import "ios/chrome/browser/tabs/tab_model.h" -#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h" #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/browser_commands.h" +#import "ios/chrome/browser/ui/commands/command_dispatcher.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/main/browser_interface_provider.h" #import "ios/chrome/browser/ui/main/test/stub_browser_interface.h" @@ -507,7 +508,6 @@ IOSChromeScopedTestingChromeBrowserProvider provider_( std::make_unique<FakeChromeBrowserProvider>()); - id browserViewController = OCMClassMock([BrowserViewController class]); id browserLauncher = [OCMockObject mockForProtocol:@protocol(BrowserLauncher)]; id applicationDelegate = @@ -516,7 +516,6 @@ StubBrowserInterfaceProvider* interfaceProvider = [[StubBrowserInterfaceProvider alloc] init]; interfaceProvider.mainInterface.userInteractionEnabled = YES; - interfaceProvider.mainInterface.bvc = browserViewController; [[[browserLauncher stub] andReturnValue:@(INITIALIZATION_STAGE_FOREGROUND)] browserInitializationStage]; @@ -538,7 +537,6 @@ [appState applicationWillTerminate:application]; // Test. - EXPECT_OCMOCK_VERIFY(browserViewController); EXPECT_OCMOCK_VERIFY(startupInformation); EXPECT_OCMOCK_VERIFY(application); EXPECT_FALSE(interfaceProvider.mainInterface.userInteractionEnabled); @@ -574,10 +572,9 @@ id tabSwitcher = [OCMockObject mockForProtocol:@protocol(TabSwitching)]; // BrowserViewInformation. - id mainTabModel = [OCMockObject mockForClass:[TabModel class]]; - id mainBVC = [OCMockObject mockForClass:[BrowserViewController class]]; - interfaceProvider.mainInterface.tabModel = mainTabModel; - interfaceProvider.mainInterface.bvc = mainBVC; + std::unique_ptr<Browser> browser = + std::make_unique<TestBrowser>(getBrowserState()); + interfaceProvider.mainInterface.browser = browser.get(); interfaceProvider.mainInterface.browserState = getBrowserState(); // Swizzle Startup Parameters. @@ -595,7 +592,6 @@ EXPECT_EQ(NSUInteger(0), [window subviews].count); EXPECT_EQ(1, getProfileSessionDurationsService()->session_started_count()); EXPECT_EQ(0, getProfileSessionDurationsService()->session_ended_count()); - EXPECT_OCMOCK_VERIFY(mainTabModel); } // Test that -resumeSessionWithTabOpener removes incognito blocker, @@ -616,10 +612,11 @@ [[[getStartupInformationMock() stub] andReturnValue:@NO] isColdStart]; // BrowserViewInformation. + std::unique_ptr<Browser> browser = + std::make_unique<TestBrowser>(getBrowserState()); + interfaceProvider.mainInterface.browser = browser.get(); id mainTabModel = [OCMockObject mockForClass:[TabModel class]]; - id mainBVC = [OCMockObject mockForClass:[BrowserViewController class]]; interfaceProvider.mainInterface.tabModel = mainTabModel; - interfaceProvider.mainInterface.bvc = mainBVC; interfaceProvider.mainInterface.browserState = getBrowserState(); // TabOpening. @@ -663,14 +660,25 @@ // BrowserViewInformation. id mainTabModel = [OCMockObject mockForClass:[TabModel class]]; - id dispatcher = [OCMockObject mockForProtocol:@protocol(ApplicationCommands)]; - [((id<ApplicationCommands>)[dispatcher expect]) openURLInNewTab:[OCMArg any]]; + id applicationCommandEndpoint = + [OCMockObject mockForProtocol:@protocol(ApplicationCommands)]; + [((id<ApplicationCommands>)[applicationCommandEndpoint expect]) + openURLInNewTab:[OCMArg any]]; - id currentBVC = [OCMockObject mockForClass:[BrowserViewController class]]; - [[[currentBVC stub] andReturn:dispatcher] dispatcher]; - + std::unique_ptr<Browser> browser = + std::make_unique<TestBrowser>(getBrowserState()); + [browser->GetCommandDispatcher() + startDispatchingToTarget:applicationCommandEndpoint + forProtocol:@protocol(ApplicationCommands)]; + // To fully conform to ApplicationCommands, the dispatcher needs to dispatch + // for ApplicationSettingsCommands as well. + id applicationSettingsCommandEndpoint = + [OCMockObject mockForProtocol:@protocol(ApplicationSettingsCommands)]; + [browser->GetCommandDispatcher() + startDispatchingToTarget:applicationSettingsCommandEndpoint + forProtocol:@protocol(ApplicationSettingsCommands)]; + interfaceProvider.mainInterface.browser = browser.get(); interfaceProvider.mainInterface.tabModel = mainTabModel; - interfaceProvider.mainInterface.bvc = currentBVC; interfaceProvider.mainInterface.browserState = getBrowserState(); // TabOpening. @@ -693,8 +701,6 @@ // Test. EXPECT_EQ(NSUInteger(0), [window subviews].count); - EXPECT_OCMOCK_VERIFY(mainTabModel); - EXPECT_OCMOCK_VERIFY(currentBVC); } // Tests that -applicationWillEnterForeground resets components as needed. @@ -714,9 +720,7 @@ browserInitializationStage]; [[[getBrowserLauncherMock() stub] andReturn:interfaceProvider] interfaceProvider]; - id mainBVC = [OCMockObject mockForClass:[BrowserViewController class]]; interfaceProvider.mainInterface.tabModel = tabModel; - interfaceProvider.mainInterface.bvc = mainBVC; interfaceProvider.mainInterface.browserState = getBrowserState(); [[metricsMediator expect] updateMetricsStateBasedOnPrefsUserTriggered:NO];
diff --git a/ios/chrome/browser/interstitials/ios_blocking_page_tab_helper.h b/ios/chrome/browser/interstitials/ios_blocking_page_tab_helper.h index ac1548b9..12bf7a8 100644 --- a/ios/chrome/browser/interstitials/ios_blocking_page_tab_helper.h +++ b/ios/chrome/browser/interstitials/ios_blocking_page_tab_helper.h
@@ -30,6 +30,10 @@ int64_t navigation_id, std::unique_ptr<IOSSecurityInterstitialPage> blocking_page); + // Returns the blocking page showing on the current tab. + IOSSecurityInterstitialPage* GetCurrentBlockingPage( + web::WebState* web_state) const; + // web::WebStateObserver implementation. void DidFinishNavigation(web::WebState* web_state, web::NavigationContext* navigation_context) override;
diff --git a/ios/chrome/browser/interstitials/ios_blocking_page_tab_helper.mm b/ios/chrome/browser/interstitials/ios_blocking_page_tab_helper.mm index 6c046bb..66b6c7b 100644 --- a/ios/chrome/browser/interstitials/ios_blocking_page_tab_helper.mm +++ b/ios/chrome/browser/interstitials/ios_blocking_page_tab_helper.mm
@@ -45,6 +45,12 @@ helper->SetBlockingPage(navigation_id, std::move(blocking_page)); } +IOSSecurityInterstitialPage* IOSBlockingPageTabHelper::GetCurrentBlockingPage( + web::WebState* web_state) const { + DCHECK_EQ(web_state_, web_state); + return blocking_page_for_currently_committed_navigation_.get(); +} + // When the navigation finishes and commits the SSL error page, store the // IOSSecurityInterstitialPage in a member variable so that it can handle // commands. Clean up the member variable when a subsequent navigation commits,
diff --git a/ios/chrome/browser/interstitials/ios_chrome_controller_client.h b/ios/chrome/browser/interstitials/ios_chrome_controller_client.h index 0393b38..54f4c05 100644 --- a/ios/chrome/browser/interstitials/ios_chrome_controller_client.h +++ b/ios/chrome/browser/interstitials/ios_chrome_controller_client.h
@@ -8,7 +8,9 @@ #include <string> #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "components/security_interstitials/core/controller_client.h" +#include "ios/web/public/web_state_observer.h" class GURL; @@ -23,7 +25,8 @@ // Provides embedder-specific logic for the security error page controller. class IOSChromeControllerClient - : public security_interstitials::ControllerClient { + : public security_interstitials::ControllerClient, + public web::WebStateObserver { public: IOSChromeControllerClient( web::WebState* web_state, @@ -32,6 +35,9 @@ void SetWebInterstitial(web::WebInterstitial* web_interstitial); + // web::WebStateObserver implementation. + void WebStateDestroyed(web::WebState* web_state) override; + private: // security_interstitials::ControllerClient implementation. bool CanLaunchDateAndTimeSettings() override; @@ -48,9 +54,15 @@ PrefService* GetPrefService() override; const std::string GetExtendedReportingPrefName() const override; + // Closes the tab. Called in cases where a user clicks "Back to safety" and + // it's not possible to go back. + void Close(); + web::WebState* web_state_; web::WebInterstitial* web_interstitial_; + base::WeakPtrFactory<IOSChromeControllerClient> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(IOSChromeControllerClient); };
diff --git a/ios/chrome/browser/interstitials/ios_chrome_controller_client.mm b/ios/chrome/browser/interstitials/ios_chrome_controller_client.mm index 4399729a..5b05769 100644 --- a/ios/chrome/browser/interstitials/ios_chrome_controller_client.mm +++ b/ios/chrome/browser/interstitials/ios_chrome_controller_client.mm
@@ -4,7 +4,9 @@ #include "ios/chrome/browser/interstitials/ios_chrome_controller_client.h" +#include "base/bind.h" #include "base/logging.h" +#include "base/task/post_task.h" #include "components/security_interstitials/core/metrics_helper.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" @@ -12,6 +14,8 @@ #import "ios/web/public/navigation/navigation_manager.h" #include "ios/web/public/navigation/reload_type.h" #include "ios/web/public/security/web_interstitial.h" +#include "ios/web/public/thread/web_task_traits.h" +#include "ios/web/public/thread/web_thread.h" #import "ios/web/public/web_state.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -23,7 +27,10 @@ std::unique_ptr<security_interstitials::MetricsHelper> metrics_helper) : security_interstitials::ControllerClient(std::move(metrics_helper)), web_state_(web_state), - web_interstitial_(nullptr) {} + web_interstitial_(nullptr), + weak_factory_(this) { + web_state_->AddObserver(this); +} IOSChromeControllerClient::~IOSChromeControllerClient() {} @@ -32,6 +39,12 @@ web_interstitial_ = web_interstitial; } +void IOSChromeControllerClient::WebStateDestroyed(web::WebState* web_state) { + DCHECK_EQ(web_state_, web_state); + web_state_->RemoveObserver(this); + web_state_ = nullptr; +} + bool IOSChromeControllerClient::CanLaunchDateAndTimeSettings() { return false; } @@ -43,6 +56,13 @@ void IOSChromeControllerClient::GoBack() { if (CanGoBack()) { web_state_->GetNavigationManager()->GoBack(); + } else { + // Closing the tab synchronously is problematic since web state is heavily + // involved in the operation and CloseWebState interrupts it, so call + // CloseWebState asynchronously. + base::PostTask(FROM_HERE, {web::WebThread::UI}, + base::BindOnce(&IOSChromeControllerClient::Close, + weak_factory_.GetWeakPtr())); } } @@ -94,3 +114,9 @@ const { return std::string(); } + +void IOSChromeControllerClient::Close() { + if (web_state_) { + web_state_->CloseWebState(); + } +}
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn index 5827a385..1b810aa 100644 --- a/ios/chrome/browser/ui/browser_view/BUILD.gn +++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -47,6 +47,7 @@ "//ios/chrome/browser/first_run", "//ios/chrome/browser/geolocation:geolocation_internal", "//ios/chrome/browser/infobars", + "//ios/chrome/browser/interstitials", "//ios/chrome/browser/language", "//ios/chrome/browser/main", "//ios/chrome/browser/metrics:metrics_browser_agent",
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.h b/ios/chrome/browser/ui/browser_view/browser_view_controller.h index 7acc169..d9ec30b 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.h +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.h
@@ -113,12 +113,6 @@ // Called when the user explicitly opens the tab switcher. - (void)userEnteredTabSwitcher; -// Presents either in-product help bubbles if the the user is in a valid state -// to see one of them. At most one bubble will be shown. If the feature -// engagement tracker determines it is not valid to see one of the bubbles, that -// bubble will not be shown. -- (void)presentBubblesIfEligible; - // Opens a new tab as if originating from |originPoint| and |focusOmnibox|. - (void)openNewTabFromOriginPoint:(CGPoint)originPoint focusOmnibox:(BOOL)focusOmnibox;
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm index 3610ec0..b16b3dd 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -38,6 +38,7 @@ #include "ios/chrome/browser/first_run/first_run.h" #import "ios/chrome/browser/geolocation/omnibox_geolocation_controller.h" #include "ios/chrome/browser/infobars/infobar_manager_impl.h" +#import "ios/chrome/browser/interstitials/ios_blocking_page_tab_helper.h" #import "ios/chrome/browser/language/url_language_histogram_factory.h" #import "ios/chrome/browser/main/browser.h" #import "ios/chrome/browser/metrics/new_tab_page_uma.h" @@ -544,6 +545,9 @@ // Command handler for text zoom commands @property(nonatomic, weak) id<TextZoomCommands> textZoomHandler; +// Command handler for help commands +@property(nonatomic, weak) id<HelpCommands> helpHandler; + // Primary toolbar. @property(nonatomic, strong) PrimaryToolbarCoordinator* primaryToolbarCoordinator; @@ -1067,22 +1071,6 @@ : nullptr; } -- (BubblePresenter*)bubblePresenter { - if (!_bubblePresenter && self.browserState) { - self.bubblePresenter = - [[BubblePresenter alloc] initWithBrowserState:self.browserState - delegate:self - rootViewController:self]; - } - return _bubblePresenter; -} - -- (void)setBubblePresenter:(BubblePresenter*)bubblePresenter { - _bubblePresenter = bubblePresenter; - _bubblePresenter.dispatcher = self.dispatcher; - self.popupMenuCoordinator.bubblePresenter = _bubblePresenter; -} - - (BOOL)isNTPActiveForCurrentWebState { if (self.currentWebState) { NewTabPageTabHelper* NTPHelper = @@ -1120,10 +1108,6 @@ [self.bubblePresenter userEnteredTabSwitcher]; } -- (void)presentBubblesIfEligible { - [self.bubblePresenter presentBubblesIfEligible]; -} - - (void)openNewTabFromOriginPoint:(CGPoint)originPoint focusOmnibox:(BOOL)focusOmnibox { NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate]; @@ -1276,7 +1260,7 @@ [self.dispatcher cancelOmniboxEdit]; } [_dialogPresenter cancelAllDialogs]; - [self.bubblePresenter dismissBubbles]; + [self.helpHandler hideAllHelpBubbles]; if (_voiceSearchController) _voiceSearchController->DismissMicPermissionsHelp(); @@ -1383,12 +1367,12 @@ self.tabStripCoordinator = nil; self.tabStripView = nil; - self.browser->GetWebStateList()->RemoveObserver(_webStateListObserver.get()); - self.browser = nullptr; + [self.commandDispatcher stopDispatchingToTarget:self.bubblePresenter]; self.bubblePresenter = nil; [self.commandDispatcher stopDispatchingToTarget:self]; - self.commandDispatcher = nil; + self.browser->GetWebStateList()->RemoveObserver(_webStateListObserver.get()); + self.browser = nullptr; [self.primaryToolbarCoordinator stop]; self.primaryToolbarCoordinator = nil; @@ -1545,7 +1529,7 @@ // |presentBubblesIfEligible| requires that |self.browserState| is not NULL, // check for |self.browserState| before calling the presenting the bubbles. if (self.browserState) { - [self presentBubblesIfEligible]; + [self.helpHandler showHelpBubbleIfEligible]; } } @@ -1560,7 +1544,7 @@ // case, display the Long Press InProductHelp if needed. auto completion = ^(id<UIViewControllerTransitionCoordinatorContext> context) { - [self.bubblePresenter presentLongPressBubbleIfEligible]; + [self.helpHandler showLongPressHelpBubbleIfEligible]; }; [self.transitionCoordinator animateAlongsideTransition:nil @@ -2180,6 +2164,18 @@ .heightAnchor; } + self.bubblePresenter = + [[BubblePresenter alloc] initWithBrowserState:self.browserState + delegate:self + rootViewController:self]; + self.bubblePresenter.toolbarHandler = + HandlerForProtocol(self.browser->GetCommandDispatcher(), ToolbarCommands); + [self.browser->GetCommandDispatcher() + startDispatchingToTarget:self.bubblePresenter + forProtocol:@protocol(HelpCommands)]; + self.helpHandler = + HandlerForProtocol(self.browser->GetCommandDispatcher(), HelpCommands); + self.popupMenuCoordinator = [[PopupMenuCoordinator alloc] initWithBaseViewController:self browser:self.browser]; @@ -2482,7 +2478,7 @@ if ([self.dispatcher respondsToSelector:@selector(hidePageInfo)]) [self.dispatcher hidePageInfo]; [self.dispatcher dismissPopupMenuAnimated:NO]; - [self.bubblePresenter dismissBubbles]; + [self.helpHandler hideAllHelpBubbles]; } - (UIView*)footerView { @@ -2980,10 +2976,13 @@ } - (void)closeWebState:(web::WebState*)webState { - // Only allow a web page to close itself if it was opened by DOM, or if there - // are no navigation items. + // Only allow a web page to close itself if it was opened by DOM, if there + // are no navigation items, or if an interstitial is showing. + IOSBlockingPageTabHelper* helper = + IOSBlockingPageTabHelper::FromWebState(webState); DCHECK(webState->HasOpener() || - !webState->GetNavigationManager()->GetItemCount()); + !webState->GetNavigationManager()->GetItemCount() || + helper->GetCurrentBlockingPage(webState) != nullptr); if (!self.browser) return; WebStateList* webStateList = self.browser->GetWebStateList(); @@ -4398,7 +4397,7 @@ } if (completion) completion(); - [self.bubblePresenter presentLongPressBubbleIfEligible]; + [self.helpHandler showLongPressHelpBubbleIfEligible]; if (self.foregroundTabWasAddedCompletionBlock) { self.foregroundTabWasAddedCompletionBlock();
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.h b/ios/chrome/browser/ui/bubble/bubble_presenter.h index 8d4334b..6a42d6b 100644 --- a/ios/chrome/browser/ui/bubble/bubble_presenter.h +++ b/ios/chrome/browser/ui/bubble/bubble_presenter.h
@@ -6,7 +6,7 @@ #define IOS_CHROME_BROWSER_UI_BUBBLE_BUBBLE_PRESENTER_H_ #import <UIKit/UIKit.h> - +#import "ios/chrome/browser/ui/commands/help_commands.h" @protocol BubblePresenterDelegate; @class BubbleViewControllerPresenter; @@ -15,7 +15,7 @@ // Object handling the presentation of the different bubbles tips. The class is // holding all the bubble presenters. -@interface BubblePresenter : NSObject +@interface BubblePresenter : NSObject <HelpCommands> // Initializes a BubblePresenter whose bubbles are presented on the // |rootViewController|. @@ -30,20 +30,7 @@ @property(nonatomic, strong, readonly) BubbleViewControllerPresenter* incognitoTabTipBubblePresenter; -@property(nonatomic, weak) id<ToolbarCommands> dispatcher; - -// Presents either in-product help bubbles if the the user is in a valid state -// to see one of them. At most one bubble will be shown. If the feature -// engagement tracker determines it is not valid to see one of the bubbles, that -// bubble will not be shown. -- (void)presentBubblesIfEligible; - -// Presents the in-product help for the LongPress help if the feature engagement -// and the application states determine that it is possible to present it. -- (void)presentLongPressBubbleIfEligible; - -// Dismisses all bubbles. -- (void)dismissBubbles; +@property(nonatomic, weak) id<ToolbarCommands> toolbarHandler; // Notifies the presenter that the user entered the tab switcher. - (void)userEnteredTabSwitcher;
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.mm b/ios/chrome/browser/ui/bubble/bubble_presenter.mm index f44be16a..74053005 100644 --- a/ios/chrome/browser/ui/bubble/bubble_presenter.mm +++ b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
@@ -67,16 +67,6 @@ @implementation BubblePresenter -@synthesize bottomToolbarTipBubblePresenter = _bottomToolbarTipBubblePresenter; -@synthesize longPressToolbarTipBubblePresenter = - _longPressToolbarTipBubblePresenter; -@synthesize tabTipBubblePresenter = _tabTipBubblePresenter; -@synthesize incognitoTabTipBubblePresenter = _incognitoTabTipBubblePresenter; -@synthesize browserState = _browserState; -@synthesize delegate = _delegate; -@synthesize dispatcher = _dispatcher; -@synthesize rootViewController = _rootViewController; - #pragma mark - Public - (instancetype)initWithBrowserState:(ChromeBrowserState*)browserState @@ -91,7 +81,7 @@ return self; } -- (void)presentBubblesIfEligible { +- (void)showHelpBubbleIfEligible { DCHECK(self.browserState); // Waits to present the bubbles until the feature engagement tracker database // is fully initialized. This method requires that |self.browserState| is not @@ -116,7 +106,7 @@ ->AddOnInitializedCallback(base::BindRepeating(onInitializedBlock)); } -- (void)presentLongPressBubbleIfEligible { +- (void)showLongPressHelpBubbleIfEligible { DCHECK(self.browserState); // Waits to present the bubble until the feature engagement tracker database // is fully initialized. This method requires that |self.browserState| is not @@ -136,7 +126,7 @@ ->AddOnInitializedCallback(base::BindRepeating(onInitializedBlock)); } -- (void)dismissBubbles { +- (void)hideAllHelpBubbles { [self.tabTipBubblePresenter dismissAnimated:NO]; [self.incognitoTabTipBubblePresenter dismissAnimated:NO]; [self.bottomToolbarTipBubblePresenter dismissAnimated:NO]; @@ -344,7 +334,7 @@ self.incognitoTabTipBubblePresenter = presenter; - [self.dispatcher triggerToolsMenuButtonAnimation]; + [self.toolbarHandler triggerToolsMenuButtonAnimation]; } #pragma mark - Private Utils
diff --git a/ios/chrome/browser/ui/commands/BUILD.gn b/ios/chrome/browser/ui/commands/BUILD.gn index 3e2893b..662de24 100644 --- a/ios/chrome/browser/ui/commands/BUILD.gn +++ b/ios/chrome/browser/ui/commands/BUILD.gn
@@ -16,6 +16,7 @@ "find_in_page_commands.h", "generate_qr_code_command.h", "generate_qr_code_command.mm", + "help_commands.h", "infobar_commands.h", "load_query_commands.h", "omnibox_suggestion_commands.h",
diff --git a/ios/chrome/browser/ui/commands/help_commands.h b/ios/chrome/browser/ui/commands/help_commands.h new file mode 100644 index 0000000..6493778 --- /dev/null +++ b/ios/chrome/browser/ui/commands/help_commands.h
@@ -0,0 +1,22 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_COMMANDS_HELP_COMMANDS_H_ +#define IOS_CHROME_BROWSER_UI_COMMANDS_HELP_COMMANDS_H_ + +// Commands to control the display of in-product help UI ("bubbles"). +@protocol HelpCommands <NSObject> + +// Shows a relevant help bubble, if any. +- (void)showHelpBubbleIfEligible; + +// Shows a relevant help bubble for long-press state, if any. +- (void)showLongPressHelpBubbleIfEligible; + +// Dismisses all bubbles. +- (void)hideAllHelpBubbles; + +@end + +#endif // IOS_CHROME_BROWSER_UI_COMMANDS_HELP_COMMANDS_H_
diff --git a/ios/web/public/test/fakes/test_web_state.h b/ios/web/public/test/fakes/test_web_state.h index a96805d..5d6a350 100644 --- a/ios/web/public/test/fakes/test_web_state.h +++ b/ios/web/public/test/fakes/test_web_state.h
@@ -79,6 +79,8 @@ void RemoveObserver(WebStateObserver* observer) override; + void CloseWebState() override; + void AddPolicyDecider(WebStatePolicyDecider* decider) override; void RemovePolicyDecider(WebStatePolicyDecider* decider) override; void DidChangeVisibleSecurityState() override {}
diff --git a/ios/web/public/test/fakes/test_web_state.mm b/ios/web/public/test/fakes/test_web_state.mm index 1f3f860..b6749722 100644 --- a/ios/web/public/test/fakes/test_web_state.mm +++ b/ios/web/public/test/fakes/test_web_state.mm
@@ -34,6 +34,8 @@ observers_.RemoveObserver(observer); } +void TestWebState::CloseWebState() {} + TestWebState::TestWebState() : browser_state_(nullptr), web_usage_enabled_(true),
diff --git a/ios/web/public/web_state.h b/ios/web/public/web_state.h index c7cc65e..5220936 100644 --- a/ios/web/public/web_state.h +++ b/ios/web/public/web_state.h
@@ -362,6 +362,10 @@ virtual void AddObserver(WebStateObserver* observer) = 0; virtual void RemoveObserver(WebStateObserver* observer) = 0; + // Instructs the delegate to close this web state. Called when the page calls + // wants to close self by calling window.close() JavaScript API. + virtual void CloseWebState() = 0; + protected: friend class WebStatePolicyDecider;
diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h index b731efb6..3275e42 100644 --- a/ios/web/web_state/web_state_impl.h +++ b/ios/web/web_state/web_state_impl.h
@@ -212,6 +212,7 @@ void TakeSnapshot(const gfx::RectF& rect, SnapshotCallback callback) override; void AddObserver(WebStateObserver* observer) override; void RemoveObserver(WebStateObserver* observer) override; + void CloseWebState() override; // Adds |interstitial|'s view to the web controller's content view. void ShowWebInterstitial(WebInterstitialImpl* interstitial); @@ -239,10 +240,6 @@ const GURL& opener_url, bool initiated_by_user); - // Instructs the delegate to close this web state. Called when the page calls - // wants to close self by calling window.close() JavaScript API. - virtual void CloseWebState(); - // Notifies the delegate that request receives an authentication challenge // and is unable to respond using cached credentials. void OnAuthRequired(NSURLProtectionSpace* protection_space,
diff --git a/media/base/status_codes.h b/media/base/status_codes.h index ccac030..219defb 100644 --- a/media/base/status_codes.h +++ b/media/base/status_codes.h
@@ -69,7 +69,7 @@ kVaapiFailedAcceleratorCreation = 0x00000509, // Special codes - kGenericErrorPleaseRemove = 0x99999999, + kGenericErrorPleaseRemove = 0x79999999, kCodeOnlyForTesting = std::numeric_limits<StatusCodeType>::max(), kMaxValue = kCodeOnlyForTesting, };
diff --git a/media/renderers/BUILD.gn b/media/renderers/BUILD.gn index f18dedf4..7cd29bd 100644 --- a/media/renderers/BUILD.gn +++ b/media/renderers/BUILD.gn
@@ -106,6 +106,8 @@ if (is_win) { source_set("media_foundation_renderer") { sources = [ + "win/media_engine_extension.cc", + "win/media_engine_extension.h", "win/media_engine_notify_impl.cc", "win/media_engine_notify_impl.h", "win/media_foundation_audio_stream.cc",
diff --git a/media/renderers/win/media_engine_extension.cc b/media/renderers/win/media_engine_extension.cc new file mode 100644 index 0000000..1fb3147 --- /dev/null +++ b/media/renderers/win/media_engine_extension.cc
@@ -0,0 +1,115 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/renderers/win/media_engine_extension.h" + +#include <mferror.h> + +#include "media/base/win/mf_helpers.h" + +namespace media { + +using Microsoft::WRL::ComPtr; + +MediaEngineExtension::MediaEngineExtension() = default; +MediaEngineExtension::~MediaEngineExtension() = default; + +HRESULT MediaEngineExtension::RuntimeClassInitialize() { + DVLOG(1) << __func__ << ": this=" << this; + return S_OK; +} + +HRESULT MediaEngineExtension::CanPlayType(BOOL is_audio_only, + BSTR mime_type, + MF_MEDIA_ENGINE_CANPLAY* result) { + // We use MF_MEDIA_ENGINE_EXTENSION to resolve as custom media source for + // MFMediaEngine, MIME types are not used. + *result = MF_MEDIA_ENGINE_CANPLAY_NOT_SUPPORTED; + return S_OK; +} + +HRESULT MediaEngineExtension::BeginCreateObject(BSTR url_bstr, + IMFByteStream* byte_stream, + MF_OBJECT_TYPE type, + IUnknown** cancel_cookie, + IMFAsyncCallback* callback, + IUnknown* state) { + DVLOG(1) << __func__ << ": this=" << this << ",type=" << type; + + if (cancel_cookie) { + // We don't support a cancel cookie. + *cancel_cookie = nullptr; + } + ComPtr<IUnknown> local_source; + { + base::AutoLock lock(lock_); + if (has_shutdown_) { + return MF_E_SHUTDOWN; + } + local_source = mf_media_source_; + } + + if (type == MF_OBJECT_MEDIASOURCE) { + DVLOG(2) << "Begin to resolve mf_media_source_: this=" << this; + DCHECK(local_source) << "Media Source should have been set"; + + ComPtr<IMFAsyncResult> async_result; + RETURN_IF_FAILED(MFCreateAsyncResult(local_source.Get(), callback, state, + &async_result)); + RETURN_IF_FAILED(async_result->SetStatus(S_OK)); + pending_create_object_ = true; + // Invoke the callback synchronously since no outstanding work is required. + RETURN_IF_FAILED(callback->Invoke(async_result.Get())); + } else { + // MediaEngine will try to resolve with different |type|. + return MF_E_UNEXPECTED; + } + + return S_OK; +} + +HRESULT MediaEngineExtension::CancelObjectCreation( + __in IUnknown* cancel_cookie) { + DVLOG(1) << __func__ << ": this=" << this; + + return MF_E_UNEXPECTED; +} + +HRESULT MediaEngineExtension::EndCreateObject(__in IMFAsyncResult* result, + __deref_out IUnknown** ret_obj) { + DVLOG(1) << __func__ << ": this=" << this; + + *ret_obj = nullptr; + if (!pending_create_object_) + return MF_E_UNEXPECTED; + + DVLOG(2) << "End to resolve mf_media_source_: this=" << this; + RETURN_IF_FAILED(result->GetStatus()); + RETURN_IF_FAILED(result->GetObject(ret_obj)); + pending_create_object_ = false; + return S_OK; +} + +HRESULT MediaEngineExtension::SetMediaSource(IUnknown* mf_media_source) { + DVLOG(1) << __func__ << ": this=" << this; + + base::AutoLock lock(lock_); + if (has_shutdown_) + return MF_E_SHUTDOWN; + mf_media_source_ = mf_media_source; + return S_OK; +} + +// Break cycles. +void MediaEngineExtension::Shutdown() { + DVLOG(1) << __func__ << ": this=" << this; + + base::AutoLock lock(lock_); + if (!has_shutdown_) { + mf_media_source_.Reset(); + has_shutdown_ = true; + } +} + +} // namespace media
diff --git a/media/renderers/win/media_engine_extension.h b/media/renderers/win/media_engine_extension.h new file mode 100644 index 0000000..cf57631 --- /dev/null +++ b/media/renderers/win/media_engine_extension.h
@@ -0,0 +1,61 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_RENDERERS_WIN_MEDIA_ENGINE_EXTENSION_H_ +#define MEDIA_RENDERERS_WIN_MEDIA_ENGINE_EXTENSION_H_ + +#include <mfapi.h> +#include <mfmediaengine.h> +#include <wrl.h> + +#include "base/synchronization/lock.h" + +namespace media { + +// Implement IMFMediaEngineExtension to load media source into the +// IMFMediaEngine. See details from: +// https://docs.microsoft.com/en-us/windows/win32/api/mfmediaengine/nn-mfmediaengine-imfmediaengineextension. +// +class MediaEngineExtension + : public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags< + Microsoft::WRL::RuntimeClassType::ClassicCom>, + IMFMediaEngineExtension> { + public: + MediaEngineExtension(); + ~MediaEngineExtension() override; + + HRESULT RuntimeClassInitialize(); + + // IMFMediaEngineExtension + IFACEMETHODIMP CanPlayType(BOOL is_audio_only, + BSTR mime_type, + MF_MEDIA_ENGINE_CANPLAY* result) override; + IFACEMETHODIMP BeginCreateObject(BSTR url_bstr, + IMFByteStream* byte_stream, + MF_OBJECT_TYPE type, + IUnknown** cancel_cookie, + IMFAsyncCallback* callback, + IUnknown* state) override; + IFACEMETHODIMP CancelObjectCreation(IUnknown* cancel_cookie) override; + IFACEMETHODIMP EndCreateObject(IMFAsyncResult* result, + IUnknown** ret_obj) override; + + HRESULT SetMediaSource(IUnknown* mf_media_source); + void Shutdown(); + + private: + bool pending_create_object_ = false; + + // Need a lock to ensure thread safe operation between IMFMediaEngineExtension + // method calls from MFMediaEngine threadpool thread and + // SetMediaSource/Shutdown from MediaFoundationRenderer calling thread. + base::Lock lock_; + bool has_shutdown_ GUARDED_BY(lock_) = false; + Microsoft::WRL::ComPtr<IUnknown> mf_media_source_ GUARDED_BY(lock_); +}; + +} // namespace media + +#endif // MEDIA_RENDERERS_WIN_MEDIA_ENGINE_EXTENSION_H_
diff --git a/net/BUILD.gn b/net/BUILD.gn index b135b51b..5d3272d 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1335,6 +1335,10 @@ "proxy_resolution/proxy_config_service_win.h", "proxy_resolution/proxy_resolver_winhttp.cc", "proxy_resolution/proxy_resolver_winhttp.h", + "proxy_resolution/win/windows_system_proxy_resolution_request.cc", + "proxy_resolution/win/windows_system_proxy_resolution_request.h", + "proxy_resolution/win/windows_system_proxy_resolution_service.cc", + "proxy_resolution/win/windows_system_proxy_resolution_service.h", "socket/tcp_socket_win.cc", "socket/tcp_socket_win.h", "socket/udp_socket_win.cc", @@ -4490,6 +4494,7 @@ "proxy_resolution/dhcp_pac_file_adapter_fetcher_win_unittest.cc", "proxy_resolution/dhcp_pac_file_fetcher_win_unittest.cc", "proxy_resolution/proxy_config_service_win_unittest.cc", + "proxy_resolution/win/windows_system_proxy_resolution_service_unittest.cc", "ssl/client_cert_store_win_unittest.cc", "ssl/ssl_platform_key_win_unittest.cc", ]
diff --git a/net/proxy_resolution/configured_proxy_resolution_request.h b/net/proxy_resolution/configured_proxy_resolution_request.h index b7b25efa..ab38b4c 100644 --- a/net/proxy_resolution/configured_proxy_resolution_request.h +++ b/net/proxy_resolution/configured_proxy_resolution_request.h
@@ -22,9 +22,9 @@ class ProxyInfo; class ConfiguredProxyResolutionService; -// ConfiguredProxyResolutionRequest is the concrete implementation of -// ProxyResolutionRequest used by ConfiguredProxyResolutionService. Manages a -// single asynchronous proxy resolution request. +// This is the concrete implementation of ProxyResolutionRequest used by +// ConfiguredProxyResolutionService. Manages a single asynchronous proxy +// resolution request. class ConfiguredProxyResolutionRequest final : public ProxyResolutionRequest { public: ConfiguredProxyResolutionRequest(
diff --git a/net/proxy_resolution/configured_proxy_resolution_service.cc b/net/proxy_resolution/configured_proxy_resolution_service.cc index d4dc748c..ae0a8be 100644 --- a/net/proxy_resolution/configured_proxy_resolution_service.cc +++ b/net/proxy_resolution/configured_proxy_resolution_service.cc
@@ -13,7 +13,6 @@ #include "base/compiler_specific.h" #include "base/location.h" #include "base/logging.h" -#include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" @@ -36,10 +35,8 @@ #include "net/proxy_resolution/pac_file_decider.h" #include "net/proxy_resolution/pac_file_fetcher.h" #include "net/proxy_resolution/proxy_config_service_fixed.h" -#include "net/proxy_resolution/proxy_resolver.h" #include "net/proxy_resolution/proxy_resolver_factory.h" #include "net/url_request/url_request_context.h" -#include "url/gurl.h" #if defined(OS_WIN) #include "net/proxy_resolution/proxy_config_service_win.h"
diff --git a/net/proxy_resolution/configured_proxy_resolution_service.h b/net/proxy_resolution/configured_proxy_resolution_service.h index fe8755d..768ca0f7 100644 --- a/net/proxy_resolution/configured_proxy_resolution_service.h +++ b/net/proxy_resolution/configured_proxy_resolution_service.h
@@ -32,8 +32,6 @@ #include "net/traffic_annotation/network_traffic_annotation.h" #include "url/gurl.h" -class GURL; - namespace base { class SequencedTaskRunner; class TimeDelta; @@ -49,9 +47,9 @@ class ProxyResolverFactory; struct PacFileDataWithSource; -// This class can be used to resolve the proxy server to use when loading a -// HTTP(S) URL. It uses the given ProxyResolver to evaluate a PAC file, which -// the ConfiguredProxyResolutionService then uses to resolve a proxy. All proxy +// This class decides which proxy server(s) to use for a particular URL request. +// It uses the given ProxyResolver to evaluate a PAC file, which the +// ConfiguredProxyResolutionService then uses to resolve a proxy. All proxy // resolution in this class is based on first getting proxy configurations (ex: // a PAC URL) from some source and then using these configurations to attempt to // resolve that proxy.
diff --git a/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc b/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc index 8fb8c820..f9000e2 100644 --- a/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc +++ b/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc
@@ -4180,4 +4180,19 @@ } } +TEST_F(ConfiguredProxyResolutionServiceTest, + CastToConfiguredProxyResolutionService) { + MockProxyConfigService* config_service = + new MockProxyConfigService(ProxyConfig::CreateDirect()); + + ConfiguredProxyResolutionService service( + base::WrapUnique(config_service), + std::make_unique<MockAsyncProxyResolverFactory>(false), nullptr, + /*quick_check_enabled=*/true); + + ConfiguredProxyResolutionService* casted_service = nullptr; + EXPECT_TRUE(service.CastToConfiguredProxyResolutionService(&casted_service)); + EXPECT_EQ(&service, casted_service); +} + } // namespace net
diff --git a/net/proxy_resolution/win/windows_system_proxy_resolution_request.cc b/net/proxy_resolution/win/windows_system_proxy_resolution_request.cc new file mode 100644 index 0000000..707c427 --- /dev/null +++ b/net/proxy_resolution/win/windows_system_proxy_resolution_request.cc
@@ -0,0 +1,18 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/proxy_resolution/win/windows_system_proxy_resolution_request.h" + +namespace net { + +WindowsSystemProxyResolutionRequest::WindowsSystemProxyResolutionRequest() = + default; +WindowsSystemProxyResolutionRequest::~WindowsSystemProxyResolutionRequest() = + default; + +LoadState WindowsSystemProxyResolutionRequest::GetLoadState() const { + return LOAD_STATE_IDLE; +} + +} // namespace net
diff --git a/net/proxy_resolution/win/windows_system_proxy_resolution_request.h b/net/proxy_resolution/win/windows_system_proxy_resolution_request.h new file mode 100644 index 0000000..575dcff --- /dev/null +++ b/net/proxy_resolution/win/windows_system_proxy_resolution_request.h
@@ -0,0 +1,32 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLUTION_REQUEST_H_ +#define NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLUTION_REQUEST_H_ + +#include "net/proxy_resolution/proxy_resolution_request.h" + +namespace net { + +// This is the concrete implementation of ProxyResolutionRequest used by +// WindowsSystemProxyResolutionService. Manages a single asynchronous proxy +// resolution request. +class WindowsSystemProxyResolutionRequest final + : public ProxyResolutionRequest { + public: + WindowsSystemProxyResolutionRequest(); + + WindowsSystemProxyResolutionRequest( + const WindowsSystemProxyResolutionRequest&) = delete; + WindowsSystemProxyResolutionRequest& operator=( + const WindowsSystemProxyResolutionRequest&) = delete; + + ~WindowsSystemProxyResolutionRequest() override; + + LoadState GetLoadState() const override; +}; + +} // namespace net + +#endif // NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLUTION_REQUEST_H_
diff --git a/net/proxy_resolution/win/windows_system_proxy_resolution_service.cc b/net/proxy_resolution/win/windows_system_proxy_resolution_service.cc new file mode 100644 index 0000000..16fc564 --- /dev/null +++ b/net/proxy_resolution/win/windows_system_proxy_resolution_service.cc
@@ -0,0 +1,66 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/proxy_resolution/win/windows_system_proxy_resolution_service.h" + +#include "base/values.h" +#include "net/base/net_errors.h" + +namespace net { + +WindowsSystemProxyResolutionService::WindowsSystemProxyResolutionService() = + default; +WindowsSystemProxyResolutionService::~WindowsSystemProxyResolutionService() = + default; + +int WindowsSystemProxyResolutionService::ResolveProxy( + const GURL& url, + const std::string& method, + const NetworkIsolationKey& network_isolation_key, + ProxyInfo* results, + CompletionOnceCallback callback, + std::unique_ptr<ProxyResolutionRequest>* request, + const NetLogWithSource& net_log) { + return ERR_NOT_IMPLEMENTED; +} + +void WindowsSystemProxyResolutionService::ReportSuccess( + const ProxyInfo& proxy_info) {} + +void WindowsSystemProxyResolutionService::SetProxyDelegate( + ProxyDelegate* delegate) {} + +void WindowsSystemProxyResolutionService::OnShutdown() {} + +bool WindowsSystemProxyResolutionService::MarkProxiesAsBadUntil( + const ProxyInfo& results, + base::TimeDelta retry_delay, + const std::vector<ProxyServer>& additional_bad_proxies, + const NetLogWithSource& net_log) { + return false; +} + +void WindowsSystemProxyResolutionService::ClearBadProxiesCache() {} + +const ProxyRetryInfoMap& WindowsSystemProxyResolutionService::proxy_retry_info() + const { + return proxy_retry_info_; +} + +std::unique_ptr<base::DictionaryValue> +WindowsSystemProxyResolutionService::GetProxyNetLogValues(int info_sources) { + std::unique_ptr<base::DictionaryValue> net_info_dict( + new base::DictionaryValue()); + return net_info_dict; +} + +bool WindowsSystemProxyResolutionService:: + CastToConfiguredProxyResolutionService( + ConfiguredProxyResolutionService** + configured_proxy_resolution_service) { + *configured_proxy_resolution_service = nullptr; + return false; +} + +} // namespace net
diff --git a/net/proxy_resolution/win/windows_system_proxy_resolution_service.h b/net/proxy_resolution/win/windows_system_proxy_resolution_service.h new file mode 100644 index 0000000..f5b820f --- /dev/null +++ b/net/proxy_resolution/win/windows_system_proxy_resolution_service.h
@@ -0,0 +1,63 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLUTION_SERVICE_H_ +#define NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLUTION_SERVICE_H_ + +#include "net/proxy_resolution/proxy_resolution_service.h" + +#include <string> + +#include "net/base/net_export.h" + +namespace net { + +// This class decides which proxy server(s) to use for a particular URL request. +// It does NOT support passing in fetched proxy configurations. Instead, it +// relies entirely on WinHttp APIs to determine the proxy that should be used +// for each network request. +class NET_EXPORT WindowsSystemProxyResolutionService + : public ProxyResolutionService { + public: + WindowsSystemProxyResolutionService(); + + WindowsSystemProxyResolutionService( + const WindowsSystemProxyResolutionService&) = delete; + WindowsSystemProxyResolutionService& operator=( + const WindowsSystemProxyResolutionService&) = delete; + + ~WindowsSystemProxyResolutionService() override; + + // ProxyResolutionService implementation + int ResolveProxy(const GURL& url, + const std::string& method, + const NetworkIsolationKey& network_isolation_key, + ProxyInfo* results, + CompletionOnceCallback callback, + std::unique_ptr<ProxyResolutionRequest>* request, + const NetLogWithSource& net_log) override; + void ReportSuccess(const ProxyInfo& proxy_info) override; + void SetProxyDelegate(ProxyDelegate* delegate) override; + void OnShutdown() override; + bool MarkProxiesAsBadUntil( + const ProxyInfo& results, + base::TimeDelta retry_delay, + const std::vector<ProxyServer>& additional_bad_proxies, + const NetLogWithSource& net_log) override; + void ClearBadProxiesCache() override; + const ProxyRetryInfoMap& proxy_retry_info() const override; + std::unique_ptr<base::DictionaryValue> GetProxyNetLogValues( + int info_sources) override; + bool CastToConfiguredProxyResolutionService( + ConfiguredProxyResolutionService** configured_proxy_resolution_service) + override WARN_UNUSED_RESULT; + + private: + // Map of the known bad proxies and the information about the retry time. + ProxyRetryInfoMap proxy_retry_info_; +}; + +} // namespace net + +#endif // NET_PROXY_RESOLUTION_WIN_WINDOWS_SYSTEM_PROXY_RESOLUTION_SERVICE_H_
diff --git a/net/proxy_resolution/win/windows_system_proxy_resolution_service_unittest.cc b/net/proxy_resolution/win/windows_system_proxy_resolution_service_unittest.cc new file mode 100644 index 0000000..94d3c7f --- /dev/null +++ b/net/proxy_resolution/win/windows_system_proxy_resolution_service_unittest.cc
@@ -0,0 +1,21 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/proxy_resolution/win/windows_system_proxy_resolution_service.h" +#include "net/proxy_resolution/configured_proxy_resolution_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { + +TEST(WindowsSystemProxyResolutionServiceTest, + CastToConfiguredProxyResolutionService) { + WindowsSystemProxyResolutionService service; + + auto configured_service = ConfiguredProxyResolutionService::CreateDirect(); + ConfiguredProxyResolutionService* casted_service = configured_service.get(); + EXPECT_FALSE(service.CastToConfiguredProxyResolutionService(&casted_service)); + EXPECT_EQ(nullptr, casted_service); +} + +} // namespace net
diff --git a/services/audio/public/cpp/audio_system_to_service_adapter.cc b/services/audio/public/cpp/audio_system_to_service_adapter.cc index 486dfb5a..15e6be9 100644 --- a/services/audio/public/cpp/audio_system_to_service_adapter.cc +++ b/services/audio/public/cpp/audio_system_to_service_adapter.cc
@@ -68,50 +68,6 @@ NOTREACHED(); } -void LogUMA(Action action, base::TimeTicks start_time) { - const base::TimeDelta duration = base::TimeTicks::Now() - start_time; - switch (action) { - case kGetInputStreamParameters: - UMA_HISTOGRAM_TIMES( - "Media.AudioService.SystemInfoClient.GetInputStreamParameters", - duration); - return; - case kGetOutputStreamParameters: - UMA_HISTOGRAM_TIMES( - "Media.AudioService.SystemInfoClient.GetOutputStreamParameters", - duration); - return; - case kHasInputDevices: - UMA_HISTOGRAM_TIMES("Media.AudioService.SystemInfoClient.HasInputDevices", - duration); - return; - case kHasOutputDevices: - UMA_HISTOGRAM_TIMES( - "Media.AudioService.SystemInfoClient.HasOutputDevices", duration); - return; - case kGetInputDeviceDescriptions: - UMA_HISTOGRAM_TIMES( - "Media.AudioService.SystemInfoClient.GetInputDeviceDescriptions", - duration); - return; - case kGetOutputDeviceDescriptions: - UMA_HISTOGRAM_TIMES( - "Media.AudioService.SystemInfoClient.GetOutputDeviceDescriptions", - duration); - return; - case kGetAssociatedOutputDeviceID: - UMA_HISTOGRAM_TIMES( - "Media.AudioService.SystemInfoClient.GetAssociatedOutputDeviceID", - duration); - return; - case kGetInputDeviceInfo: - UMA_HISTOGRAM_TIMES( - "Media.AudioService.SystemInfoClient.GetInputDeviceInfo", duration); - return; - } - NOTREACHED(); -} - OnAudioParamsCallback WrapGetStreamParametersReply( StreamType stream_type, const std::string& device_id, @@ -129,7 +85,6 @@ TRACE_EVENT_ASYNC_END1("audio", GetTraceEvent(action), ToTraceId(start_time), "params", ParamsToString(params)); - LogUMA(action, start_time); std::move(on_params_callback).Run(params); }, action, start_time, std::move(on_params_callback)); @@ -148,7 +103,6 @@ OnBoolCallback on_has_devices_callback, bool answer) { TRACE_EVENT_ASYNC_END1("audio", GetTraceEvent(action), ToTraceId(start_time), "answer", answer); - LogUMA(action, start_time); std::move(on_has_devices_callback).Run(answer); }, action, start_time, std::move(on_has_devices_callback)); @@ -170,7 +124,6 @@ TRACE_EVENT_ASYNC_END1("audio", GetTraceEvent(action), ToTraceId(start_time), "device count", descriptions.size()); - LogUMA(action, start_time); std::move(on_descriptions_callback).Run(std::move(descriptions)); }, action, start_time, std::move(on_descriptions_callback)); @@ -190,7 +143,6 @@ TRACE_EVENT_ASYNC_END1( "audio", GetTraceEvent(kGetAssociatedOutputDeviceID), ToTraceId(start_time), "answer", answer.value_or("nullopt")); - LogUMA(kGetAssociatedOutputDeviceID, start_time); std::move(on_device_id_callback).Run(answer); }, start_time, std::move(on_device_id_callback)); @@ -213,7 +165,6 @@ "audio", GetTraceEvent(kGetInputDeviceInfo), ToTraceId(start_time), "params", ParamsToString(params), "associated_output_device_id", associated_output_device_id.value_or("nullopt")); - LogUMA(kGetInputDeviceInfo, start_time); std::move(on_input_device_info_callback) .Run(params, associated_output_device_id); },
diff --git a/services/audio/service_metrics.cc b/services/audio/service_metrics.cc index 762c44a..c63b970 100644 --- a/services/audio/service_metrics.cc +++ b/services/audio/service_metrics.cc
@@ -10,14 +10,10 @@ namespace audio { -ServiceMetrics::ServiceMetrics(const base::TickClock* clock) - : clock_(clock), service_start_(clock_->NowTicks()) {} +ServiceMetrics::ServiceMetrics(const base::TickClock* clock) : clock_(clock) {} ServiceMetrics::~ServiceMetrics() { LogHasNoConnectionsDuration(); - UMA_HISTOGRAM_CUSTOM_TIMES( - "Media.AudioService.Uptime", clock_->NowTicks() - service_start_, - base::TimeDelta(), base::TimeDelta::FromDays(7), 50); } void ServiceMetrics::HasConnections() {
diff --git a/services/audio/service_metrics.h b/services/audio/service_metrics.h index 3c2d7610..3ed3645 100644 --- a/services/audio/service_metrics.h +++ b/services/audio/service_metrics.h
@@ -25,7 +25,6 @@ void LogHasNoConnectionsDuration(); const base::TickClock* clock_; - const base::TimeTicks service_start_; base::TimeTicks has_connections_start_; base::TimeTicks has_no_connections_start_;
diff --git a/services/audio/service_metrics_unittest.cc b/services/audio/service_metrics_unittest.cc index efdf5b04..3e9fed0 100644 --- a/services/audio/service_metrics_unittest.cc +++ b/services/audio/service_metrics_unittest.cc
@@ -22,9 +22,6 @@ std::make_unique<ServiceMetrics>(&test_clock); test_clock.Advance(base::TimeDelta::FromDays(6)); metrics.reset(); - histogram_tester.ExpectTimeBucketCount("Media.AudioService.Uptime", - base::TimeDelta::FromDays(6), 1); - histogram_tester.ExpectTotalCount("Media.AudioService.Uptime", 1); } TEST(AudioServiceMetricsTest, AddRemoveConnection_LogsHasConnectionDuration) {
diff --git a/testing/buildbot/chromium.ci.json b/testing/buildbot/chromium.ci.json index 9c45cfc03..33e99d3 100644 --- a/testing/buildbot/chromium.ci.json +++ b/testing/buildbot/chromium.ci.json
@@ -223728,8 +223728,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -223755,7 +223754,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -223781,7 +223780,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -223807,7 +223806,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -223859,6 +223858,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -223912,8 +223936,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -223939,7 +223962,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -223965,7 +223988,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -223991,7 +224014,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -224043,6 +224066,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -224096,8 +224144,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -224123,7 +224170,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -224149,7 +224196,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -224175,7 +224222,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -224227,6 +224274,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -224280,8 +224352,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -224307,7 +224378,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -224333,7 +224404,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -224359,7 +224430,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -224411,6 +224482,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -224464,8 +224560,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -224491,7 +224586,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -224517,7 +224612,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -224543,7 +224638,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -224595,6 +224690,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -224648,8 +224768,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -224675,7 +224794,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -224701,7 +224820,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -224727,7 +224846,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -224779,6 +224898,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -233650,8 +233794,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -233677,7 +233820,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -233703,7 +233846,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -233729,7 +233872,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -233781,6 +233924,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -233834,8 +234002,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -233861,7 +234028,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -233887,7 +234054,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -233913,7 +234080,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -233965,6 +234132,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -234018,8 +234210,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -234045,7 +234236,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -234071,7 +234262,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -234097,7 +234288,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -234149,6 +234340,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -234202,8 +234418,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -234229,7 +234444,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -234255,7 +234470,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -234281,7 +234496,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -234333,6 +234548,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -234386,8 +234626,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -234413,7 +234652,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -234439,7 +234678,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -234465,7 +234704,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -234517,6 +234756,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -234570,8 +234834,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -234597,7 +234860,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -234623,7 +234886,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -234649,7 +234912,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -234701,6 +234964,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" },
diff --git a/testing/buildbot/chromium.swangle.json b/testing/buildbot/chromium.swangle.json index 7b32bac..0ecd4bd 100644 --- a/testing/buildbot/chromium.swangle.json +++ b/testing/buildbot/chromium.swangle.json
@@ -23,8 +23,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -50,7 +49,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -76,7 +75,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -102,7 +101,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -154,6 +153,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -207,8 +231,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -234,7 +257,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -260,7 +283,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -286,7 +309,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -338,6 +361,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -391,8 +439,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -418,7 +465,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -444,7 +491,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -470,7 +517,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -522,6 +569,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -575,8 +647,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -602,7 +673,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -628,7 +699,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -654,7 +725,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -706,6 +777,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -759,8 +855,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -786,7 +881,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -812,7 +907,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -838,7 +933,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -890,6 +985,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -943,8 +1063,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -970,7 +1089,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -996,7 +1115,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -1022,7 +1141,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -1074,6 +1193,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "isolate_coverage_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-16.04" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -1127,8 +1271,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -1154,7 +1297,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -1180,7 +1323,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -1206,7 +1349,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -1258,6 +1401,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -1311,8 +1479,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -1338,7 +1505,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -1364,7 +1531,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -1390,7 +1557,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -1442,6 +1609,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -1495,8 +1687,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -1522,7 +1713,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -1548,7 +1739,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -1574,7 +1765,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -1626,6 +1817,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -1679,8 +1895,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -1706,7 +1921,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -1732,7 +1947,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -1758,7 +1973,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -1810,6 +2025,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -1863,8 +2103,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -1890,7 +2129,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -1916,7 +2155,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -1942,7 +2181,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -1994,6 +2233,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" }, @@ -2047,8 +2311,7 @@ ], "hard_timeout": 900, "io_timeout": 900, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "angle_deqp_egl_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_egl_tests" @@ -2074,7 +2337,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "angle_deqp_gles2_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles2_tests" @@ -2100,7 +2363,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 3 }, "test": "angle_deqp_gles31_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles31_tests" @@ -2126,7 +2389,7 @@ "hard_timeout": 900, "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 9 + "shards": 6 }, "test": "angle_deqp_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_gles3_tests" @@ -2178,6 +2441,31 @@ "io_timeout": 900, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, + "test": "angle_deqp_khr_gles31_tests", + "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles31_tests" + }, + { + "args": [ + "--deqp-egl-display-type=angle-swiftshader", + "--test-launcher-batch-limit=512", + "--test-launcher-retry-limit=0" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "cpu": "x86-64", + "os": "Windows-10-15063" + } + ], + "hard_timeout": 900, + "io_timeout": 900, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, "test": "angle_deqp_khr_gles3_tests", "test_target": "//third_party/angle/src/tests:angle_deqp_khr_gles3_tests" },
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index c6dbb63c..f148b79 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -3493,9 +3493,6 @@ '--test-launcher-batch-limit=512', '--test-launcher-retry-limit=0', ], - 'swarming': { - 'shards': 2, - }, }, 'angle_deqp_gles2_tests': { 'args': [ @@ -3504,7 +3501,7 @@ '--test-launcher-retry-limit=0', ], 'swarming': { - 'shards': 3, + 'shards': 2, }, }, 'angle_deqp_gles31_tests': { @@ -3514,7 +3511,7 @@ '--test-launcher-retry-limit=0', ], 'swarming': { - 'shards': 4, + 'shards': 3, }, }, 'angle_deqp_gles3_tests': { @@ -3524,7 +3521,7 @@ '--test-launcher-retry-limit=0', ], 'swarming': { - 'shards': 9, + 'shards': 6, }, }, 'angle_deqp_khr_gles2_tests': { @@ -3534,6 +3531,13 @@ '--test-launcher-retry-limit=0', ], }, + 'angle_deqp_khr_gles31_tests': { + 'args': [ + '--deqp-egl-display-type=angle-swiftshader', + '--test-launcher-batch-limit=512', + '--test-launcher-retry-limit=0', + ], + }, 'angle_deqp_khr_gles3_tests': { 'args': [ '--deqp-egl-display-type=angle-swiftshader',
diff --git a/third_party/blink/renderer/bindings/scripts/utilities.py b/third_party/blink/renderer/bindings/scripts/utilities.py index 674a35e..8529b5a 100644 --- a/third_party/blink/renderer/bindings/scripts/utilities.py +++ b/third_party/blink/renderer/bindings/scripts/utilities.py
@@ -7,13 +7,16 @@ """ import os -import cPickle as pickle import re import shlex -import string import subprocess import sys +if sys.version_info.major == 2: + import cPickle as pickle +else: + import pickle + sys.path.append( os.path.join(os.path.dirname(__file__), '..', '..', 'build', 'scripts')) from blinkbuild.name_style_converter import NameStyleConverter @@ -351,7 +354,7 @@ except Exception: # If trouble unpickling, overwrite pass - with open(pickle_filename, 'w') as pickle_file: + with open(pickle_filename, 'wb') as pickle_file: pickle.dump(data, pickle_file) @@ -433,7 +436,7 @@ if parences < 0 or square_brackets < 0: raise ValueError('You have more close braces than open braces.') if parences == 0 and square_brackets == 0: - name, _, value = map(string.strip, concatenated.partition('=')) + name, _, value = map(str.strip, concatenated.partition('=')) extended_attributes[name] = value concatenated = None return extended_attributes @@ -450,7 +453,7 @@ if not match: return None arguments = [] - for argument in map(string.strip, match.group(1).split(',')): + for argument in map(str.strip, match.group(1).split(',')): exposed, runtime_enabled = argument.split() arguments.append({ 'exposed': exposed,
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/file_io.py b/third_party/blink/renderer/bindings/scripts/web_idl/file_io.py index b5e8418..19e3327a 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/file_io.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/file_io.py
@@ -3,7 +3,12 @@ # found in the LICENSE file. import os -import cPickle as pickle # 'cPickle' is faster than 'pickle' +import sys + +if sys.version_info.major == 2: + import cPickle as pickle # 'cPickle' is faster than 'pickle' on Py2 +else: + import pickle def read_pickle_file(filepath):
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py b/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py index 7e4d9af..4184196 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/idl_type.py
@@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import exceptions import functools from blinkbuild.name_style_converter import NameStyleConverter @@ -178,7 +177,7 @@ return not self == other def __hash__(self): - raise exceptions.NotImplementedError() + raise NotImplementedError() def make_copy(self, memo): return self @@ -188,7 +187,7 @@ """ Returns a text representation of the type in the form of Web IDL syntax. """ - raise exceptions.NotImplementedError() + raise NotImplementedError() @property def type_name(self): @@ -213,7 +212,7 @@ @property def type_name_without_extended_attributes(self): - raise exceptions.NotImplementedError() + raise NotImplementedError() @property def keyword_typename(self):
diff --git a/third_party/blink/renderer/build/scripts/make_runtime_features.py b/third_party/blink/renderer/build/scripts/make_runtime_features.py index 320177e..cafe8d94 100755 --- a/third_party/blink/renderer/build/scripts/make_runtime_features.py +++ b/third_party/blink/renderer/build/scripts/make_runtime_features.py
@@ -28,10 +28,14 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import copy -import cPickle as pickle import os import sys +if sys.version_info.major == 2: + import cPickle as pickle +else: + import pickle + from blinkbuild.name_style_converter import NameStyleConverter import make_runtime_features_utilities as util import json5_generator
diff --git a/third_party/blink/renderer/core/DEPS b/third_party/blink/renderer/core/DEPS index 19b8fe3..391a212 100644 --- a/third_party/blink/renderer/core/DEPS +++ b/third_party/blink/renderer/core/DEPS
@@ -57,7 +57,6 @@ "+cc/trees/browser_controls_params.h", "+cc/trees/layer_tree_host.h", "+cc/trees/paint_holding_commit_trigger.h", - "+cc/trees/layer_tree_host.h", "+components/performance_manager/public/mojom/coordination_unit.mojom-blink.h", "+gpu/config/gpu_feature_info.h", "-inspector/v8",
diff --git a/third_party/blink/renderer/core/css/css_font_face_source.cc b/third_party/blink/renderer/core/css/css_font_face_source.cc index b89ad04..5084426 100644 --- a/third_party/blink/renderer/core/css/css_font_face_source.cc +++ b/third_party/blink/renderer/core/css/css_font_face_source.cc
@@ -84,7 +84,7 @@ void CSSFontFaceSource::PruneOldestIfNeeded() { if (font_cache_key_age.size() > kMaxCachedFontData) { DCHECK_EQ(font_cache_key_age.size() - 1, kMaxCachedFontData); - FontCacheKey& key = font_cache_key_age.back(); + const FontCacheKey& key = font_cache_key_age.back(); auto font_data_entry = font_data_table_.Take(key); font_cache_key_age.pop_back(); DCHECK_EQ(font_cache_key_age.size(), kMaxCachedFontData);
diff --git a/third_party/blink/renderer/core/editing/finder/find_task_controller.cc b/third_party/blink/renderer/core/editing/finder/find_task_controller.cc index a44846b..532a4a9 100644 --- a/third_party/blink/renderer/core/editing/finder/find_task_controller.cc +++ b/third_party/blink/renderer/core/editing/finder/find_task_controller.cc
@@ -56,6 +56,8 @@ void Invoke() { const base::TimeTicks task_start_time = base::TimeTicks::Now(); + if (!controller_) + return; if (!controller_->ShouldFindMatches(identifier_, search_text_, *options_)) { controller_->DidFinishTask(identifier_, search_text_, *options_, true /* finished_whole_request */, @@ -64,20 +66,21 @@ } SCOPED_UMA_HISTOGRAM_TIMER("WebCore.FindInPage.TaskDuration"); + Document* document = controller_->GetLocalFrame()->GetDocument(); + if (!document || document_ != document) + return; Document::ScopedForceActivatableDisplayLocks forced_activatable_display_locks( - controller_->GetLocalFrame() - ->GetDocument() - ->GetScopedForceActivatableLocks()); - Document& document = *controller_->GetLocalFrame()->GetDocument(); + document->GetScopedForceActivatableLocks()); PositionInFlatTree search_start = - PositionInFlatTree::FirstPositionInNode(document); + PositionInFlatTree::FirstPositionInNode(*document); PositionInFlatTree search_end; - if (document.documentElement() && document.documentElement()->lastChild()) { + if (document->documentElement() && + document->documentElement()->lastChild()) { search_end = PositionInFlatTree::AfterNode( - *document.documentElement()->lastChild()); + *document->documentElement()->lastChild()); } else { - search_end = PositionInFlatTree::LastPositionInNode(document); + search_end = PositionInFlatTree::LastPositionInNode(*document); } DCHECK_EQ(search_start.GetDocument(), search_end.GetDocument()); @@ -92,8 +95,7 @@ } // This is required if we forced any of the display-locks. - search_start.GetDocument()->UpdateStyleAndLayout( - DocumentUpdateReason::kFindInPage); + document->UpdateStyleAndLayout(DocumentUpdateReason::kFindInPage); int match_count = 0; bool full_range_searched = false; @@ -208,6 +210,8 @@ int match_count, bool aborted, base::TimeTicks task_start_time) { + if (current_find_identifier_ != identifier) + return; total_task_duration_for_current_request_ += base::TimeTicks::Now() - task_start_time; if (find_task_) @@ -236,13 +240,11 @@ text_finder_->FinishCurrentScopingEffort(identifier); - if (identifier == current_find_identifier_) { - RecordRequestMetrics(RequestEndState::ABORTED); - last_find_request_completed_with_no_matches_ = - !aborted && !current_match_count_; - finding_in_progress_ = false; - current_find_identifier_ = kInvalidFindIdentifier; - } + RecordRequestMetrics(RequestEndState::ABORTED); + last_find_request_completed_with_no_matches_ = + !aborted && !current_match_count_; + finding_in_progress_ = false; + current_find_identifier_ = kInvalidFindIdentifier; } void FindTaskController::RecordRequestMetrics( @@ -281,10 +283,10 @@ const mojom::blink::FindOptions& options) { if (identifier != current_find_identifier_) return false; - // Don't scope if we can't find a frame or a view. + // Don't scope if we can't find a frame, a document, or a view. // The user may have closed the tab/application, so abort. LocalFrame* frame = GetLocalFrame(); - if (!frame || !frame->View() || !frame->GetPage()) + if (!frame || !frame->View() || !frame->GetPage() || !frame->GetDocument()) return false; DCHECK(frame->GetDocument());
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index ded89456..aa998a1 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2661,7 +2661,7 @@ AnchoringAdjustmentQueue queue_copy = anchoring_adjustment_queue_; anchoring_adjustment_queue_.clear(); - for (WeakMember<ScrollableArea>& scroller : queue_copy) { + for (const WeakMember<ScrollableArea>& scroller : queue_copy) { if (scroller) { DCHECK(scroller->GetScrollAnchor()); scroller->GetScrollAnchor()->Adjust(); @@ -2671,7 +2671,7 @@ void LocalFrameView::EnqueueScrollEvents() { ForAllNonThrottledLocalFrameViews([](LocalFrameView& frame_view) { - for (WeakMember<PaintLayerScrollableArea>& scroller : + for (const WeakMember<PaintLayerScrollableArea>& scroller : frame_view.scroll_event_queue_) { if (scroller) scroller->EnqueueScrollEventIfNeeded();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc index b76fe8c..0824e067 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc
@@ -621,9 +621,6 @@ min_max_sizes_in_main_axis_direction.min_size = table_preferred_widths.min_size; } else { - // TODO(dgrogan): Do the aspect ratio parts of - // https://www.w3.org/TR/css-flexbox-1/#min-size-auto - LayoutUnit content_size_suggestion; if (MainAxisIsInlineAxis(child)) { content_size_suggestion = MinMaxSizesFunc().min_size; @@ -647,9 +644,6 @@ content_size_suggestion = intrinsic_block_size; } - content_size_suggestion = - std::min(content_size_suggestion, - min_max_sizes_in_main_axis_direction.max_size); if (child.HasAspectRatio()) { // TODO(dgrogan): We're including borders/padding in both @@ -666,7 +660,7 @@ min_max_sizes_in_cross_axis_direction.max_size); } - LayoutUnit specified_size_suggestion(LayoutUnit::Max()); + LayoutUnit specified_size_suggestion = LayoutUnit::Max(); // If the item’s computed main size property is definite, then the // specified size suggestion is that size. if (MainAxisIsInlineAxis(child)) { @@ -689,13 +683,42 @@ LengthResolvePhase::kLayout); DCHECK_NE(specified_size_suggestion, kIndefiniteSize); } - // Spec says to clamp specified_size_suggestion by max size but - // because content_size_suggestion already is, and we take the min of - // those two, we don't need to clamp specified_size_suggestion. - // https://github.com/w3c/csswg-drafts/issues/3669 + + LayoutUnit transferred_size_suggestion = LayoutUnit::Max(); + if (specified_size_suggestion == LayoutUnit::Max() && + child.HasAspectRatio()) { + const Length& cross_axis_length = is_horizontal_flow_ + ? child_style.Height() + : child_style.Width(); + if (IsItemCrossAxisLengthDefinite(child, cross_axis_length)) { + LayoutUnit cross_axis_size; + if (MainAxisIsInlineAxis(child)) { + cross_axis_size = ResolveMainBlockLength( + flex_basis_space, child_style, + border_padding_in_child_writing_mode, cross_axis_length, + kIndefiniteSize, LengthResolvePhase::kLayout); + DCHECK_NE(cross_axis_size, kIndefiniteSize); + } else { + cross_axis_size = ResolveMainInlineLength( + flex_basis_space, child_style, + border_padding_in_child_writing_mode, MinMaxSizesFunc, + cross_axis_length); + } + double ratio = GetMainOverCrossAspectRatio(child); + transferred_size_suggestion = LayoutUnit( + ratio * + min_max_sizes_in_cross_axis_direction.ClampSizeToMinAndMax( + cross_axis_size)); + } + } + + DCHECK(specified_size_suggestion == LayoutUnit::Max() || + transferred_size_suggestion == LayoutUnit::Max()); min_max_sizes_in_main_axis_direction.min_size = - std::min(specified_size_suggestion, content_size_suggestion); + std::min({specified_size_suggestion, content_size_suggestion, + transferred_size_suggestion, + min_max_sizes_in_main_axis_direction.max_size}); } } } else if (MainAxisIsInlineAxis(child)) {
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc index 1327dc4..6140bf3 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -345,7 +345,9 @@ cc::ScrollbarLayerBase* scrollbar_layer = GetScrollbarLayer(scrollable_area, orientation); - if (!scrollbar_layer) { + if (!scrollbar_layer || + scrollbar_layer->is_left_side_vertical_scrollbar() != + scrollable_area->ShouldPlaceVerticalScrollbarOnLeft()) { scoped_refptr<cc::ScrollbarLayerBase> new_scrollbar_layer; if (scrollbar.IsSolidColor()) { DCHECK(scrollbar.IsOverlayScrollbar());
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index 81fdd7e..c65b9739a 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -127,6 +127,7 @@ needs_composited_scrolling_(false), rebuild_horizontal_scrollbar_layer_(false), rebuild_vertical_scrollbar_layer_(false), + previous_vertical_scrollbar_on_left_(false), needs_scroll_offset_clamp_(false), needs_relayout_(false), had_horizontal_scrollbar_before_relayout_(false), @@ -1335,6 +1336,14 @@ VerticalScrollbar()->StyleChanged(); UpdateScrollCornerStyle(); + + if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + bool vertical_scrollbar_on_left = ShouldPlaceVerticalScrollbarOnLeft(); + if (vertical_scrollbar_on_left != previous_vertical_scrollbar_on_left_) { + rebuild_vertical_scrollbar_layer_ = true; + previous_vertical_scrollbar_on_left_ = vertical_scrollbar_on_left; + } + } } void PaintLayerScrollableArea::UpdateAfterOverflowRecalc() {
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h index 448dcd8..ef47d22 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -695,6 +695,7 @@ // instance has been reconstructed. unsigned rebuild_horizontal_scrollbar_layer_ : 1; unsigned rebuild_vertical_scrollbar_layer_ : 1; + unsigned previous_vertical_scrollbar_on_left_ : 1; unsigned needs_scroll_offset_clamp_ : 1; unsigned needs_relayout_ : 1;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.idl b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.idl index f682516..997333f 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.idl +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.idl
@@ -8,4 +8,6 @@ required unsigned long source; double audioLevel; required unsigned long rtpTimestamp; + // https://w3c.github.io/webrtc-extensions/#dom-rtcrtpcontributingsource-capturetimestamp + [RuntimeEnabled=CaptureTimeInCsrc] DOMHighResTimeStamp captureTimestamp; };
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc index 5816763..ed576047 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -120,6 +120,10 @@ synchronization_source->setSource(web_source->Source()); if (web_source->AudioLevel()) synchronization_source->setAudioLevel(*web_source->AudioLevel()); + if (web_source->CaptureTimestamp()) { + synchronization_source->setCaptureTimestamp( + *web_source->CaptureTimestamp()); + } synchronization_source->setRtpTimestamp(web_source->RtpTimestamp()); synchronization_sources.push_back(synchronization_source); } @@ -147,6 +151,9 @@ contributing_source->setSource(web_source->Source()); if (web_source->AudioLevel()) contributing_source->setAudioLevel(*web_source->AudioLevel()); + if (web_source->CaptureTimestamp()) { + contributing_source->setCaptureTimestamp(*web_source->CaptureTimestamp()); + } contributing_source->setRtpTimestamp(web_source->RtpTimestamp()); contributing_sources.push_back(contributing_source); }
diff --git a/third_party/blink/renderer/platform/fonts/font_data_cache.cc b/third_party/blink/renderer/platform/fonts/font_data_cache.cc index d99cae2..680da16 100644 --- a/third_party/blink/renderer/platform/fonts/font_data_cache.cc +++ b/third_party/blink/renderer/platform/fonts/font_data_cache.cc
@@ -132,7 +132,7 @@ auto end = inactive_font_data_.end(); auto it = inactive_font_data_.begin(); for (int i = 0; i < count && it != end; ++it, ++i) { - scoped_refptr<SimpleFontData>& font_data = *it; + const scoped_refptr<SimpleFontData>& font_data = *it; cache_.erase(&(font_data->PlatformData())); // We should not delete SimpleFontData here because deletion can modify // m_inactiveFontData. See http://trac.webkit.org/changeset/44011
diff --git a/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc b/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc index 522197a..eeb5932 100644 --- a/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc +++ b/third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.cc
@@ -60,7 +60,8 @@ // record_ which is for non-composited scrollbars. record_ = nullptr; - if (!layer_) + if (!layer_ || layer_->is_left_side_vertical_scrollbar() != + scrollbar_->IsLeftSideVerticalScrollbar()) layer_ = CreateLayer(); layer_->SetOffsetToTransformParent(
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc index fc74d61..bc9a3c0 100644 --- a/third_party/blink/renderer/platform/heap/heap_test.cc +++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -3129,7 +3129,7 @@ ClearOutOldGarbage(); OrderedSetHelper<HeapListHashSet<Member<IntWrapper>>>(true); ClearOutOldGarbage(); - // TODO(keinakashiima): add a test case for WeakMember once it's supported + // TODO(keinakashima): add a test case for WeakMember once it's supported OrderedSetHelper<HeapNewLinkedHashSet<Member<IntWrapper>>>(true); } @@ -3258,6 +3258,7 @@ typedef HeapLinkedHashSet<PairWeakUnwrapped> WeakUnwrappedLinkedSet; typedef HeapLinkedHashSet<PairStrongWeak> StrongWeakLinkedSet; typedef HeapLinkedHashSet<PairUnwrappedWeak> UnwrappedWeakLinkedSet; +// TODO(bartekn): add HeapNewLinkedHashSet cases once WeakMember is supported typedef HeapHashCountedSet<PairWeakStrong> WeakStrongCountedSet; typedef HeapHashCountedSet<PairWeakUnwrapped> WeakUnwrappedCountedSet; typedef HeapHashCountedSet<PairStrongWeak> StrongWeakCountedSet; @@ -3338,6 +3339,7 @@ typedef HeapHashMap<WeakMember<IntWrapper>, WeakMember<IntWrapper>> WeakWeak; typedef HeapHashSet<WeakMember<IntWrapper>> WeakSet; typedef HeapLinkedHashSet<WeakMember<IntWrapper>> WeakOrderedSet; + // TODO(bartekn): add HeapNewLinkedHashSet case once WeakMember is supported ClearOutOldGarbage(); @@ -5305,6 +5307,8 @@ using P = HeapVector<Member<HeapLinkedHashSet<Member<IntWrapper>>>>; MakeGarbageCollected<P>(); + using Q = HeapVector<Member<HeapNewLinkedHashSet<Member<IntWrapper>>>>; + MakeGarbageCollected<Q>(); } TEST_F(HeapTest, PersistentAssignsDeletedValue) {
diff --git a/third_party/blink/renderer/platform/heap/incremental_marking_test.cc b/third_party/blink/renderer/platform/heap/incremental_marking_test.cc index e9ce9fd..5132cc58 100644 --- a/third_party/blink/renderer/platform/heap/incremental_marking_test.cc +++ b/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
@@ -1813,11 +1813,12 @@ size_t Destructed::n_destructed = 0; -class Wrapper final : public GarbageCollected<Wrapper> { +class LinkedHashSetWrapper final + : public GarbageCollected<LinkedHashSetWrapper> { public: using HashType = HeapLinkedHashSet<Member<Destructed>>; - Wrapper() { + LinkedHashSetWrapper() { for (size_t i = 0; i < 10; ++i) { hash_set_.insert(MakeGarbageCollected<Destructed>()); } @@ -1833,7 +1834,7 @@ HashType hash_set_; }; -TEST_F(IncrementalMarkingTest, MovingCallback) { +TEST_F(IncrementalMarkingTest, LinkedHashSetMovingCallback) { ClearOutOldGarbage(); Destructed::n_destructed = 0; @@ -1841,14 +1842,15 @@ HeapHashSet<Member<Destructed>> to_be_destroyed; to_be_destroyed.ReserveCapacityForSize(100); } - Persistent<Wrapper> wrapper = MakeGarbageCollected<Wrapper>(); + Persistent<LinkedHashSetWrapper> wrapper = + MakeGarbageCollected<LinkedHashSetWrapper>(); IncrementalMarkingTestDriver driver(ThreadState::Current()); ThreadState::Current()->EnableCompactionForNextGCForTesting(); driver.Start(); driver.FinishSteps(); - // Destroy the link between original HeapLinkedHashSet object and its backign + // Destroy the link between original HeapLinkedHashSet object and its backing // store. wrapper->Swap(); DCHECK(wrapper->hash_set_.IsEmpty()); @@ -1858,5 +1860,52 @@ EXPECT_EQ(10u, Destructed::n_destructed); } +class NewLinkedHashSetWrapper final + : public GarbageCollected<NewLinkedHashSetWrapper> { + public: + using HashType = HeapNewLinkedHashSet<Member<Destructed>>; + + NewLinkedHashSetWrapper() { + for (size_t i = 0; i < 10; ++i) { + hash_set_.insert(MakeGarbageCollected<Destructed>()); + } + } + + void Trace(Visitor* v) { v->Trace(hash_set_); } + + void Swap() { + HashType hash_set; + hash_set_.Swap(hash_set); + } + + HashType hash_set_; +}; + +TEST_F(IncrementalMarkingTest, NewLinkedHashSetMovingCallback) { + ClearOutOldGarbage(); + + Destructed::n_destructed = 0; + { + HeapHashSet<Member<Destructed>> to_be_destroyed; + to_be_destroyed.ReserveCapacityForSize(100); + } + Persistent<NewLinkedHashSetWrapper> wrapper = + MakeGarbageCollected<NewLinkedHashSetWrapper>(); + + IncrementalMarkingTestDriver driver(ThreadState::Current()); + ThreadState::Current()->EnableCompactionForNextGCForTesting(); + driver.Start(); + driver.FinishSteps(); + + // Destroy the link between original NewHeapLinkedHashSet object and its + // backing store. + wrapper->Swap(); + DCHECK(wrapper->hash_set_.IsEmpty()); + + PreciselyCollectGarbage(); + + EXPECT_EQ(10u, Destructed::n_destructed); +} + } // namespace incremental_marking_test } // namespace blink
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc b/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc index be6a3c8..704a4e90 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.cc
@@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/time/time.h" #include "third_party/webrtc/api/scoped_refptr.h" +#include "third_party/webrtc/system_wrappers/include/ntp_time.h" namespace blink { @@ -54,4 +55,11 @@ return source_.rtp_timestamp(); } +base::Optional<int64_t> RTCRtpSource::CaptureTimestamp() const { + if (!source_.absolute_capture_time()) + return base::nullopt; + return webrtc::UQ32x32ToInt64Ms( + source_.absolute_capture_time()->absolute_capture_timestamp); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h b/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h index a36dd37..551ac0b 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h +++ b/third_party/blink/renderer/platform/peerconnection/rtc_rtp_source.h
@@ -35,6 +35,7 @@ uint32_t Source() const; base::Optional<double> AudioLevel() const; uint32_t RtpTimestamp() const; + base::Optional<int64_t> CaptureTimestamp() const; private: const webrtc::RtpSource source_;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index cd15281..e1637b6e7 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -292,6 +292,10 @@ status: "experimental", }, { + name: "CaptureTimeInCsrc", + status: "test", + }, + { name: "ClickPointerEvent", status: "experimental", },
diff --git a/third_party/blink/renderer/platform/wtf/linked_hash_set.h b/third_party/blink/renderer/platform/wtf/linked_hash_set.h index 7a6c369..7be2da08 100644 --- a/third_party/blink/renderer/platform/wtf/linked_hash_set.h +++ b/third_party/blink/renderer/platform/wtf/linked_hash_set.h
@@ -51,12 +51,8 @@ class LinkedHashSet; template <typename LinkedHashSet> -class LinkedHashSetIterator; -template <typename LinkedHashSet> class LinkedHashSetConstIterator; template <typename LinkedHashSet> -class LinkedHashSetReverseIterator; -template <typename LinkedHashSet> class LinkedHashSetConstReverseIterator; template <typename Value, typename HashFunctions> @@ -233,13 +229,11 @@ ImplType; public: - typedef LinkedHashSetIterator<LinkedHashSet> iterator; - friend class LinkedHashSetIterator<LinkedHashSet>; + typedef LinkedHashSetConstIterator<LinkedHashSet> iterator; typedef LinkedHashSetConstIterator<LinkedHashSet> const_iterator; friend class LinkedHashSetConstIterator<LinkedHashSet>; - typedef LinkedHashSetReverseIterator<LinkedHashSet> reverse_iterator; - friend class LinkedHashSetReverseIterator<LinkedHashSet>; + typedef LinkedHashSetConstReverseIterator<LinkedHashSet> reverse_iterator; typedef LinkedHashSetConstReverseIterator<LinkedHashSet> const_reverse_iterator; friend class LinkedHashSetConstReverseIterator<LinkedHashSet>; @@ -252,7 +246,7 @@ : stored_value(&hash_table_add_result.stored_value->value_), is_new_entry(hash_table_add_result.is_new_entry) {} - Value* stored_value; + const Value* stored_value; bool is_new_entry; }; @@ -340,13 +334,13 @@ AddResult InsertBefore(ValuePeekInType before_value, IncomingValueType&& new_value); template <typename IncomingValueType> - AddResult InsertBefore(iterator it, IncomingValueType&& new_value) { + AddResult InsertBefore(const_iterator it, IncomingValueType&& new_value) { return impl_.template insert<NodeHashFunctions>( std::forward<IncomingValueType>(new_value), it.GetNode()); } void erase(ValuePeekInType); - void erase(iterator); + void erase(const_iterator); void clear() { impl_.clear(); } template <typename Collection> void RemoveAll(const Collection& other) { @@ -565,59 +559,6 @@ }; template <typename LinkedHashSetType> -class LinkedHashSetIterator { - DISALLOW_NEW(); - - private: - typedef typename LinkedHashSetType::Node Node; - typedef typename LinkedHashSetType::Traits Traits; - - typedef typename LinkedHashSetType::Value& ReferenceType; - typedef typename LinkedHashSetType::Value* PointerType; - - typedef LinkedHashSetConstIterator<LinkedHashSetType> const_iterator; - - Node* GetNode() { return const_cast<Node*>(iterator_.GetNode()); } - - protected: - LinkedHashSetIterator(const Node* position, LinkedHashSetType* container) - : iterator_(position, container) {} - - public: - // Default copy, assignment and destructor are OK. - - PointerType Get() const { return const_cast<PointerType>(iterator_.Get()); } - ReferenceType operator*() const { return *Get(); } - PointerType operator->() const { return Get(); } - - LinkedHashSetIterator& operator++() { - ++iterator_; - return *this; - } - LinkedHashSetIterator& operator--() { - --iterator_; - return *this; - } - - // Postfix ++ and -- intentionally omitted. - - // Comparison. - bool operator==(const LinkedHashSetIterator& other) const { - return iterator_ == other.iterator_; - } - bool operator!=(const LinkedHashSetIterator& other) const { - return iterator_ != other.iterator_; - } - - operator const_iterator() const { return iterator_; } - - protected: - const_iterator iterator_; - template <typename T, typename U, typename V, typename W> - friend class LinkedHashSet; -}; - -template <typename LinkedHashSetType> class LinkedHashSetConstIterator { DISALLOW_NEW(); @@ -628,7 +569,9 @@ typedef const typename LinkedHashSetType::Value& ReferenceType; typedef const typename LinkedHashSetType::Value* PointerType; - const Node* GetNode() const { return static_cast<const Node*>(position_); } + Node* GetNode() const { + return const_cast<Node*>(static_cast<const Node*>(position_)); + } protected: LinkedHashSetConstIterator(const LinkedHashSetNodeBase* position, @@ -687,42 +630,6 @@ #endif template <typename T, typename U, typename V, typename W> friend class LinkedHashSet; - friend class LinkedHashSetIterator<LinkedHashSetType>; -}; - -template <typename LinkedHashSetType> -class LinkedHashSetReverseIterator - : public LinkedHashSetIterator<LinkedHashSetType> { - typedef LinkedHashSetReverseIterator<LinkedHashSetType> reverse_iterator; - typedef LinkedHashSetIterator<LinkedHashSetType> Superclass; - typedef LinkedHashSetConstReverseIterator<LinkedHashSetType> - const_reverse_iterator; - typedef typename LinkedHashSetType::Node Node; - - protected: - LinkedHashSetReverseIterator(const Node* position, - LinkedHashSetType* container) - : Superclass(position, container) {} - - public: - LinkedHashSetReverseIterator& operator++() { - Superclass::operator--(); - return *this; - } - LinkedHashSetReverseIterator& operator--() { - Superclass::operator++(); - return *this; - } - - // Postfix ++ and -- intentionally omitted. - - operator const_reverse_iterator() const { - return *reinterpret_cast<const_reverse_iterator*>( - const_cast<reverse_iterator*>(this)); - } - - template <typename T, typename U, typename V, typename W> - friend class LinkedHashSet; }; template <typename LinkedHashSetType> @@ -1010,7 +917,7 @@ } template <typename T, typename U, typename V, typename W> -inline void LinkedHashSet<T, U, V, W>::erase(iterator it) { +inline void LinkedHashSet<T, U, V, W>::erase(const_iterator it) { if (it == end()) return; impl_.erase(it.GetNode());
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 42bd8042..7fceee1 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2938,6 +2938,43 @@ crbug.com/947951 [ Win ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch.html [ Pass Timeout ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Mac10.10 ] virtual/threaded/external/wpt/css/css-scroll-snap/snap-after-initial-layout/writing-mode-vertical-rl.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/threaded/external/wpt/requestidlecallback/callback-invoked.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/threaded/external/wpt/css/css-animations/parsing/animation-shorthand.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/semantics/forms/the-input-element/input-type-checkbox.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/semantics/forms/constraints/form-validation-validity-stepMismatch.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-interface.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-empty-cue.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/characteristic/readValue/read-updates-value.https.window.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/dom/events/Event-dispatch-throwing.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/device/gattserverdisconnected-event/reconnect-during-disconnected-event.https.window.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-disabled-scrollbar-tentative.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/requestDevice/canonicalizeFilter/max-length-exceeded-name-unicode.https.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-name.https.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-same.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/threaded/external/wpt/css/css-scroll-snap/snap-to-visible-areas-both.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/server/getPrimaryServices/gen-disconnect-called-during-success.https.window.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/characteristic/getDescriptors/gen-service-is-removed-with-uuid.https.window.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-negative-timestamp-events.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/id.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/semantics/forms/the-input-element/range.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/semantics/forms/the-output-element/mutations.window.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/threaded/external/wpt/feature-policy/experimental-features/sync-script.tentative.https.sub.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/semantics/grouping-content/the-li-element/grouping-li-reftest-list-owner-ol.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/device/gattserverdisconnected-event/one-event-per-disconnection.https.window.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/semantics/embedded-content/media-elements/event_order_canplay_playing.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/dom/nodes/getElementsByClassName-26.htm [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/server/getPrimaryServices/gen-service-not-found-with-uuid.https.window.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/threaded/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/semantics/embedded-content/media-elements/event_order_canplay_canplaythrough.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/service/getCharacteristics/gen-reconnect-during.https.window.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/semantics/interactive-elements/the-summary-element/activation-behavior.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/dom/nodes/getElementsByClassName-08.htm [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-bluetooth-new-permissions-backend/external/wpt/bluetooth/characteristic/startNotifications/gen-characteristic-is-removed.https.window.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/threaded/external/wpt/css/css-scroll-snap/snap-after-initial-layout/writing-mode-horizontal-tb.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/semantics/embedded-content/the-iframe-element/sandbox_016.htm [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/web-components-v0-disabled/external/wpt/html/dom/documents/dom-tree-accessors/nameditem-07.html [ Timeout ] +crbug.com/626703 [ Mac10.10 ] virtual/threaded/external/wpt/css/css-animations/CSSAnimation-canceling.tentative.html [ Timeout ] crbug.com/626703 [ Mac10.10 ] external/wpt/css/css-fonts/matching/range-descriptor-reversed.html [ Failure ] crbug.com/626703 [ Mac10.12 ] external/wpt/css/css-fonts/matching/range-descriptor-reversed.html [ Failure ] crbug.com/626703 [ Linux ] external/wpt/editing/run/caretnavigation.html [ Timeout ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_7.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_7.json index 057ed5e..33fe265 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_7.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_7.json
@@ -276,6 +276,12 @@ "svg/svg-in-svg/svg-in-svg-circular-filter-reference-crash.html", {} ] + ], + "svg/text/reftests/text-display-contents-crash.html": [ + [ + "svg/text/reftests/text-display-contents-crash.html", + {} + ] ] }, "manual": { @@ -45909,6 +45915,30 @@ {} ] ], + "css/css-flexbox/flex-minimum-height-flex-items-020.html": [ + [ + "css/css-flexbox/flex-minimum-height-flex-items-020.html", + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], + "css/css-flexbox/flex-minimum-height-flex-items-021.html": [ + [ + "css/css-flexbox/flex-minimum-height-flex-items-021.html", + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "css/css-flexbox/flex-minimum-width-flex-items-001.xht": [ [ "css/css-flexbox/flex-minimum-width-flex-items-001.xht", @@ -46029,6 +46059,42 @@ {} ] ], + "css/css-flexbox/flex-minimum-width-flex-items-011.html": [ + [ + "css/css-flexbox/flex-minimum-width-flex-items-011.html", + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], + "css/css-flexbox/flex-minimum-width-flex-items-012.html": [ + [ + "css/css-flexbox/flex-minimum-width-flex-items-012.html", + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], + "css/css-flexbox/flex-minimum-width-flex-items-013.html": [ + [ + "css/css-flexbox/flex-minimum-width-flex-items-013.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "css/css-flexbox/flex-order.html": [ [ "css/css-flexbox/flex-order.html", @@ -46341,6 +46407,18 @@ {} ] ], + "css/css-flexbox/flexbox-overflow-auto-001.html": [ + [ + "css/css-flexbox/flexbox-overflow-auto-001.html", + [ + [ + "/css/css-flexbox/reference/flexbox-overflow-auto-001-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-flexbox/flexbox_absolute-atomic.html": [ [ "css/css-flexbox/flexbox_absolute-atomic.html", @@ -123461,6 +123539,30 @@ {} ] ], + "html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-aspect-ratio.html": [ + [ + "html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-aspect-ratio.html", + [ + [ + "/html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-aspect-ratio-ref.html", + "==" + ] + ], + {} + ] + ], + "html/semantics/embedded-content/the-img-element/image-loading-lazy-slow.html": [ + [ + "html/semantics/embedded-content/the-img-element/image-loading-lazy-slow.html", + [ + [ + "/html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-ref.html", + "==" + ] + ], + {} + ] + ], "html/semantics/embedded-content/the-img-element/image-loading-subpixel-clip.html": [ [ "html/semantics/embedded-content/the-img-element/image-loading-subpixel-clip.html", @@ -136679,12 +136781,21 @@ "credential-management/passwordcredential-framed-get.sub.https-expected.txt": [ [] ], + "credential-management/support/README.md": [ + [] + ], "credential-management/support/echoing-nester.html": [ [] ], "credential-management/support/federatedcredential-get.html": [ [] ], + "credential-management/support/otpcredential-helper.js": [ + [] + ], + "credential-management/support/otpcredential-iframe.html": [ + [] + ], "credential-management/support/passwordcredential-get.html": [ [] ], @@ -142262,6 +142373,9 @@ "css/css-flexbox/reference/flexbox-flex-wrap-nowrap-ref.htm": [ [] ], + "css/css-flexbox/reference/flexbox-overflow-auto-001-ref.html": [ + [] + ], "css/css-flexbox/reference/flexbox_quirks_body-ref.html": [ [] ], @@ -171053,6 +171167,12 @@ "html/semantics/embedded-content/the-img-element/image-loading-lazy-move-document-expected.txt": [ [] ], + "html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-aspect-ratio-ref.html": [ + [] + ], + "html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-ref.html": [ + [] + ], "html/semantics/embedded-content/the-img-element/image-loading-subpixel-clip-ref.html": [ [] ], @@ -178019,6 +178139,9 @@ "resources/chromium/mock-imagecapture.js": [ [] ], + "resources/chromium/mock-sms-receiver.js": [ + [] + ], "resources/chromium/mojo_bindings.js": [ [] ], @@ -186527,6 +186650,9 @@ "webaudio/the-audio-api/the-audioparam-interface/retrospective-test.js": [ [] ], + "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-iterable.https-expected.txt": [ + [] + ], "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-postmessage-sharedarraybuffer.https.html.headers": [ [] ], @@ -215682,6 +215808,18 @@ } ] ], + "credential-management/otpcredential-get-basics.https.html": [ + [ + "credential-management/otpcredential-get-basics.https.html", + {} + ] + ], + "credential-management/otpcredential-iframe.https.html": [ + [ + "credential-management/otpcredential-iframe.https.html", + {} + ] + ], "credential-management/passwordcredential-framed-get.sub.https.html": [ [ "credential-management/passwordcredential-framed-get.sub.https.html", @@ -218720,6 +218858,18 @@ {} ] ], + "css/css-flexbox/flex-minimum-size-002.html": [ + [ + "css/css-flexbox/flex-minimum-size-002.html", + {} + ] + ], + "css/css-flexbox/flex-outer-flexbox-column-recalculate-height-on-resize-001.html": [ + [ + "css/css-flexbox/flex-outer-flexbox-column-recalculate-height-on-resize-001.html", + {} + ] + ], "css/css-flexbox/flexbox-overflow-auto-002.html": [ [ "css/css-flexbox/flexbox-overflow-auto-002.html", @@ -219230,12 +219380,24 @@ {} ] ], + "css/css-flexbox/justify-content_space-between-002.html": [ + [ + "css/css-flexbox/justify-content_space-between-002.html", + {} + ] + ], "css/css-flexbox/order_value.html": [ [ "css/css-flexbox/order_value.html", {} ] ], + "css/css-flexbox/overflow-auto-002.html": [ + [ + "css/css-flexbox/overflow-auto-002.html", + {} + ] + ], "css/css-flexbox/parsing/flex-basis-computed.html": [ [ "css/css-flexbox/parsing/flex-basis-computed.html", @@ -226272,6 +226434,24 @@ {} ] ], + "css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-computed.html": [ + [ + "css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-computed.html", + {} + ] + ], + "css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-invalid.html": [ + [ + "css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-invalid.html", + {} + ] + ], + "css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-valid.html": [ + [ + "css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-valid.html", + {} + ] + ], "css/css-sizing/button-min-width.html": [ [ "css/css-sizing/button-min-width.html", @@ -321214,6 +321394,12 @@ {} ] ], + "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-iterable.https.html": [ + [ + "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-iterable.https.html", + {} + ] + ], "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-size.https.html": [ [ "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-size.https.html", @@ -339218,6 +339404,12 @@ {} ] ], + "css/css-sizing/replaced-fractional-height-from-aspect-ratio.html": [ + [ + "css/css-sizing/replaced-fractional-height-from-aspect-ratio.html", + {} + ] + ], "css/css-text-decor/text-decoration-visibility-001.xht": [ [ "css/css-text-decor/text-decoration-visibility-001.xht", @@ -357485,6 +357677,14 @@ "789643e2369fca0baed12579bc0cfb23f943f61e", "testharness" ], + "credential-management/otpcredential-get-basics.https.html": [ + "aca48227ce839afcc805c02b18e3d3dcde50f31e", + "testharness" + ], + "credential-management/otpcredential-iframe.https.html": [ + "8af17b599612e3750f3094270be8e9cd9a109290", + "testharness" + ], "credential-management/passwordcredential-framed-get.sub.https-expected.txt": [ "b58767080c33af12e82638869ef395346ca509e5", "support" @@ -357497,6 +357697,10 @@ "b1f3103da06e2ba2243f8e2107666abb42ccfdce", "testharness" ], + "credential-management/support/README.md": [ + "cacd959d02629b3f665ee51eb65b8b5a4115a49c", + "support" + ], "credential-management/support/echoing-nester.html": [ "d4f5899da7894749a51039f9d5bf3b8bfd680570", "support" @@ -357505,6 +357709,14 @@ "476f32688f91cede949edf2a1e650ef573525bd7", "support" ], + "credential-management/support/otpcredential-helper.js": [ + "d5a7eb8c4715f08031933391b953ac32b43443d1", + "support" + ], + "credential-management/support/otpcredential-iframe.html": [ + "37fe6e1cd891b3f1c4500a0c09b0f6d2c603bccf", + "support" + ], "credential-management/support/passwordcredential-get.html": [ "0ec584d73d1f6d8626efe4c7190e5160fe527286", "support" @@ -376782,11 +376994,11 @@ "testharness" ], "css/css-backgrounds/parsing/background-image-computed.sub-expected.txt": [ - "93cf4bde801dff8a3e8281c4ec3b41a5ae36fab8", + "16890895d53604b322beda4531e64c6d1b728aba", "support" ], "css/css-backgrounds/parsing/background-image-computed.sub.html": [ - "ff2f34a2c661fcfc246f939b65ca81cf29c850a3", + "8ee18e20d1210394a18fa6794cf7ffab630db17d", "testharness" ], "css/css-backgrounds/parsing/background-image-invalid.html": [ @@ -382225,6 +382437,18 @@ "3572a6cc88e50ade3a8f7faff5a343bc84d9f581", "reftest" ], + "css/css-flexbox/flex-minimum-height-flex-items-020.html": [ + "dad3b6479685107439fb0bf37ebd21538a7abc6e", + "reftest" + ], + "css/css-flexbox/flex-minimum-height-flex-items-021.html": [ + "ed8d1d425180615aa0f5193f891c1c313438f79c", + "reftest" + ], + "css/css-flexbox/flex-minimum-size-002.html": [ + "c2eea80ca5b79818f6b7a9a36ab1ff64826b5218", + "testharness" + ], "css/css-flexbox/flex-minimum-width-flex-items-001.xht": [ "cd18483ba414160c46e30bc282dec0c2fcd2f418", "reftest" @@ -382265,6 +382489,18 @@ "8845b4896e58d47dac4fc8b25b9fc36b8d594521", "reftest" ], + "css/css-flexbox/flex-minimum-width-flex-items-011.html": [ + "0eb6c5fa49c4d5d4ac331a8ba6f194f53d717451", + "reftest" + ], + "css/css-flexbox/flex-minimum-width-flex-items-012.html": [ + "2ce9129eb1100bcbb94b5849d734af0bdd3c8ee1", + "reftest" + ], + "css/css-flexbox/flex-minimum-width-flex-items-013.html": [ + "6ee9ed10b5663b381f0238096117e8d70ca0347b", + "reftest" + ], "css/css-flexbox/flex-order-ref.html": [ "02f0eb35752e805aa2bc0bd339f73ff2b197c99e", "support" @@ -382273,6 +382509,10 @@ "be24b2817e232b7ad7fc936b7b22787591d3d9db", "reftest" ], + "css/css-flexbox/flex-outer-flexbox-column-recalculate-height-on-resize-001.html": [ + "0b0b5b4d4e5a9e8011d7fdee87cce9caba5fa241", + "testharness" + ], "css/css-flexbox/flex-shrink-001.html": [ "7427004a72c01e40a08ecf274a5e70ae8662e68e", "reftest" @@ -382389,6 +382629,10 @@ "b06f24cfd68f1740d49a869bbce00c9913041f48", "visual" ], + "css/css-flexbox/flexbox-overflow-auto-001.html": [ + "ee5a1afffbe04a9adf779fd5e590ed76167a431e", + "reftest" + ], "css/css-flexbox/flexbox-overflow-auto-002.html": [ "d69b297ef7301cfb46ea725d99aaa0f9dac3e126", "testharness" @@ -384553,6 +384797,10 @@ "7abfd4a6c3c3e9d80b2cea059ac7e2a5463523fe", "visual" ], + "css/css-flexbox/justify-content_space-between-002.html": [ + "fde1a7312408d02fe3843452585de2ee660ae6f7", + "testharness" + ], "css/css-flexbox/layout-algorithm_algo-cross-line-001.html": [ "7fcc96f3c0c07068a00ed6a3a8007d44cca021fb", "reftest" @@ -384593,6 +384841,10 @@ "08c1bdbafabad98e7d823c47246f455cc0861fef", "reftest" ], + "css/css-flexbox/overflow-auto-002.html": [ + "2bb04a2604076d0883c1322e60015316f6f34b10", + "testharness" + ], "css/css-flexbox/overflow-top-left-ref.html": [ "48b2aa88158b6301c7c7df3d7af84d9d96192761", "support" @@ -384921,6 +385173,10 @@ "413b5909fea7c8468db08d23eb7644a8d713a7bc", "support" ], + "css/css-flexbox/reference/flexbox-overflow-auto-001-ref.html": [ + "ace792e456c12f40e52ae50d51d05fd6a449a628", + "support" + ], "css/css-flexbox/reference/flexbox_quirks_body-ref.html": [ "164784fbd30859888b63069d9813eb5a104eb999", "support" @@ -397738,7 +397994,7 @@ "testharness" ], "css/css-images/parsing/gradient-position-valid.html": [ - "9857496fe4407fb0b9b4d6fe32ef9ed982c9cc88", + "d2e3ff072b0d9f1982411c935110b22d80893b18", "testharness" ], "css/css-images/parsing/image-orientation-computed.html": [ @@ -408545,6 +408801,18 @@ "0dbbb2f9404da7cfa89f2e75af3ca06cfbe4be7e", "testharness" ], + "css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-computed.html": [ + "3cd562fb9ce10a0f5c82b4884046c91e2b9428b0", + "testharness" + ], + "css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-invalid.html": [ + "523ba7269c76777cd314edeb195b5465bbccef4d", + "testharness" + ], + "css/css-sizing/aspect-ratio/parsing/contain-intrinsic-size-valid.html": [ + "d9341d8c15b0a4f7fac268d24b08109484cafe20", + "testharness" + ], "css/css-sizing/auto-scrollbar-inside-stf-abspos-ref.html": [ "076893b2728772662f06b9474bcc1918c860b480", "support" @@ -409129,6 +409397,10 @@ "f2c2431978b1596078f48727da0953f23e1f0d3e", "reftest" ], + "css/css-sizing/replaced-fractional-height-from-aspect-ratio.html": [ + "d97c3f133ebec02ce5569e95826ab3237b7559c7", + "visual" + ], "css/css-sizing/slice-intrinsic-size-ref.html": [ "f550f335e5b1808c6120218c593c6ddbf7a8d9dc", "support" @@ -473145,6 +473417,22 @@ "1458fb44b7849fed9792170638381a11a45d22ab", "testharness" ], + "html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-aspect-ratio-ref.html": [ + "6de01a9b3bbf19567555af2524f8950abdfb2d81", + "support" + ], + "html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-aspect-ratio.html": [ + "15df330835f16ad07ef2c350a17e2661db7bdaac", + "reftest" + ], + "html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-ref.html": [ + "20fbb9b50e99b8c0505d65618880b6d2130fa909", + "support" + ], + "html/semantics/embedded-content/the-img-element/image-loading-lazy-slow.html": [ + "15a3056f7ccd9d06483f4c9de5c82843b9f6f004", + "reftest" + ], "html/semantics/embedded-content/the-img-element/image-loading-lazy-subframe-detached-crash.html": [ "86a290d50db16d9f19d08bb8a9ad07b0aa52f66d", "crashtest" @@ -482426,7 +482714,7 @@ "support" ], "interfaces/resize-observer.idl": [ - "60d55a19bae8b156a99b1ad8a88089297ad409e4", + "f20b719d11e76cf92997a56061d0091895453f52", "support" ], "interfaces/resource-timing.idl": [ @@ -482602,7 +482890,7 @@ "support" ], "interfaces/webxr.idl": [ - "1b005c3cdb39667e55875d31a53f574ac8d388e3", + "5f5320c205598b2c8cec340326686f6589d14984", "support" ], "interfaces/worklets.idl": [ @@ -483266,7 +483554,7 @@ "testharness" ], "lint.whitelist": [ - "65494c70cfbf446011b404b5b657564b2ec61e35", + "7c282eefeabda7c3ce73e40f794123710219cf36", "support" ], "loading/preloader-css-import-no-quote.tentative.html": [ @@ -503530,7 +503818,7 @@ "testharness" ], "resize-observer/idlharness.window-expected.txt": [ - "e060e059911409cf4ade0e718adcaafeda93baae", + "ae5fde697e5cac55f700f7f3647a4d7867d6fd54", "support" ], "resize-observer/idlharness.window.js": [ @@ -504245,6 +504533,10 @@ "ce2b968391343339a9958100f564fa73d5c01509", "support" ], + "resources/chromium/mock-sms-receiver.js": [ + "c4aa9a86f2c8a15303f96cc9859b2ec146eb2f58", + "support" + ], "resources/chromium/mojo_bindings.js": [ "70f6cad5e5f06f4f64a0fd4cdcd693fcea12bb78", "support" @@ -513445,6 +513737,10 @@ "40b62ac95d66f2914c8a373332f567929e8d2aae", "reftest" ], + "svg/text/reftests/text-display-contents-crash.html": [ + "04b6a7e7cf8c6714f6c51c75ef6355102089428e", + "crashtest" + ], "svg/text/reftests/text-inline-size-001-ref.svg": [ "6abd211584ea3b500e409c0f0fa956182fe131e6", "support" @@ -523074,7 +523370,7 @@ "support" ], "webaudio/js/helpers.js": [ - "fbbfc8e00444dce1440fdbe8e28e11c5b064ce3d", + "3819d12769898a3e2462ab06a35e5046d25f14f3", "support" ], "webaudio/js/worklet-recorder.js": [ @@ -523501,6 +523797,14 @@ "dc324b22d6539d5383ed53f68ab911f6e96fd0dd", "testharness" ], + "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-iterable.https-expected.txt": [ + "b411cbf28a60c725bfb2e3f1762a767ef0e649be", + "support" + ], + "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-iterable.https.html": [ + "9e93f48ab878c5f9208dae7a6d2278cd98ab4529", + "testharness" + ], "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-size.https.html": [ "9578b268815a89d31457df8cdd7a088e9df13c7c", "testharness"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/parsing/background-image-computed.sub-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/parsing/background-image-computed.sub-expected.txt index 93cf4bd..1689089 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/parsing/background-image-computed.sub-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/parsing/background-image-computed.sub-expected.txt
@@ -3,9 +3,31 @@ PASS Property background-image value 'url("http://web-platform.test/")' PASS Property background-image value 'none, url("http://web-platform.test/")' PASS Property background-image value 'linear-gradient(to left bottom, red, blue)' +PASS Property background-image value 'radial-gradient(rgb(255, 0, 0), rgb(0, 0, 255))' +FAIL Property background-image value 'radial-gradient(at center, red, blue)' assert_equals: expected "radial-gradient(rgb(255, 0, 0), rgb(0, 0, 255))" but got "radial-gradient(at center center, rgb(255, 0, 0), rgb(0, 0, 255))" +FAIL Property background-image value 'radial-gradient(at 50%, red, blue)' assert_equals: expected "radial-gradient(rgb(255, 0, 0), rgb(0, 0, 255))" but got "radial-gradient(at 50% center, rgb(255, 0, 0), rgb(0, 0, 255))" +PASS Property background-image value 'radial-gradient(at 10px 10px, rgb(255, 0, 0), rgb(0, 0, 255))' +PASS Property background-image value 'radial-gradient(farthest-side, rgb(255, 0, 0), rgb(0, 0, 255))' +PASS Property background-image value 'radial-gradient(farthest-side at 10px 10px, rgb(255, 0, 0), rgb(0, 0, 255))' +PASS Property background-image value 'radial-gradient(farthest-corner, red, blue)' +FAIL Property background-image value 'radial-gradient(farthest-corner at center, red, blue)' assert_equals: expected "radial-gradient(rgb(255, 0, 0), rgb(0, 0, 255))" but got "radial-gradient(at center center, rgb(255, 0, 0), rgb(0, 0, 255))" +FAIL Property background-image value 'radial-gradient(farthest-corner at 50%, red, blue)' assert_equals: expected "radial-gradient(rgb(255, 0, 0), rgb(0, 0, 255))" but got "radial-gradient(at 50% center, rgb(255, 0, 0), rgb(0, 0, 255))" +PASS Property background-image value 'radial-gradient(farthest-corner at 10px 10px, red, blue)' PASS Property background-image value 'radial-gradient(10px at 20px 30px, rgb(255, 0, 0), rgb(0, 0, 255))' FAIL Property background-image value 'radial-gradient(circle calc(-0.5em + 10px) at calc(-1em + 10px) calc(-2em + 10px), red, blue)' assert_equals: expected "radial-gradient(0px at -30px -70px, rgb(255, 0, 0), rgb(0, 0, 255))" but got "radial-gradient(calc(-0.5em + 10px) at calc(-1em + 10px) calc(-2em + 10px), rgb(255, 0, 0), rgb(0, 0, 255))" FAIL Property background-image value 'radial-gradient(ellipse calc(-0.5em + 10px) calc(0.5em + 10px) at 20px 30px, red, blue)' assert_equals: expected "radial-gradient(0px 30px at 20px 30px, rgb(255, 0, 0), rgb(0, 0, 255))" but got "radial-gradient(calc(-0.5em + 10px) calc(0.5em + 10px) at 20px 30px, rgb(255, 0, 0), rgb(0, 0, 255))" FAIL Property background-image value 'radial-gradient(ellipse calc(0.5em + 10px) calc(-0.5em + 10px) at 20px 30px, red, blue)' assert_equals: expected "radial-gradient(30px 0px at 20px 30px, rgb(255, 0, 0), rgb(0, 0, 255))" but got "radial-gradient(calc(0.5em + 10px) calc(-0.5em + 10px) at 20px 30px, rgb(255, 0, 0), rgb(0, 0, 255))" +PASS Property background-image value 'conic-gradient(rgb(255, 0, 0), rgb(0, 0, 255))' +FAIL Property background-image value 'conic-gradient(at center, red, blue)' assert_equals: expected "conic-gradient(rgb(255, 0, 0), rgb(0, 0, 255))" but got "conic-gradient(at center center, rgb(255, 0, 0), rgb(0, 0, 255))" +FAIL Property background-image value 'conic-gradient(at 50%, red, blue)' assert_equals: expected "conic-gradient(rgb(255, 0, 0), rgb(0, 0, 255))" but got "conic-gradient(at 50% center, rgb(255, 0, 0), rgb(0, 0, 255))" +PASS Property background-image value 'conic-gradient(at 10px 10px, rgb(255, 0, 0), rgb(0, 0, 255))' +FAIL Property background-image value 'conic-gradient(from 0deg, red, blue)' assert_equals: expected "conic-gradient(rgb(255, 0, 0), rgb(0, 0, 255))" but got "conic-gradient(from 0deg, rgb(255, 0, 0), rgb(0, 0, 255))" +FAIL Property background-image value 'conic-gradient(from 0deg at center, red, blue)' assert_equals: expected "conic-gradient(rgb(255, 0, 0), rgb(0, 0, 255))" but got "conic-gradient(from 0deg at center center, rgb(255, 0, 0), rgb(0, 0, 255))" +FAIL Property background-image value 'conic-gradient(from 0deg at 50%, red, blue)' assert_equals: expected "conic-gradient(rgb(255, 0, 0), rgb(0, 0, 255))" but got "conic-gradient(from 0deg at 50% center, rgb(255, 0, 0), rgb(0, 0, 255))" +FAIL Property background-image value 'conic-gradient(from 0deg at 10px 10px, red, blue)' assert_equals: expected "conic-gradient(at 10px 10px, rgb(255, 0, 0), rgb(0, 0, 255))" but got "conic-gradient(from 0deg at 10px 10px, rgb(255, 0, 0), rgb(0, 0, 255))" +PASS Property background-image value 'conic-gradient(from 45deg, rgb(255, 0, 0), rgb(0, 0, 255))' +FAIL Property background-image value 'conic-gradient(from 45deg at center, red, blue)' assert_equals: expected "conic-gradient(from 45deg, rgb(255, 0, 0), rgb(0, 0, 255))" but got "conic-gradient(from 45deg at center center, rgb(255, 0, 0), rgb(0, 0, 255))" +FAIL Property background-image value 'conic-gradient(from 45deg at 50%, red, blue)' assert_equals: expected "conic-gradient(from 45deg, rgb(255, 0, 0), rgb(0, 0, 255))" but got "conic-gradient(from 45deg at 50% center, rgb(255, 0, 0), rgb(0, 0, 255))" +PASS Property background-image value 'conic-gradient(from 45deg at 10px 10px, red, blue)' Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/parsing/background-image-computed.sub.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/parsing/background-image-computed.sub.html index ff2f34a..8ee18e2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/parsing/background-image-computed.sub.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/parsing/background-image-computed.sub.html
@@ -26,10 +26,34 @@ test_computed_value('background-image', 'linear-gradient(to left bottom, red, blue)', 'linear-gradient(to left bottom, rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'radial-gradient(rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'radial-gradient(at center, red, blue)', 'radial-gradient(rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'radial-gradient(at 50%, red, blue)', 'radial-gradient(rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'radial-gradient(at 10px 10px, rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'radial-gradient(farthest-side, rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'radial-gradient(farthest-side at 10px 10px, rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'radial-gradient(farthest-corner, red, blue)', 'radial-gradient(rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'radial-gradient(farthest-corner at center, red, blue)', 'radial-gradient(rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'radial-gradient(farthest-corner at 50%, red, blue)', 'radial-gradient(rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'radial-gradient(farthest-corner at 10px 10px, red, blue)', 'radial-gradient(at 10px 10px, rgb(255, 0, 0), rgb(0, 0, 255))'); + test_computed_value('background-image', 'radial-gradient(10px at 20px 30px, rgb(255, 0, 0), rgb(0, 0, 255))'); test_computed_value('background-image', 'radial-gradient(circle calc(-0.5em + 10px) at calc(-1em + 10px) calc(-2em + 10px), red, blue)', 'radial-gradient(0px at -30px -70px, rgb(255, 0, 0), rgb(0, 0, 255))'); test_computed_value('background-image', 'radial-gradient(ellipse calc(-0.5em + 10px) calc(0.5em + 10px) at 20px 30px, red, blue)', 'radial-gradient(0px 30px at 20px 30px, rgb(255, 0, 0), rgb(0, 0, 255))'); test_computed_value('background-image', 'radial-gradient(ellipse calc(0.5em + 10px) calc(-0.5em + 10px) at 20px 30px, red, blue)', 'radial-gradient(30px 0px at 20px 30px, rgb(255, 0, 0), rgb(0, 0, 255))'); + +test_computed_value('background-image', 'conic-gradient(rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'conic-gradient(at center, red, blue)', 'conic-gradient(rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'conic-gradient(at 50%, red, blue)', 'conic-gradient(rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'conic-gradient(at 10px 10px, rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'conic-gradient(from 0deg, red, blue)', 'conic-gradient(rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'conic-gradient(from 0deg at center, red, blue)', 'conic-gradient(rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'conic-gradient(from 0deg at 50%, red, blue)', 'conic-gradient(rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'conic-gradient(from 0deg at 10px 10px, red, blue)', 'conic-gradient(at 10px 10px, rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'conic-gradient(from 45deg, rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'conic-gradient(from 45deg at center, red, blue)', 'conic-gradient(from 45deg, rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'conic-gradient(from 45deg at 50%, red, blue)', 'conic-gradient(from 45deg, rgb(255, 0, 0), rgb(0, 0, 255))'); +test_computed_value('background-image', 'conic-gradient(from 45deg at 10px 10px, red, blue)', 'conic-gradient(from 45deg at 10px 10px, rgb(255, 0, 0), rgb(0, 0, 255))'); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-020.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-020.html new file mode 100644 index 0000000..dad3b647 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-020.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<title>Flex transferred minimum height</title> +<link rel="author" title="dgrogan@chromium.org" href="mailto:dgrogan@chromium.org" /> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#transferred-size-suggestion" /> +<link rel="match" href="../reference/ref-filled-green-100px-square-only.html" /> +<meta name="assert" content="min-height: auto honors transferred size suggestion"> + +<p>Test passes if there is a filled green square.</p> + +<div style="width:100px; height: 50px; background: green;"></div> +<div style="display: flex; flex-direction: column; height: 0px"> + <img src="support/300x150-green.png" style="width: 100px"> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-021.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-021.html new file mode 100644 index 0000000..ed8d1d4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-height-flex-items-021.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<title>Flex transferred minimum height</title> +<link rel="author" title="dgrogan@chromium.org" href="mailto:dgrogan@chromium.org" /> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#transferred-size-suggestion" /> +<link rel="match" href="../reference/ref-filled-green-100px-square-only.html" /> +<meta name="assert" content="min-height: auto honors transferred size suggestion subject to cross axis min/max sizes"> + +<p>Test passes if there is a filled green square.</p> + +<div style="width:100px; height: 50px; background: green;"></div> +<div style="display: flex; flex-direction: column; height: 0px"> + <img src="support/300x150-green.png" style="width: 0px; min-width: 100px;"> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-011.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-011.html new file mode 100644 index 0000000..0eb6c5fa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-011.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<title>Flex transferred minimum width</title> +<link rel="author" title="dgrogan@chromium.org" href="mailto:dgrogan@chromium.org" /> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#transferred-size-suggestion" /> +<link rel="match" href="../reference/ref-filled-green-100px-square-only.html" /> +<meta name="assert" content="min-width: auto honors transferred size suggestion"> + +<p>Test passes if there is a filled green square.</p> + +<div style="width:100px; height: 50px; background: green;"></div> +<div style="display: flex; width: 0px"> <!-- width:0 makes items shrink to min-width --> + <img src="support/300x150-green.png" style="height: 50px"> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-012.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-012.html new file mode 100644 index 0000000..2ce9129e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-012.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<title>Flex transferred minimum width</title> +<link rel="author" title="dgrogan@chromium.org" href="mailto:dgrogan@chromium.org" /> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#transferred-size-suggestion" /> +<link rel="match" href="../reference/ref-filled-green-100px-square-only.html" /> +<meta name="assert" content="min-width: auto honors transferred size suggestion subject to cross axis min/max sizes"> + +<p>Test passes if there is a filled green square.</p> + +<div style="width:100px; height: 50px; background: green;"></div> +<div style="display: flex; width: 0px"> <!-- width:0 makes items shrink to min-width --> + <img src="support/300x150-green.png" style="height: 2000px; max-height: 50px"> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-013.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-013.html new file mode 100644 index 0000000..6ee9ed10 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/flex-minimum-width-flex-items-013.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<title>Flex transferred minimum width</title> +<link rel="author" title="dgrogan@chromium.org" href="mailto:dgrogan@chromium.org" /> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#min-size-auto" /> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht" /> +<meta name="assert" content="min-width: auto ignores transferred size suggestion when item has a definite main size"> + +<style> +#reference-overlapped-red { + position: absolute; + background-color: red; + width: 100px; + height: 100px; + z-index: -1; +} +</style> + +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> + +<div id="reference-overlapped-red"></div> +<div style="width:100px; height: 75px; background: green;"></div> +<div style="display: flex; width: 0px"> + <!-- + content size suggestion is 300px. + specified size suggestion is 100px. + transferred size suggestion is 50px, but that is ignored because there is a + specified size. The ignoring is from the spec text that says, + (capitalization added): + + In general, the content-based minimum size of a flex item is the smaller of + its content size suggestion and its specified size suggestion. However, if + the box has an aspect ratio AND NO specified size, its content-based + minimum size is the smaller of its content size suggestion and its + transferred size suggestion. + + So here the content-based minimum size is min(300, 100) = 100. + --> + <img src="support/300x150-green.png" style="height: 25px; width: 100px;"> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-images/parsing/gradient-position-valid.html b/third_party/blink/web_tests/external/wpt/css/css-images/parsing/gradient-position-valid.html index 9857496f..d2e3ff07 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-images/parsing/gradient-position-valid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-images/parsing/gradient-position-valid.html
@@ -13,6 +13,7 @@ <body> <script> // Where two values are shown, the first serialization is being used by Blink/Firefox/WebKit and the second by Edge. +// Where three values are shown, the first is used by Blink/Webkit, the second by Edge and the third by Firefox. test_valid_value("background-image", "radial-gradient(at 10%, red, blue)", ["radial-gradient(at 10% center, red, blue)", "radial-gradient(at 10%, red, blue)"]); test_valid_value("background-image", "radial-gradient(at 20% 30px, red, blue)"); @@ -20,10 +21,10 @@ test_valid_value("background-image", "radial-gradient(at 40px top, red, blue)"); test_valid_value("background-image", "radial-gradient(at bottom 10% right 20%, red, blue)", "radial-gradient(at right 20% bottom 10%, red, blue)"); test_valid_value("background-image", "radial-gradient(at bottom right, red, blue)", "radial-gradient(at right bottom, red, blue)"); -test_valid_value("background-image", "radial-gradient(at center, red, blue)", ["radial-gradient(at center center, red, blue)", "radial-gradient(at center, red, blue)"]); +test_valid_value("background-image", "radial-gradient(at center, red, blue)", ["radial-gradient(at center center, red, blue)", "radial-gradient(at center, red, blue)", "radial-gradient(red, blue)"]); test_valid_value("background-image", "radial-gradient(at center 50px, red, blue)"); test_valid_value("background-image", "radial-gradient(at center bottom, red, blue)", ["radial-gradient(at center bottom, red, blue)", "radial-gradient(at bottom, red, blue)"]); -test_valid_value("background-image", "radial-gradient(at center center, red, blue)", ["radial-gradient(at center center, red, blue)", "radial-gradient(at center, red, blue)"]); +test_valid_value("background-image", "radial-gradient(at center center, red, blue)", ["radial-gradient(at center center, red, blue)", "radial-gradient(at center, red, blue)", "radial-gradient(red, blue)"]); test_valid_value("background-image", "radial-gradient(at center left, red, blue)", ["radial-gradient(at left center, red, blue)", "radial-gradient(at left, red, blue)"]); test_valid_value("background-image", "radial-gradient(at left, red, blue)", ["radial-gradient(at left center, red, blue)", "radial-gradient(at left, red, blue)"]); test_valid_value("background-image", "radial-gradient(at left bottom, red, blue)");
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/resize-observer.idl b/third_party/blink/web_tests/external/wpt/interfaces/resize-observer.idl index 60d55a1..f20b719d 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/resize-observer.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/resize-observer.idl
@@ -39,5 +39,5 @@ constructor(Element target); readonly attribute Element target; readonly attribute ResizeObserverBoxOptions observedBox; - readonly attribute sequence<ResizeObserverSize> lastReportedSizes; + readonly attribute FrozenArray<ResizeObserverSize> lastReportedSizes; };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl index 1b005c3..5f5320c 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
@@ -258,7 +258,7 @@ dictionary XRReferenceSpaceEventInit : EventInit { required XRReferenceSpace referenceSpace; - XRRigidTransform transform; + XRRigidTransform? transform = null; }; dictionary XRPermissionDescriptor: PermissionDescriptor {
diff --git a/third_party/blink/web_tests/external/wpt/lint.whitelist b/third_party/blink/web_tests/external/wpt/lint.whitelist index 0b9ebb9..7c282ee 100644 --- a/third_party/blink/web_tests/external/wpt/lint.whitelist +++ b/third_party/blink/web_tests/external/wpt/lint.whitelist
@@ -322,6 +322,7 @@ *: css/tools/w3ctestlib/* *: resources/webidl2/* *: tools/* +*: */third_party/* # Build system virtualenv *: css/tools/_virtualenv/*
diff --git a/third_party/blink/web_tests/external/wpt/resize-observer/idlharness.window-expected.txt b/third_party/blink/web_tests/external/wpt/resize-observer/idlharness.window-expected.txt index e060e05..ae5fde6 100644 --- a/third_party/blink/web_tests/external/wpt/resize-observer/idlharness.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/resize-observer/idlharness.window-expected.txt
@@ -1,6 +1,62 @@ This is a testharness.js-based test. -FAIL idl_test setup promise_test: Unhandled rejection with value: object "WebIDLParseError: Syntax error at line 42 in resize-observer, since `interface ResizeObservation`: - attribute sequence<ResizeObserverSize> lastReportedSizes; - ^ Attributes cannot accept sequence types" +Found 58 tests; 49 PASS, 9 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS idl_test setup +PASS idl_test validation +PASS ResizeObserverEntry creator +PASS Element includes ParentNode: member names are unique +PASS Element includes NonDocumentTypeChildNode: member names are unique +PASS Element includes ChildNode: member names are unique +PASS Element includes Slotable: member names are unique +PASS ResizeObserver interface: existence and properties of interface object +PASS ResizeObserver interface object length +PASS ResizeObserver interface object name +PASS ResizeObserver interface: existence and properties of interface prototype object +PASS ResizeObserver interface: existence and properties of interface prototype object's "constructor" property +PASS ResizeObserver interface: existence and properties of interface prototype object's @@unscopables property +PASS ResizeObserver interface: operation observe(Element, optional ResizeObserverOptions) +PASS ResizeObserver interface: operation unobserve(Element) +PASS ResizeObserver interface: operation disconnect() +PASS ResizeObserver must be primary interface of observer +PASS Stringification of observer +PASS ResizeObserver interface: observer must inherit property "observe(Element, optional ResizeObserverOptions)" with the proper type +PASS ResizeObserver interface: calling observe(Element, optional ResizeObserverOptions) on observer with too few arguments must throw TypeError +PASS ResizeObserver interface: observer must inherit property "unobserve(Element)" with the proper type +PASS ResizeObserver interface: calling unobserve(Element) on observer with too few arguments must throw TypeError +PASS ResizeObserver interface: observer must inherit property "disconnect()" with the proper type +PASS ResizeObserverEntry interface: existence and properties of interface object +PASS ResizeObserverEntry interface object length +PASS ResizeObserverEntry interface object name +PASS ResizeObserverEntry interface: existence and properties of interface prototype object +PASS ResizeObserverEntry interface: existence and properties of interface prototype object's "constructor" property +PASS ResizeObserverEntry interface: existence and properties of interface prototype object's @@unscopables property +PASS ResizeObserverEntry interface: attribute target +PASS ResizeObserverEntry interface: attribute contentRect +PASS ResizeObserverEntry interface: attribute borderBoxSize +PASS ResizeObserverEntry interface: attribute contentBoxSize +PASS ResizeObserverEntry interface: attribute devicePixelContentBoxSize +PASS ResizeObserverEntry must be primary interface of entry +PASS Stringification of entry +PASS ResizeObserverEntry interface: entry must inherit property "target" with the proper type +PASS ResizeObserverEntry interface: entry must inherit property "contentRect" with the proper type +PASS ResizeObserverEntry interface: entry must inherit property "borderBoxSize" with the proper type +PASS ResizeObserverEntry interface: entry must inherit property "contentBoxSize" with the proper type +PASS ResizeObserverEntry interface: entry must inherit property "devicePixelContentBoxSize" with the proper type +PASS ResizeObserverSize interface: existence and properties of interface object +PASS ResizeObserverSize interface object length +PASS ResizeObserverSize interface object name +PASS ResizeObserverSize interface: existence and properties of interface prototype object +PASS ResizeObserverSize interface: existence and properties of interface prototype object's "constructor" property +PASS ResizeObserverSize interface: existence and properties of interface prototype object's @@unscopables property +PASS ResizeObserverSize interface: attribute inlineSize +PASS ResizeObserverSize interface: attribute blockSize +FAIL ResizeObservation interface: existence and properties of interface object assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface object length assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface object name assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface: attribute target assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface: attribute observedBox assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing +FAIL ResizeObservation interface: attribute lastReportedSizes assert_own_property: self does not have own property "ResizeObservation" expected property "ResizeObservation" missing Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-display-contents-crash.html b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-display-contents-crash.html new file mode 100644 index 0000000..04b6a7e7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/svg/text/reftests/text-display-contents-crash.html
@@ -0,0 +1,25 @@ +<!doctype html> +<title>Crash with dynamic creation of absolutely positioned element under display: contents in svg:text.</title> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1611848"> +<style> +* { + position: absolute; +} +</style> +<script> + function start () { + const text = document.getElementById('text') + + const div = document.createElementNS('http://www.w3.org/1999/xhtml', 'div') + div.style.display = "contents"; + + const another = document.createElementNS('http://www.w3.org/2000/svg', 'whatevs') + text.appendChild(div); + document.documentElement.getBoundingClientRect(); + div.appendChild(another); + } + + document.addEventListener('DOMContentLoaded', start) +</script> +<svg> + <text id='text'>
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/js/helpers.js b/third_party/blink/web_tests/external/wpt/webaudio/js/helpers.js index fbbfc8e..3819d12 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/js/helpers.js +++ b/third_party/blink/web_tests/external/wpt/webaudio/js/helpers.js
@@ -216,3 +216,35 @@ runTestFunction(); } + +// Simpler than audit.js, but still logs the message. Requires +// `setup("explicit_done": true)` if testing code that runs after the "load" +// event. +function equals(a, b, msg) { + test(function() { + assert_equals(a, b); + }, msg); +} +function is_true(a, msg) { + test(function() { + assert_true(a); + }, msg); +} + +// This allows writing AudioWorkletProcessor code in the same file as the rest +// of the test, for quick one off AudioWorkletProcessor testing. +function URLFromScriptsElements(ids) +{ + var scriptTexts = []; + for (let id of ids) { + + const e = document.querySelector("script#"+id) + if (!e) { + throw id+" is not the id of a <script> tag"; + } + scriptTexts.push(e.innerText); + } + const blob = new Blob(scriptTexts, {type: "application/javascript"}); + + return URL.createObjectURL(blob); +}
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-iterable.https-expected.txt b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-iterable.https-expected.txt new file mode 100644 index 0000000..b411cbf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-iterable.https-expected.txt
@@ -0,0 +1,66 @@ +This is a testharness.js-based test. +Found 54 tests; 49 PASS, 5 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS Creating an AudioWorkletNode with a set for + parameter descriptor worked +PASS Map match in size for set +PASS set: ä½ å¥½ exists in both maps +PASS Values for ä½ å¥½.defaultValue match for set +PASS Values for ä½ å¥½.minValue match for set +PASS Values for ä½ å¥½.maxValue match for set +PASS Values for ä½ å¥½.automationRate match for set +PASS set: a control-rate parameter exists in both maps +PASS Values for a control-rate parameter.defaultValue match for set +PASS Values for a control-rate parameter.minValue match for set +PASS Values for a control-rate parameter.maxValue match for set +PASS Values for a control-rate parameter.automationRate match for set +PASS set: 🎶 exists in both maps +PASS Values for 🎶.defaultValue match for set +PASS Values for 🎶.minValue match for set +PASS Values for 🎶.maxValue match for set +FAIL Values for 🎶.automationRate match for set assert_equals: expected "k-rate" but got "a-rate" +PASS Creating an AudioWorkletNode with a array for + parameter descriptor worked +PASS Map match in size for array +PASS array: ä½ å¥½ exists in both maps +PASS Values for ä½ å¥½.defaultValue match for array +PASS Values for ä½ å¥½.minValue match for array +PASS Values for ä½ å¥½.maxValue match for array +PASS Values for ä½ å¥½.automationRate match for array +PASS array: a control-rate parameter exists in both maps +PASS Values for a control-rate parameter.defaultValue match for array +PASS Values for a control-rate parameter.minValue match for array +PASS Values for a control-rate parameter.maxValue match for array +PASS Values for a control-rate parameter.automationRate match for array +PASS array: 🎶 exists in both maps +PASS Values for 🎶.defaultValue match for array +PASS Values for 🎶.minValue match for array +PASS Values for 🎶.maxValue match for array +FAIL Values for 🎶.automationRate match for array assert_equals: expected "k-rate" but got "a-rate" +PASS Creating an AudioWorkletNode with a generator for + parameter descriptor worked +PASS Map match in size for generator +PASS generator: ä½ å¥½ exists in both maps +PASS Values for ä½ å¥½.defaultValue match for generator +PASS Values for ä½ å¥½.minValue match for generator +PASS Values for ä½ å¥½.maxValue match for generator +PASS Values for ä½ å¥½.automationRate match for generator +PASS generator: a control-rate parameter exists in both maps +PASS Values for a control-rate parameter.defaultValue match for generator +PASS Values for a control-rate parameter.minValue match for generator +PASS Values for a control-rate parameter.maxValue match for generator +PASS Values for a control-rate parameter.automationRate match for generator +PASS generator: 🎶 exists in both maps +PASS Values for 🎶.defaultValue match for generator +PASS Values for 🎶.minValue match for generator +PASS Values for 🎶.maxValue match for generator +FAIL Values for 🎶.automationRate match for generator assert_equals: expected "k-rate" but got "a-rate" +PASS Attempting to create an AudioWorkletNode with an non + iterable for parameter descriptor should not work +FAIL Attempting to create an AudioWorkletNode from a processor + that does not have a parameterDescriptors getter should work Failed to construct 'AudioWorkletNode': AudioWorkletNode cannot be created: The node name 'no-params' is not defined in AudioWorkletGlobalScope. +FAIL Attempting to create an AudioWorkletNode with two parameter + descriptor with the same name should not work assert_throws_dom: function "function() { + new AudioWorkletNode(ac, "duplicate-param-name"); + }" did not throw +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-iterable.https.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-iterable.https.html new file mode 100644 index 0000000..9e93f48 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-iterable.https.html
@@ -0,0 +1,205 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <title> + Test get parameterDescriptor as various iterables + </title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/js/helpers.js"></script> + </head> + + <body> + <script id="params"> + // A series of AudioParamDescriptors, copied one by one into various iterable + // data structures. This is used by both the processor side and the main + // thread side, so is in a different script tag. + const PARAMS = [ + { + name: "a control-rate parameter", + defaultValue: 0.5, + minValue: 0, + maxValue: 1, + automationRate: "a-rate", + }, + { + name: "ä½ å¥½", + defaultValue: 2.5, + minValue: 0, + maxValue: 7, + automationRate: "a-rate", + }, + { + name: "🎶", + defaultValue: 8.5, + minValue: 0, + maxValue: 11115, + automationRate: "k-rate", + }, + ]; + </script> + <script id="processors" type="worklet"> + registerProcessor("set", + class SetParamProcessor extends AudioWorkletProcessor { + static get parameterDescriptors() { + var s = new Set(); + s.add(PARAMS[0]); + s.add(PARAMS[1]); + s.add(PARAMS[2]); + return s; + } + constructor() { super(); } + process() { + } + }); + + registerProcessor("array", + class ArrayParamProcessor extends AudioWorkletProcessor { + static get parameterDescriptors() { + return PARAMS; + } + constructor() { super(); } + process() { } + }); + + function* gen() { + yield PARAMS[0]; + yield PARAMS[1]; + yield PARAMS[2]; + } + registerProcessor("generator", + class GeneratorParamProcessor extends AudioWorkletProcessor { + static get parameterDescriptors() { + return gen(); + } + constructor() { super(); } + process() { } + }); + // Test a processor that has a get parameterDescriptors, but it returns + // something that is not iterable. + try { + registerProcessor("invalid", + class InvalidParamProcessor extends AudioWorkletProcessor { + static get parameterDescriptors() { + return 4; + } + constructor() { super(); } + process() { } + }); + throw "This should not have been reached."; + } catch (e) { + // unclear how to signal success here, but we can signal failure in the + // developer console + if (e.name != "TypeError") { + throw "This should be TypeError"; + } + } + // Test a processor that has a get parameterDescriptors, with a duplicate + // param name something that is not iterable. + try { + registerProcessor("duplicate-param-name", + class DuplicateParamProcessor extends AudioWorkletProcessor { + static get parameterDescriptors() { + var p = { + name: "a", + defaultValue: 1, + minValue: 0, + maxValue: 1, + automationRate: "k-rate", + }; + return [p,p]; + } + constructor() { super(); } + process() { } + }); + throw "This should not have been reached."; + } catch (e) { + // unclear how to signal success here, but we can signal failure in the + // developer console + if (e.name != "NotSupportedError") { + throw "This should be NotSupportedError"; + } + } + // Test a processor that has a no get parameterDescriptors. + try { + registerProcessor("no-params", + class NoParamProcessor extends AudioWorkletProcessor { + constructor() { super(); } + process() { } + }); + } catch (e) { + throw "Construction should have worked."; + } + </script> + <script> + setup({ explicit_done: true }); + // Mangle the PARAMS object into a map that has the same shape as what an + // AudioWorkletNode.parameter property would + var PARAMS_MAP = new Map(); + for (var param of PARAMS) { + var o = param; + var name = o.name; + delete o.name; + PARAMS_MAP.set(name, o); + } + + // This compares `lhs` and `rhs`, that are two maplike with the same shape + // as PARAMS_MAP. + function compare(testname, lhs, rhs) { + equals(lhs.size, rhs.size, "Map match in size for " + testname); + var i = 0; + for (var [k, v] of lhs) { + is_true(rhs.has(k), testname + ": " + k + " exists in both maps"); + var vrhs = rhs.get(k); + ["defaultValue", "minValue", "maxValue", "automationRate"].forEach( + paramKey => { + equals( + v[paramKey], + vrhs[paramKey], + `Values for ${k}.${paramKey} match for ${testname}` + ); + } + ); + } + } + var ac = new AudioContext(); + var url = URLFromScriptsElements(["params", "processors"]); + ac.audioWorklet + .addModule(url) + .then(() => { + ["set", "array", "generator"].forEach(iterable => { + test(() => { + var node = new AudioWorkletNode(ac, iterable); + compare(iterable, node.parameters, PARAMS_MAP); + }, `Creating an AudioWorkletNode with a ${iterable} for + parameter descriptor worked`); + }); + }) + .then(function() { + test(function() { + assert_throws_dom("InvalidStateError", function() { + new AudioWorkletNode(ac, "invalid"); + }); + }, `Attempting to create an AudioWorkletNode with an non + iterable for parameter descriptor should not work`); + }) + .then(function() { + test(() => { + new AudioWorkletNode(ac, "no-params"); + }, `Attempting to create an AudioWorkletNode from a processor + that does not have a parameterDescriptors getter should work`); + }) + .then(function() { + test(function() { + assert_throws_dom("InvalidStateError", function() { + new AudioWorkletNode(ac, "duplicate-param-name"); + }); + }, `Attempting to create an AudioWorkletNode with two parameter + descriptor with the same name should not work`); + }).then(function() { + done(); + }); + </script> + </body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpSynchronizationSource-captureTimestamp.html b/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpSynchronizationSource-captureTimestamp.html new file mode 100644 index 0000000..0902118a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpSynchronizationSource-captureTimestamp.html
@@ -0,0 +1,222 @@ +<!doctype html> +<meta charset=utf-8> +<!-- This file contains a test that waits for 2 seconds. --> +<meta name="timeout" content="long"> +<title>captureTimestamp attribute in RTCRtpSynchronizationSource</title> +<div><video id="remote" width="124" height="124" autoplay></video></div> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/webrtc/RTCPeerConnection-helper.js"></script> +<script src="/webrtc/RTCStats-helper.js"></script> +<script> +'use strict'; + +var kAbsCaptureTime = + 'http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time'; + +function addHeaderExtensionToSdp(sdp, uri) { + const extmap = new RegExp('a=extmap:(\\d+)'); + let sdpLines = sdp.split('\r\n'); + + // This assumes at most one audio m= section and one video m= section. + // If more are present, only the first section of each kind is munged. + for (const section of ['audio', 'video']) { + let found_section = false; + let maxId = undefined; + let maxIdLine = undefined; + let extmapAllowMixed = false; + + // find the largest header extension id for section. + for (let i = 0; i < sdpLines.length; ++i) { + if (!found_section) { + if (sdpLines[i].startsWith('m=' + section)) { + found_section = true; + } + continue; + } else { + if (sdpLines[i].startsWith('m=')) { + // end of section + break; + } + } + + if (sdpLines[i] === 'a=extmap-allow-mixed') { + extmapAllowMixed = true; + } + let result = sdpLines[i].match(extmap); + if (result && result.length === 2) { + if (maxId == undefined || result[1] > maxId) { + maxId = parseInt(result[1]); + maxIdLine = i; + } + } + } + + if (maxId == 14 && !extmapAllowMixed) { + // Reaching the limit of one byte header extension. Adding two byte header + // extension support. + sdpLines.splice(maxIdLine + 1, 0, 'a=extmap-allow-mixed'); + } + if (maxIdLine !== undefined) { + sdpLines.splice(maxIdLine + 1, 0, + 'a=extmap:' + (maxId + 1).toString() + ' ' + uri); + } + } + return sdpLines.join('\r\n'); +} + +// TODO(crbug.com/1051821): Use RTP header extension API instead of munging +// when the RTP header extension API is implemented. +async function addAbsCaptureTimeAndExchangeOffer(caller, callee) { + let offer = await caller.createOffer(); + + // Absolute capture time header extension may not be offered by default, + // in such case, munge the SDP. + offer.sdp = addHeaderExtensionToSdp(offer.sdp, kAbsCaptureTime); + + await caller.setLocalDescription(offer); + return callee.setRemoteDescription(offer); +} + +// TODO(crbug.com/1051821): Use RTP header extension API instead of munging +// when the RTP header extension API is implemented. +async function checkAbsCaptureTimeAndExchangeAnswer(caller, callee, + absCaptureTimeAnswered) { + let answer = await callee.createAnswer(); + + const extmap = new RegExp('a=extmap:\\d+ ' + kAbsCaptureTime + '\r\n', 'g'); + if (answer.sdp.match(extmap) == null) { + // We expect that absolute capture time RTP header extension is answered. + // But if not, there is no need to proceed with the test. + assert_precondition(!absCaptureTimeAnswered, 'Absolute capture time RTP ' + + 'header extension is not answered'); + } else { + if (!absCaptureTimeAnswered) { + // We expect that absolute capture time RTP header extension is not + // answered, but it is, then we munge the answer to remove it. + answer.sdp = answer.sdp.replace(extmap, ''); + } + } + + await callee.setLocalDescription(answer); + return caller.setRemoteDescription(answer); +} + +async function exchangeOfferAndListenToOntrack(t, caller, callee, + absCaptureTimeOffered) { + const ontrackPromise = addEventListenerPromise(t, callee, 'track'); + // Absolute capture time header extension is expected not offered by default, + // and thus munging is needed to enable it. + await absCaptureTimeOffered + ? addAbsCaptureTimeAndExchangeOffer(caller, callee) + : exchangeOffer(caller, callee); + return ontrackPromise; +} + +async function initiateSingleTrackCall(t, cap, absCaptureTimeOffered, + absCaptureTimeAnswered) { + const caller = new RTCPeerConnection(); + t.add_cleanup(() => caller.close()); + const callee = new RTCPeerConnection(); + t.add_cleanup(() => callee.close()); + + const stream = await getNoiseStream(cap); + stream.getTracks().forEach(track => { + caller.addTrack(track, stream); + t.add_cleanup(() => track.stop()); + }); + + // TODO(crbug.com/988432): `getSynchronizationSources() on the audio side + // needs a hardware sink for the returned dictionary entries to get updated. + const remoteVideo = document.getElementById('remote'); + + callee.ontrack = e => { + remoteVideo.srcObject = e.streams[0]; + } + + exchangeIceCandidates(caller, callee); + + await exchangeOfferAndListenToOntrack(t, caller, callee, + absCaptureTimeOffered); + + // Exchange answer and check whether the absolute capture time RTP header + // extension is answered. + await checkAbsCaptureTimeAndExchangeAnswer(caller, callee, + absCaptureTimeAnswered); + + return [caller, callee]; +} + +function listenForCaptureTimestamp(t, receiver) { + return new Promise((resolve) => { + function listen() { + const ssrcs = receiver.getSynchronizationSources(); + assert_true(ssrcs != undefined); + if (ssrcs.length > 0) { + assert_equals(ssrcs.length, 1); + if (ssrcs[0].captureTimestamp != undefined) { + resolve(ssrcs[0].captureTimestamp); + return; + } + } + t.step_timeout(listen, 0); + }; + listen(); + }); +} + +// This test only passes if the implementation is sending the absolute capture +// timestamp header extension. +for (const kind of ['audio', 'video']) { + promise_test(async t => { + const [caller, callee] = await initiateSingleTrackCall( + t, {[kind]: true}, false, false); + const receiver = callee.getReceivers()[0]; + + for (const ssrc of await listenForSSRCs(t, receiver)) { + assert_equals(typeof ssrc.captureTimestamp, 'undefined'); + } + }, '[' + kind + '] getSynchronizationSources() should not contain ' + + 'captureTimestamp if absolute capture time RTP header extension is not ' + + 'offered'); + + promise_test(async t => { + const [caller, callee] = await initiateSingleTrackCall( + t, {[kind]: true}, false, false); + const receiver = callee.getReceivers()[0]; + + for (const ssrc of await listenForSSRCs(t, receiver)) { + assert_equals(typeof ssrc.captureTimestamp, 'undefined'); + } + }, '[' + kind + '] getSynchronizationSources() should not contain ' + + 'captureTimestamp if absolute capture time RTP header extension is ' + + 'offered, but not answered'); + + promise_test(async t => { + const [caller, callee] = await initiateSingleTrackCall( + t, {[kind]: true}, true, true); + const receiver = callee.getReceivers()[0]; + await listenForCaptureTimestamp(t, receiver); + }, '[' + kind + '] getSynchronizationSources() should contain ' + + 'captureTimestamp if absolute capture time RTP header extension is ' + + 'negotiated'); +} + +promise_test(async t => { + const [caller, callee] = await initiateSingleTrackCall( + t, {audio: true, video: true}, true, true); + const receivers = callee.getReceivers(); + assert_equals(receivers.length, 2); + + let captureTimestamps = [undefined, undefined]; + const t0 = performance.now(); + for (let i = 0; i < 2; ++i) { + captureTimestamps[i] = await listenForCaptureTimestamp(t, receivers[i]); + } + const t1 = performance.now(); + assert_less_than(Math.abs(captureTimestamps[0] - captureTimestamps[1]), + t1 - t0); +}, 'Audio and video RTCRtpSynchronizationSource.captureTimestamp are ' + + 'comparable'); + +</script>
diff --git a/third_party/blink/web_tests/fast/scrolling/scrollbars/scrollbar-ltr-to-rtl-expected.html b/third_party/blink/web_tests/fast/scrolling/scrollbars/scrollbar-ltr-to-rtl-expected.html new file mode 100644 index 0000000..7d1ba4956 --- /dev/null +++ b/third_party/blink/web_tests/fast/scrolling/scrollbars/scrollbar-ltr-to-rtl-expected.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<style> +.container { + width: 100px; + height: 100px; + overflow: scroll; + direction: rtl; +} +.content { + width: 200px; + height: 300px; +} +</style> +<div class="container"> + <div class="content"></div> +</div> +<div class="container" style="will-change: transform"> + <div class="content"></div> +</div>
diff --git a/third_party/blink/web_tests/fast/scrolling/scrollbars/scrollbar-ltr-to-rtl.html b/third_party/blink/web_tests/fast/scrolling/scrollbars/scrollbar-ltr-to-rtl.html new file mode 100644 index 0000000..12483a37 --- /dev/null +++ b/third_party/blink/web_tests/fast/scrolling/scrollbars/scrollbar-ltr-to-rtl.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<script src="../../../resources/run-after-layout-and-paint.js"></script> +<style> +.container { + width: 100px; + height: 100px; + overflow: scroll; + direction: ltr; +} +.content { + width: 200px; + height: 200px; +} +</style> +<div id="target1" class="container"> + <div class="content"></div> +</div> +<div id="target2" class="container" style="will-change: transform"> + <div class="content"></div> +</div> +<script> +runAfterLayoutAndPaint(() => { + document.querySelectorAll('.container').forEach((e) => { + e.style.direction = 'rtl'; + }); + document.querySelectorAll('.content').forEach((e) => { + e.style.height = '300px'; + }); +}, true); +</script>
diff --git a/third_party/minigbm/BUILD.gn b/third_party/minigbm/BUILD.gn index 8e8c6259..8cc5f9d 100644 --- a/third_party/minigbm/BUILD.gn +++ b/third_party/minigbm/BUILD.gn
@@ -22,6 +22,7 @@ use_msm_minigbm = false use_radeon_minigbm = false use_rockchip_minigbm = false + use_synaptics_minigbm = false use_tegra_minigbm = false use_vc4_minigbm = false } @@ -57,6 +58,9 @@ if (use_rockchip_minigbm) { defines += [ "DRV_ROCKCHIP" ] } + if (use_synaptics_minigbm) { + defines += [ "DRV_SYNAPTICS" ] + } if (use_tegra_minigbm) { defines += [ "DRV_TEGRA" ] } @@ -84,6 +88,7 @@ "src/nouveau.c", "src/radeon.c", "src/rockchip.c", + "src/synaptics.c", "src/tegra.c", "src/udl.c", "src/vc4.c",
diff --git a/third_party/webrtc_overrides/rtc_base/logging.h b/third_party/webrtc_overrides/rtc_base/logging.h index 85622bc..5513bc6e 100644 --- a/third_party/webrtc_overrides/rtc_base/logging.h +++ b/third_party/webrtc_overrides/rtc_base/logging.h
@@ -4,9 +4,9 @@ // This file overrides the logging macros in WebRTC (webrtc/rtc_base/logging.h). // Instead of using WebRTC's logging implementation, the WebRTC macros are -// mapped to DIAGNOSTIC_LOGING. In its implementation (DiagnosticLogMessage in -// third_party/webrtc_overrides/rtc_base/logging.h), the corresponding -// base/logging.h macros (e.g. Chromium's VLOG) are used. +// mapped to DIAGNOSTIC_LOGGING. In its implementation (DiagnosticLogMessage in +// third_party/webrtc_overrides/rtc_base/diagnostic_logging.h), the +// corresponding base/logging.h macros (e.g. Chromium's VLOG) are used. // If this file is included outside of WebRTC/libjingle it should be included // after base/logging.h (if any) or compiler error or unexpected behavior may // occur (macros that have the same name in WebRTC as in Chromium will use @@ -47,10 +47,14 @@ } // namespace rtc -#define DIAGNOSTIC_LOG(sev, ctx, err, ...) \ - rtc::DiagnosticLogMessage(__FILE__, __LINE__, sev, rtc::ERRCTX_##ctx, err, \ - ##__VA_ARGS__) \ - .stream() +// The LogMessageVoidify() call suppresses -Wunreachable-code diagnostics +// in certain conditions (see https://crbug.com/1065568) +// TODO(thakis): Make the warning smarter and then remove this again. +#define DIAGNOSTIC_LOG(sev, ctx, err, ...) \ + rtc::LogMessageVoidify() & rtc::DiagnosticLogMessage(__FILE__, __LINE__, \ + sev, rtc::ERRCTX_##ctx, \ + err, ##__VA_ARGS__) \ + .stream() #define RTC_LOG_CHECK_LEVEL(sev) CheckVlogIsOn(rtc::sev, __FILE__) #define RTC_LOG_CHECK_LEVEL_V(sev) CheckVlogIsOn(sev, __FILE__)
diff --git a/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp b/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp index fa10c9df..312687f5 100644 --- a/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp +++ b/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp
@@ -700,6 +700,9 @@ if (result != 0) return result; + if (replacements.empty()) + return 0; + // Serialization format is documented in tools/clang/scripts/run_tool.py llvm::outs() << "==== BEGIN EDITS ====\n"; for (const auto& r : replacements) {
diff --git a/tools/clang/empty_string/EmptyStringConverter.cpp b/tools/clang/empty_string/EmptyStringConverter.cpp index c2da652..db82a77 100644 --- a/tools/clang/empty_string/EmptyStringConverter.cpp +++ b/tools/clang/empty_string/EmptyStringConverter.cpp
@@ -179,6 +179,9 @@ if (result != 0) return result; + if (replacements.empty()) + return 0; + // Each replacement line should have the following format: // r:<file path>:<offset>:<length>:<replacement text> // Only the <replacement text> field can contain embedded ":" characters.
diff --git a/tools/clang/pass_to_move/PassToMove.cpp b/tools/clang/pass_to_move/PassToMove.cpp index 48d4aae..e5b563dc 100644 --- a/tools/clang/pass_to_move/PassToMove.cpp +++ b/tools/clang/pass_to_move/PassToMove.cpp
@@ -100,6 +100,9 @@ if (result != 0) return result; + if (replacements.empty()) + return 0; + // Serialization format is documented in tools/clang/scripts/run_tool.py llvm::outs() << "==== BEGIN EDITS ====\n"; for (const auto& r : replacements) {
diff --git a/tools/clang/rewrite_scoped_refptr/RewriteScopedRefptr.cpp b/tools/clang/rewrite_scoped_refptr/RewriteScopedRefptr.cpp index f334231..08c232e 100644 --- a/tools/clang/rewrite_scoped_refptr/RewriteScopedRefptr.cpp +++ b/tools/clang/rewrite_scoped_refptr/RewriteScopedRefptr.cpp
@@ -425,6 +425,9 @@ if (result != 0) return result; + if (replacements.empty()) + return 0; + // Serialization format is documented in tools/clang/scripts/run_tool.py llvm::outs() << "==== BEGIN EDITS ====\n"; for (const auto& r : replacements) {
diff --git a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp index 3ead52f..b38fbba6 100644 --- a/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp +++ b/tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp
@@ -1946,6 +1946,9 @@ edit_tracker->SerializeTo(llvm::outs()); llvm::outs() << "==== END TRACKED EDITS ====\n"; + if (replacements.empty()) + return 0; + // Serialization format is documented in tools/clang/scripts/run_tool.py llvm::outs() << "==== BEGIN EDITS ====\n"; for (const auto& r : replacements) {
diff --git a/tools/grit/README b/tools/grit/README deleted file mode 100644 index aa7d946..0000000 --- a/tools/grit/README +++ /dev/null
@@ -1,8 +0,0 @@ -GRIT (Google Resource and Internationalization Tool) is a tool for Windows -projects to manage resources and simplify the localization workflow. - -This code previously used to live at -https://code.google.com/p/grit-i18n/source/checkout which still contains the -project's history. https://chromium.googlesource.com/external/grit-i18n/ is -a git mirror of the SVN repository that's identical except for the last two -commits.
diff --git a/tools/grit/README.md b/tools/grit/README.md new file mode 100644 index 0000000..b5c3f4b --- /dev/null +++ b/tools/grit/README.md
@@ -0,0 +1,19 @@ +# GRIT (Google Resource and Internationalization Tool) + +This is a tool for projects to manage resources and simplify the localization +workflow. + +See the user guide for more details on using this project: +https://dev.chromium.org/developers/tools-we-use-in-chromium/grit/grit-users-guide + +## History + +This code previously used to live at +https://code.google.com/p/grit-i18n/source/checkout which still contains the +project's history. https://chromium.googlesource.com/external/grit-i18n/ is +a git mirror of the SVN repository that's identical except for the last two +commits. The project is now developed in the Chromium project directly. + +There is a read-only mirror of just this directory at +https://chromium.googlesource.com/chromium/src/tools/grit/ if you don't want to +check out all of Chromium.
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index edbe2f6..4b479e8 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -39492,6 +39492,7 @@ <int value="335976733" label="NotificationStackingBarRedesign:enabled"/> <int value="336429189" label="DisallowUnsafeHttpDownloads:disabled"/> <int value="338662897" label="AndroidNightModeTabReparenting:disabled"/> + <int value="339419844" label="EmojiSuggestAddition:enabled"/> <int value="339671131" label="disable-per-user-timezone"/> <int value="341152650" label="SoundContentSetting:enabled"/> <int value="341851350" label="EnableDbusAndX11StatusIcons:enabled"/> @@ -39995,6 +39996,7 @@ <int value="952558794" label="enable-remote-assistance"/> <int value="955340765" label="ChromeHomeOptOutSnackbar:enabled"/> <int value="955425932" label="EnterpriseReportingInChromeOS:enabled"/> + <int value="955901619" label="EmojiSuggestAddition:disabled"/> <int value="956716414" label="GlobalMediaControlsPictureInPicture:disabled"/> <int value="963457392" label="ChromeHomeModernLayout:disabled"/> <int value="963671232" label="DrawOcclusion:disabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 3e661cd2..35824c2 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -67600,6 +67600,66 @@ </summary> </histogram> +<histogram name="IsolatedPrerender.Prefetch.Mainframe.BodyLength" units="bytes" + expires_after="M90"> + <owner>robertogden@chromium.org</owner> + <owner>ryansturm@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + Records the response body length as cached in memory encountered when + isolated prefetching a mainframe HTML resource from the Google Search Result + Page. Recorded for non-network error prefetches only. + </summary> +</histogram> + +<histogram name="IsolatedPrerender.Prefetch.Mainframe.ConnectTime" units="ms" + expires_after="M90"> + <owner>robertogden@chromium.org</owner> + <owner>ryansturm@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + Records the time taken to establish a socket connection when isolated + prefetching a mainframe HTML resource from the Google Search Result Page. + Recorded for non-network error prefetches only. + </summary> +</histogram> + +<histogram name="IsolatedPrerender.Prefetch.Mainframe.NetError" + enum="NetErrorCodes" expires_after="M90"> + <owner>robertogden@chromium.org</owner> + <owner>ryansturm@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + Records the Net Error encountered when isolated prefetching a mainframe HTML + resource from the Google Search Result Page. Recorded for every completed + prefetch. + </summary> +</histogram> + +<histogram name="IsolatedPrerender.Prefetch.Mainframe.RespCode" + enum="HttpResponseCode" expires_after="M90"> + <owner>robertogden@chromium.org</owner> + <owner>ryansturm@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + Records the HTTP response code encountered isolated prefetching a mainframe + HTML resource from the Google Search Result Page. Recorded for non-network + error prefetches only. Redirects are not included here. + </summary> +</histogram> + +<histogram name="IsolatedPrerender.Prefetch.Mainframe.TotalTime" units="ms" + expires_after="M90"> + <owner>robertogden@chromium.org</owner> + <owner>ryansturm@chromium.org</owner> + <owner>tbansal@chromium.org</owner> + <summary> + Records the total time taken when isolated prefetching a mainframe HTML + resource from the Google Search Result Page. Recorded for successful + non-network error prefetches only. + </summary> +</histogram> + <histogram name="JSDialogs.CharacterCount" units="characters" expires_after="2020-07-06"> <obsolete> @@ -70873,7 +70933,12 @@ </histogram> <histogram name="Media.Audio.Render.AudioMixing.LatencyMap" units="subsets" - expires_after="2020-04-05"> + expires_after="2020-03-31"> + <obsolete> + Removed on March 2020. + </obsolete> + <owner>armax@chromium.org</owner> + <owner>guidou@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> Subset of audio output latencies encountered by the renderer so far. Logged @@ -71045,9 +71110,11 @@ </histogram> <histogram name="Media.Audio.Render.OutputDeviceStatus" - enum="OutputDeviceStatus" expires_after="2020-04-05"> - <owner>olka@chromium.org</owner> + enum="OutputDeviceStatus" expires_after="2021-04-05"> + <owner>armax@chromium.org</owner> <owner>dalecurtis@chromium.org</owner> + <owner>guidou@chromium.org</owner> + <owner>olka@chromium.org</owner> <summary> Device status received in response to device authorization request. </summary> @@ -71672,9 +71739,9 @@ </histogram> <histogram name="Media.AudioService.AudioManagerStartupTime" units="ms" - expires_after="2020-04-05"> - <owner>marinaciocea@chromium.org</owner> - <owner>maxmorin@chromium.org</owner> + expires_after="2021-04-05"> + <owner>armax@chromium.org</owner> + <owner>guidou@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> How long it take for the audio manager instance to be created by the audio @@ -71724,9 +71791,12 @@ </histogram> <histogram name="Media.AudioService.ObservedDowntime2" units="ms" - expires_after="2020-04-05"> - <owner>marinaciocea@chromium.org</owner> - <owner>maxmorin@chromium.org</owner> + expires_after="2020-03-31"> + <obsolete> + Removed on March 2020. + </obsolete> + <owner>armax@chromium.org</owner> + <owner>guidou@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> The audio service downtime, observed from the browser process. The downtime @@ -71735,9 +71805,12 @@ </histogram> <histogram name="Media.AudioService.ObservedInitialDowntime" units="ms" - expires_after="2020-04-05"> - <owner>marinaciocea@chromium.org</owner> - <owner>maxmorin@chromium.org</owner> + expires_after="2020-03-31"> + <obsolete> + Removed on March 2020. + </obsolete> + <owner>armax@chromium.org</owner> + <owner>guidou@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> The audio service downtime, observed from the browser process. The downtime @@ -71763,9 +71836,12 @@ </histogram> <histogram name="Media.AudioService.ObservedStartStatus" - enum="AudioServiceStartStatus" expires_after="2020-04-05"> - <owner>marinaciocea@chromium.org</owner> - <owner>maxmorin@chromium.org</owner> + enum="AudioServiceStartStatus" expires_after="2020-03-31"> + <obsolete> + Removed on March 2020. + </obsolete> + <owner>armax@chromium.org</owner> + <owner>guidou@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> The start result of the audio service, observed from the browser process. @@ -71773,9 +71849,12 @@ </histogram> <histogram name="Media.AudioService.ObservedStartupTime" units="ms" - expires_after="2020-04-05"> - <owner>marinaciocea@chromium.org</owner> - <owner>maxmorin@chromium.org</owner> + expires_after="2020-03-31"> + <obsolete> + Removed on March 2020. + </obsolete> + <owner>armax@chromium.org</owner> + <owner>guidou@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> The startup time of the audio service, observed from the browser process. @@ -71786,9 +71865,12 @@ </histogram> <histogram name="Media.AudioService.ObservedUptime" units="ms" - expires_after="2020-04-05"> - <owner>marinaciocea@chromium.org</owner> - <owner>maxmorin@chromium.org</owner> + expires_after="2020-03-31"> + <obsolete> + Removed on March 2020. + </obsolete> + <owner>armax@chromium.org</owner> + <owner>guidou@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> The uptime of the audio service, observed from the browser process. The @@ -71801,11 +71883,14 @@ </histogram> <histogram name="Media.AudioService.SystemInfoClient" units="ms" - expires_after="2020-04-05"> + expires_after="2020-03-31"> + <obsolete> + Removed on March 2020. + </obsolete> <!-- Name completed by histogram_suffixes name="AudioSystemInfoRequest" --> - <owner>marinaciocea@chromium.org</owner> - <owner>maxmorin@chromium.org</owner> + <owner>armax@chromium.org</owner> + <owner>guidou@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> The time interval between the moment when a client issues a system @@ -71815,9 +71900,12 @@ </histogram> <histogram name="Media.AudioService.Uptime" units="ms" - expires_after="2020-04-05"> - <owner>marinaciocea@chromium.org</owner> - <owner>maxmorin@chromium.org</owner> + expires_after="2020-03-31"> + <obsolete> + Removed on March 2020. + </obsolete> + <owner>armax@chromium.org</owner> + <owner>guidou@chromium.org</owner> <owner>olka@chromium.org</owner> <summary> The uptime of the audio service, observed from the audio service. The uptime @@ -73344,8 +73432,10 @@ </histogram> <histogram name="Media.HighLatencyAudioCaptureStartupSuccess" - enum="AudioCaptureStartupResult" expires_after="2020-04-05"> - <owner>maxmorin@chromium.org</owner> + enum="AudioCaptureStartupResult" expires_after="2020-10-01"> + <owner>armax@chromium.org</owner> + <owner>guidou@chromium.org</owner> + <owner>olka@chromium.org</owner> <summary> Whether capture started successfully after a high-latency input stream startup was requested. @@ -73597,8 +73687,10 @@ </histogram> <histogram name="Media.LowLatencyAudioCaptureStartupSuccess" - enum="AudioCaptureStartupResult" expires_after="2020-08-09"> - <owner>maxmorin@chromium.org</owner> + enum="AudioCaptureStartupResult" expires_after="2020-10-01"> + <owner>armax@chromium.org</owner> + <owner>guidou@chromium.org</owner> + <owner>olka@chromium.org</owner> <summary> Whether capture started successfully after a low-latency input stream startup was requested. @@ -75911,8 +76003,11 @@ </histogram> <histogram name="Media.VideoDecodeStatsDB.OpSuccess" enum="BooleanSuccess" - expires_after="M82"> + expires_after="never"> +<!-- expires-never: MediaCapabilities DB health metric. --> + <owner>chcunningham@chromium.org</owner> + <owner>media-dev@chromium.org</owner> <summary> Indicates whether we were successful performing some database operation. See suffix VideoDecodeStatsDBOperations. @@ -76094,8 +76189,10 @@ </histogram> <histogram name="Media.VirtualAudioCaptureStartupSuccess" - enum="AudioCaptureStartupResult" expires_after="M85"> - <owner>maxmorin@chromium.org</owner> + enum="AudioCaptureStartupResult" expires_after="2020-10-01"> + <owner>armax@chromium.org</owner> + <owner>guidou@chromium.org</owner> + <owner>olka@chromium.org</owner> <summary> Whether capture started successfully after a high-latency input stream startup was requested. @@ -76541,9 +76638,30 @@ </summary> </histogram> +<histogram name="MediaRouter.Cloud.PrefAtDialogOpen" enum="BooleanEnabled" + expires_after="2021-02-01"> + <owner>takumif@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> + <summary> + The pref value to enable the cloud services. Recorded whenever the Cast + dialog is opened. + </summary> +</histogram> + +<histogram name="MediaRouter.Cloud.PrefAtInit" enum="BooleanEnabled" + expires_after="2021-02-01"> + <owner>takumif@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> + <summary> + The pref value to enable the cloud services. Recorded whenever the browser + is initialized for a regular (not incognito or guest) profile. + </summary> +</histogram> + <histogram name="MediaRouter.Dial.AvailableDevicesCount" units="devices" - expires_after="M85"> + expires_after="2021-02-01"> <owner>mfoltz@chromium.org</owner> + <owner>takumif@chromium.org</owner> <owner>openscreen-eng@google.com</owner> <summary> The number of available DIAL devices. Recorded when browser finishes
diff --git a/tools/metrics/structured/codegen.py b/tools/metrics/structured/codegen.py index e8eecee..f5a483c 100644 --- a/tools/metrics/structured/codegen.py +++ b/tools/metrics/structured/codegen.py
@@ -34,16 +34,16 @@ def __init__(self, event_obj, project_obj): self.raw_name = event_obj['name'] self.name = sanitize_name(event_obj['name']) - self.hash = HashName(event_obj['name']) + self.name_hash = HashName(event_obj['name']) # If a project is associated with this event, project_obj will be non-None # and we should use the project's name as the key name hash. Otherwise, use # the event's name as the key name hash. if project_obj: - key_name = project_obj['name'] + project_name = sanitize_name(project_obj['name']) else: - key_name = event_obj['name'] - self.key_name_hash = HashName(key_name) + project_name = sanitize_name(event_obj['name']) + self.project_name_hash = HashName(project_name) class MetricInfo(object): @@ -95,25 +95,29 @@ file_info = FileInfo(relpath, self.basename) event_code = [] - projects = { + project_name_hashes = set() + defined_projects = { project['name']: project for project in data[_PROJECTS_TYPE.tag][_PROJECT_TYPE.tag] } for event in data[_EVENTS_TYPE.tag][_EVENT_TYPE.tag]: - project = projects.get(event.get('project')) - event_code.append(self._StampEventCode(file_info, event, project)) + defined_project = defined_projects.get(event.get('project')) + event_code.append(self._StampEventCode(file_info, event, defined_project)) + project_name_hashes.add( + defined_project['name'] if defined_project else event['name']) + event_code = ''.join(event_code) - event_name_hashes = [ - 'UINT64_C(%s)' % HashName(metric['name']) - for metric in data[_EVENTS_TYPE.tag][_EVENT_TYPE.tag] + project_name_hashes = [ + 'UINT64_C(%s)' % HashName(name) + for name in sorted(list(project_name_hashes)) ] - event_name_hashes = '{' + ', '.join(event_name_hashes) + '}' + project_name_hashes = '{' + ', '.join(project_name_hashes) + '}' return self.file_template.format( file=file_info, event_code=event_code, - event_name_hashes=event_name_hashes) + project_name_hashes=project_name_hashes) def WriteFile(self, outdir, relpath, data): """Generates code and writes it to a file.
diff --git a/tools/metrics/structured/events_template.py b/tools/metrics/structured/events_template.py index e859150..4ead309 100644 --- a/tools/metrics/structured/events_template.py +++ b/tools/metrics/structured/events_template.py
@@ -26,7 +26,7 @@ namespace structured {{ namespace events {{ -constexpr uint64_t kEventNameHashes[] = {event_name_hashes};\ +constexpr uint64_t kProjectNameHashes[] = {project_name_hashes};\ {event_code} }} // namespace events @@ -43,8 +43,8 @@ {event.name}(); ~{event.name}() override; - static constexpr uint64_t kEventNameHash = UINT64_C({event.hash}); - static constexpr uint64_t kKeyNameHash = UINT64_C({event.key_name_hash});\ + static constexpr uint64_t kEventNameHash = UINT64_C({event.name_hash}); + static constexpr uint64_t kProjectNameHash = UINT64_C({event.project_name_hash});\ {metric_code} }};\ """ @@ -84,7 +84,7 @@ IMPL_EVENT_TEMPLATE = """ {event.name}::{event.name}() : - ::metrics::structured::EventBase(kEventNameHash) {{}} + ::metrics::structured::EventBase(kEventNameHash, kProjectNameHash) {{}} {event.name}::~{event.name}() = default;\ {metric_code}\ """
diff --git a/ui/accessibility/ax_role_properties.h b/ui/accessibility/ax_role_properties.h index 53f33e6..be7bd96 100644 --- a/ui/accessibility/ax_role_properties.h +++ b/ui/accessibility/ax_role_properties.h
@@ -90,7 +90,7 @@ // Returns true if the provided role belongs to a menu or related control. AX_EXPORT bool IsMenuRelated(const ax::mojom::Role role); -// Return true if this object supports readonly. +// Returns true if this object supports readonly. // Note: This returns false for table cells and headers, it is up to the // caller to make sure that they are included IFF they are within an // ARIA-1.1+ role='grid' or 'treegrid', and not role='table'.
diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc index f0d8452..133540ca 100644 --- a/ui/base/resource/resource_bundle.cc +++ b/ui/base/resource/resource_bundle.cc
@@ -292,6 +292,14 @@ } // static +ResourceBundle* ResourceBundle::SwapSharedInstanceForTesting( + ResourceBundle* instance) { + ResourceBundle* ret = g_shared_instance_; + g_shared_instance_ = instance; + return ret; +} + +// static bool ResourceBundle::HasSharedInstance() { return g_shared_instance_ != nullptr; }
diff --git a/ui/base/resource/resource_bundle.h b/ui/base/resource/resource_bundle.h index 102bb47..3daa73bd 100644 --- a/ui/base/resource/resource_bundle.h +++ b/ui/base/resource/resource_bundle.h
@@ -148,6 +148,9 @@ // Delete the ResourceBundle for this process if it exists. static void CleanupSharedInstance(); + // Returns the existing shared instance and sets it to the given instance. + static ResourceBundle* SwapSharedInstanceForTesting(ResourceBundle* instance); + // Returns true after the global resource loader instance has been created. static bool HasSharedInstance();
diff --git a/ui/base/resource/resource_bundle_unittest.cc b/ui/base/resource/resource_bundle_unittest.cc index e1e56c5..b038ccc2 100644 --- a/ui/base/resource/resource_bundle_unittest.cc +++ b/ui/base/resource/resource_bundle_unittest.cc
@@ -150,8 +150,8 @@ } TEST_F(ResourceBundleTest, DelegateGetPathForLocalePack) { - ResourceBundle::CleanupSharedInstance(); - + ResourceBundle* orig_instance = + ResourceBundle::SwapSharedInstanceForTesting(nullptr); MockResourceBundleDelegate delegate; ResourceBundle::InitSharedInstance(&delegate); @@ -175,6 +175,7 @@ ResourceBundle::GetSharedInstance().LoadLocaleResources(locale)); ResourceBundle::CleanupSharedInstance(); + ResourceBundle::SwapSharedInstanceForTesting(orig_instance); } TEST_F(ResourceBundleTest, DelegateGetImageNamed) {