From 62ac86cb19633a8ff2edb237385a79803692fd61 Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 07:44:48 +0000 Subject: [PATCH 01/81] Roll Chrome Win32 PGO Profile Roll Chrome Win32 PGO profile from chrome-win32-master-1622483725-e592581519e2e467a881534fc9e51e3e93c1d0b1.profdata to chrome-win32-master-1622489765-425bcb96f463f5ee8cc869a9b78416fde26adec1.profdata If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/pgo-win32-chromium Please CC pgo-profile-sheriffs@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chrome.try:win-chrome Tbr: pgo-profile-sheriffs@google.com Change-Id: I52e9f938700817daf15fc7f3270328b505165eeb Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928798 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887878} --- chrome/build/win32.pgo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index f65aa3ef3d4722..ea74500e33b1a3 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt @@ -1 +1 @@ -chrome-win32-master-1622483725-e592581519e2e467a881534fc9e51e3e93c1d0b1.profdata +chrome-win32-master-1622489765-425bcb96f463f5ee8cc869a9b78416fde26adec1.profdata From e6a0b2bab231d6c3ba50e34a1a51337442e57c18 Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 08:01:37 +0000 Subject: [PATCH 02/81] Roll Chrome Win64 PGO Profile Roll Chrome Win64 PGO profile from chrome-win64-master-1622483725-e57c48324ade86a0cf5db99c0a175a0b2327d7f5.profdata to chrome-win64-master-1622489765-17f517230a1b6a8f215c9f0b82fd2c04108ce54e.profdata If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/pgo-win64-chromium Please CC pgo-profile-sheriffs@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chrome.try:win64-chrome Tbr: pgo-profile-sheriffs@google.com Change-Id: Idc9e550a4a0c74acb6e3018e64c7410c551592b9 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929580 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887879} --- chrome/build/win64.pgo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 8aa2fcbb487982..c9761b6ce3930e 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt @@ -1 +1 @@ -chrome-win64-master-1622483725-e57c48324ade86a0cf5db99c0a175a0b2327d7f5.profdata +chrome-win64-master-1622489765-17f517230a1b6a8f215c9f0b82fd2c04108ce54e.profdata From d59ace5151f8dad25400b1c921bc985004ab4ee9 Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 08:07:29 +0000 Subject: [PATCH 03/81] Roll Skia from 77724af76ce2 to fe9b4316d8de (5 revisions) https://skia.googlesource.com/skia.git/+log/77724af76ce2..fe9b4316d8de 2021-06-01 skia-autoroll@skia-public.iam.gserviceaccount.com Roll ANGLE from a9f26cc1ec75 to fe93fcdd1b48 (5 revisions) 2021-06-01 skia-autoroll@skia-public.iam.gserviceaccount.com Roll SwiftShader from f504d9ef5615 to 90c0551ca547 (1 revision) 2021-06-01 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Dawn from 2e660b38ec56 to f3db4dbca090 (5 revisions) 2021-06-01 csmartdalton@google.com Disable the indirect stroke tessellator 2021-06-01 skia-recreate-skps@skia-swarming-bots.iam.gserviceaccount.com Update SKP version If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-autoroll Please CC lovisolo@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux-blink-rel;luci.chromium.try:linux-chromeos-compile-dbg;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel Cq-Do-Not-Cancel-Tryjobs: true Bug: None Tbr: lovisolo@google.com Change-Id: I579ac35764331e4eb0f3219eda726b8cb95a350f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2927319 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887880} --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 615b9efb83f3c2..bb1e39b914c789 100644 --- a/DEPS +++ b/DEPS @@ -209,7 +209,7 @@ vars = { # 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': '77724af76ce24bc845a0909046d3fb7cd2453006', + 'skia_revision': 'fe9b4316d8de469749812376684957347b0709cd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. From 83f3041ca89911c6f11abb43e4f2dc583fedfe51 Mon Sep 17 00:00:00 2001 From: sandromaggi <sandromaggi@google.com> Date: Tue, 1 Jun 2021 08:12:06 +0000 Subject: [PATCH 04/81] [Autofill Assistant] Fix disappearing Autofill Assistant Do not detach keyboard listener on |hideTriggerScript|. The detach of the listener should be handled by the |clearNativePtr| that is called when the UI is detached. Bug: b/189283884 Change-Id: Ie84d8ee1ce3ecf34ecb46a95ac68e648142fdcf9 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929178 Reviewed-by: Clemens Arbesser <arbesser@google.com> Commit-Queue: Sandro Maggi <sandromaggi@google.com> Cr-Commit-Position: refs/heads/master@{#887881} --- .../trigger_scripts/AssistantTriggerScriptBridge.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/trigger_scripts/AssistantTriggerScriptBridge.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/trigger_scripts/AssistantTriggerScriptBridge.java index 12dd8e20a5232b..3d25cc343cbca7 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/trigger_scripts/AssistantTriggerScriptBridge.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/trigger_scripts/AssistantTriggerScriptBridge.java @@ -120,8 +120,6 @@ private boolean showTriggerScript(String[] cancelPopupMenuItems, int[] cancelPop @CalledByNative private void hideTriggerScript() { mTriggerScript.hide(); - mStartupDependencies.getKeyboardVisibilityDelegate().removeKeyboardVisibilityListener( - mKeyboardVisibilityListener); } @CalledByNative From 5e5eea490f4fe16d7e19ea310cddd600b7b7677b Mon Sep 17 00:00:00 2001 From: Miriam Polzer <mpolzer@google.com> Date: Tue, 1 Jun 2021 08:12:26 +0000 Subject: [PATCH 05/81] Increase policy store timeout and remove metrics Initially storing the device policy may take up to 180s. Increase the timeout to catch all outliers, as we only want to time out if we are sure the call is not going to return. Remove the metric that was used to determine the proper timeout value. Bug: 1166126 Test: Simple Chrome and enroll Change-Id: I8bcba3569e45b615f3487d35e11c93b5df055e88 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2917299 Commit-Queue: Miriam Polzer <mpolzer@google.com> Reviewed-by: Weilun Shi <sweilun@chromium.org> Reviewed-by: Roland Bock <rbock@google.com> Reviewed-by: Maksim Ivanov <emaxx@chromium.org> Cr-Commit-Position: refs/heads/master@{#887882} --- .../session_manager/session_manager_client.cc | 29 ++++--------------- .../histograms_xml/enterprise/histograms.xml | 3 ++ 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/chromeos/dbus/session_manager/session_manager_client.cc b/chromeos/dbus/session_manager/session_manager_client.cc index 4f97cfec8463ee..8a680f77d6d006 100644 --- a/chromeos/dbus/session_manager/session_manager_client.cc +++ b/chromeos/dbus/session_manager/session_manager_client.cc @@ -24,7 +24,6 @@ #include "base/memory/platform_shared_memory_region.h" #include "base/memory/read_only_shared_memory_region.h" #include "base/memory/writable_shared_memory_region.h" -#include "base/metrics/histogram_functions.h" #include "base/path_service.h" #include "base/strings/string_util.h" #include "base/threading/thread_task_runner_handle.h" @@ -709,18 +708,6 @@ class SessionManagerClientImpl : public SessionManagerClient { std::move(callback).Run(response); } - // Called when `StorePolicyEx()` finishes. - void OnStorePolicyEx(base::TimeTicks store_policy_ex_start_time, - VoidDBusMethodCallback callback, - dbus::Response* response) { - base::TimeTicks now = base::TimeTicks::Now(); - DCHECK(!store_policy_ex_start_time.is_null()); - base::TimeDelta delta = now - store_policy_ex_start_time; - base::UmaHistogramMediumTimes("Enterprise.StorePolicy.Duration", delta); - - OnVoidMethod(std::move(callback), response); - } - // Non-blocking call to Session Manager to retrieve policy. void CallRetrievePolicy(const login_manager::PolicyDescriptor& descriptor, RetrievePolicyCallback callback) { @@ -784,17 +771,13 @@ class SessionManagerClientImpl : public SessionManagerClient { writer.AppendArrayOfBytes( reinterpret_cast<const uint8_t*>(policy_blob.data()), policy_blob.size()); - // TODO(crbug/1155533) On grunt devices, initially storing device policy may - // take about 45s, which is longer than the default timeout for dbus calls. - // We need to investigate why this is happening. In the meantime, increase - // the timeout to make sure enrollment does not fail. - // Record the timing to find a reasonable timeout value. - base::TimeTicks store_policy_ex_start_time = base::TimeTicks::Now(); + // The timeout is intentionally chosen to be that big because on some + // devices the operation is slow and a short timeout would lead to + // unnecessary enrollment failures. See crbug.com/1155533 for context. session_manager_proxy_->CallMethod( - &method_call, /*timeout_ms=*/90000, - base::BindOnce(&SessionManagerClientImpl::OnStorePolicyEx, - weak_ptr_factory_.GetWeakPtr(), - store_policy_ex_start_time, std::move(callback))); + &method_call, /*timeout_ms=*/180000, + base::BindOnce(&SessionManagerClientImpl::OnVoidMethod, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } // Called when kSessionManagerRetrieveActiveSessions method is complete. diff --git a/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml b/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml index 6bd1a7b83bec34..9b4c6b94382006 100644 --- a/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/enterprise/histograms.xml @@ -1417,6 +1417,9 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. <histogram name="Enterprise.StorePolicy.Duration" units="ms" expires_after="2021-10-10"> + <obsolete> + Removed in M93. + </obsolete> <owner>mpolzer@google.com</owner> <owner>managed-platforms@google.com</owner> <summary> From c470aa52f6e98c5d8322a76028f9b62aea63841d Mon Sep 17 00:00:00 2001 From: Christopher Lam <calamity@chromium.org> Date: Tue, 1 Jun 2021 08:21:51 +0000 Subject: [PATCH 06/81] Fix WebAppIconManagerTest from dirtying the test environment. Leaving the UI scale factor at 100P/300P in WebAppIconManagerTest was causing the next WebAppInstallTaskTest to crash when it tried to load a user icon at 300P. This CL changes WebAppIconManagerTest to use ScopedSetSupportedScaleFactors which resets the values post-test. Bug: 1215006 Change-Id: Ibb9ada4bb22869a87bd3b7f329ae49faca6afd58 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929637 Commit-Queue: calamity <calamity@chromium.org> Reviewed-by: Alexey Baskakov <loyso@chromium.org> Cr-Commit-Position: refs/heads/master@{#887883} --- .../web_app_icon_manager_unittest.cc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/chrome/browser/web_applications/web_app_icon_manager_unittest.cc b/chrome/browser/web_applications/web_app_icon_manager_unittest.cc index 3a4bc05b2bb739..3a509dc04520f0 100644 --- a/chrome/browser/web_applications/web_app_icon_manager_unittest.cc +++ b/chrome/browser/web_applications/web_app_icon_manager_unittest.cc @@ -1381,7 +1381,7 @@ TEST_F(WebAppIconManagerTest, CacheNewAppFavicon) { } TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_NoMissingIcons) { - ui::SetSupportedScaleFactors( + ui::test::ScopedSetSupportedScaleFactors scoped_scale_factors( {ui::SCALE_FACTOR_100P, ui::SCALE_FACTOR_200P, ui::SCALE_FACTOR_300P}); std::unique_ptr<WebApp> web_app = CreateWebApp(); @@ -1424,7 +1424,8 @@ TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_NoMissingIcons) { } TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_DownsizingIcons) { - ui::SetSupportedScaleFactors({ui::SCALE_FACTOR_100P, ui::SCALE_FACTOR_200P}); + ui::test::ScopedSetSupportedScaleFactors scoped_scale_factors( + {ui::SCALE_FACTOR_100P, ui::SCALE_FACTOR_200P}); std::unique_ptr<WebApp> web_app = CreateWebApp(); const AppId app_id = web_app->app_id(); @@ -1461,7 +1462,8 @@ TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_DownsizingIcons) { } TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_NoIcons) { - ui::SetSupportedScaleFactors({ui::SCALE_FACTOR_100P, ui::SCALE_FACTOR_200P}); + ui::test::ScopedSetSupportedScaleFactors scoped_scale_factors( + {ui::SCALE_FACTOR_100P, ui::SCALE_FACTOR_200P}); std::unique_ptr<WebApp> web_app = CreateWebApp(); const AppId app_id = web_app->app_id(); @@ -1474,7 +1476,8 @@ TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_NoIcons) { } TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_NoMatchSmaller) { - ui::SetSupportedScaleFactors({ui::SCALE_FACTOR_200P, ui::SCALE_FACTOR_300P}); + ui::test::ScopedSetSupportedScaleFactors scoped_scale_factors( + {ui::SCALE_FACTOR_200P, ui::SCALE_FACTOR_300P}); std::unique_ptr<WebApp> web_app = CreateWebApp(); const AppId app_id = web_app->app_id(); @@ -1495,7 +1498,8 @@ TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_NoMatchSmaller) { TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_DownsizingFromSingleIcon) { - ui::SetSupportedScaleFactors({ui::SCALE_FACTOR_100P, ui::SCALE_FACTOR_200P}); + ui::test::ScopedSetSupportedScaleFactors scoped_scale_factors( + {ui::SCALE_FACTOR_100P, ui::SCALE_FACTOR_200P}); std::unique_ptr<WebApp> web_app = CreateWebApp(); const AppId app_id = web_app->app_id(); @@ -1529,7 +1533,8 @@ TEST_F(WebAppIconManagerTest, TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_BiggerUiScaleFactorIconMissing) { - ui::SetSupportedScaleFactors({ui::SCALE_FACTOR_100P, ui::SCALE_FACTOR_300P}); + ui::test::ScopedSetSupportedScaleFactors scoped_scale_factors( + {ui::SCALE_FACTOR_100P, ui::SCALE_FACTOR_300P}); std::unique_ptr<WebApp> web_app = CreateWebApp(); const AppId app_id = web_app->app_id(); From 38c2b3c5f18bfaf68d14f1e3014aa78728e9da9e Mon Sep 17 00:00:00 2001 From: Chrome Metrics Logs <chrome-metrics-team+robot@google.com> Date: Tue, 1 Jun 2021 08:25:59 +0000 Subject: [PATCH 07/81] Delay expiry of frequently used histograms. Updates the expires_after attribute for 34 histograms that show frequent access in the past 180 days. These are the 99% most frequently used histograms over that time that do not already have a date later than or within 60 days of 2021-08-30. TBR=chromium-metrics-reviews@google.com Change-Id: I3b34310bef4bf8a0d1c768872c60f9ddc0c30d56 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929359 Commit-Queue: Chrome Metrics Logs <chrome-metrics-team+robot@google.com> Bot-Commit: Chrome Metrics Logs <chrome-metrics-team+robot@google.com> Cr-Commit-Position: refs/heads/master@{#887884} --- .../histograms_xml/accessibility/histograms.xml | 2 +- .../histograms/histograms_xml/apps/histograms.xml | 2 +- .../histograms/histograms_xml/arc/histograms.xml | 4 ++-- .../histograms/histograms_xml/ash/histograms.xml | 6 +++--- .../histograms/histograms_xml/blink/histograms.xml | 2 +- .../histograms_xml/holding_space/histograms.xml | 14 +++++++------- .../histograms/histograms_xml/ios/histograms.xml | 4 ++-- .../histograms_xml/memory/histograms.xml | 2 +- .../histograms/histograms_xml/net/histograms.xml | 2 +- .../histograms_xml/others/histograms.xml | 10 +++++----- .../histograms_xml/platform/histograms.xml | 2 +- .../histograms/histograms_xml/power/histograms.xml | 4 ++-- .../histograms_xml/safe_browsing/histograms.xml | 4 ++-- .../histograms/histograms_xml/uma/histograms.xml | 2 +- .../histograms_xml/web_rtc/histograms.xml | 8 ++++---- 15 files changed, 34 insertions(+), 34 deletions(-) diff --git a/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml b/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml index 33e801fdb8ee37..515b658de4cc1b 100644 --- a/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml @@ -177,7 +177,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Accessibility.ChromeVox.PerformGestureType" - enum="ChromeVoxGestureType" expires_after="2021-09-19"> + enum="ChromeVoxGestureType" expires_after="2021-11-28"> <owner>dtseng@chromium.org</owner> <owner>chrome-a11y-core@google.com</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/apps/histograms.xml b/tools/metrics/histograms/histograms_xml/apps/histograms.xml index 1223dda158fba6..78c42f928f91c3 100644 --- a/tools/metrics/histograms/histograms_xml/apps/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/apps/histograms.xml @@ -1174,7 +1174,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Apps.AppListRecommendedImpResultCountAfterOpen" units="shows" - expires_after="2021-09-27"> + expires_after="2021-11-28"> <owner>napper@chromium.org</owner> <owner>robsc@chromium.org</owner> <owner>thanhdng@chromium.org</owner> diff --git a/tools/metrics/histograms/histograms_xml/arc/histograms.xml b/tools/metrics/histograms/histograms_xml/arc/histograms.xml index 9d7136c46b9b60..87ab959eb86f66 100644 --- a/tools/metrics/histograms/histograms_xml/arc/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/arc/histograms.xml @@ -1069,7 +1069,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Arc.Runtime.Performance.Generic.FrameTime" units="ms" - expires_after="2021-09-28"> + expires_after="2021-11-28"> <owner>camurcu@google.com</owner> <owner>khmel@google.com</owner> <summary> @@ -1079,7 +1079,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Arc.Runtime.Performance.Generic.Jankiness" units="%" - expires_after="2021-09-28"> + expires_after="2021-11-28"> <owner>camurcu@google.com</owner> <owner>khmel@google.com</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/ash/histograms.xml b/tools/metrics/histograms/histograms_xml/ash/histograms.xml index b89a7b12f01dfb..cf97e806373c19 100644 --- a/tools/metrics/histograms/histograms_xml/ash/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/ash/histograms.xml @@ -355,7 +355,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Ash.CaptureModeController.ScreenshotsPerDay" units="int" - expires_after="2021-09-29"> + expires_after="2021-11-28"> <owner>afakhry@chromium.org</owner> <owner>gzadina@google.com</owner> <summary> @@ -367,7 +367,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Ash.CaptureModeController.ScreenshotsPerWeek" units="int" - expires_after="2021-09-29"> + expires_after="2021-11-28"> <owner>afakhry@chromium.org</owner> <owner>gzadina@google.com</owner> <summary> @@ -2011,7 +2011,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Ash.ScreenshotController.ScreenshotsPerWeek" units="int" - expires_after="2021-09-29"> + expires_after="2021-11-28"> <owner>xiyuan@chromium.org</owner> <owner>gzadina@google.com</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/blink/histograms.xml b/tools/metrics/histograms/histograms_xml/blink/histograms.xml index 06ac1028f824ae..c3bf4e13d897a9 100644 --- a/tools/metrics/histograms/histograms_xml/blink/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/blink/histograms.xml @@ -2645,7 +2645,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram base="true" name="Blink.Style.UpdateTime" units="microseconds" - expires_after="2021-09-26"> + expires_after="2021-11-28"> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePreFCPSuffixes" --> <!-- Name completed by histogram_suffixes name="BlinkUpdateTimePostFCPSuffixes" --> diff --git a/tools/metrics/histograms/histograms_xml/holding_space/histograms.xml b/tools/metrics/histograms/histograms_xml/holding_space/histograms.xml index 2a1a89b5b36b9e..0d62831a95a8bb 100644 --- a/tools/metrics/histograms/histograms_xml/holding_space/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/holding_space/histograms.xml @@ -52,7 +52,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </variants> <histogram name="HoldingSpace.Animation.BubbleResize.Smoothness" units="%" - expires_after="2021-09-24"> + expires_after="2021-11-28"> <owner>dmblack@google.com</owner> <owner>gzadina@google.com</owner> <summary> @@ -76,7 +76,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="HoldingSpace.Downloads.Action.All" - enum="HoldingSpaceDownloadsAction" expires_after="2021-09-24"> + enum="HoldingSpaceDownloadsAction" expires_after="2021-11-28"> <owner>dmblack@google.com</owner> <owner>gzadina@google.com</owner> <summary> @@ -86,7 +86,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="HoldingSpace.FilesAppChip.Action.All" - enum="HoldingSpaceFilesAppChipAction" expires_after="2021-09-24"> + enum="HoldingSpaceFilesAppChipAction" expires_after="2021-11-28"> <owner>dmblack@google.com</owner> <owner>gzadina@google.com</owner> <summary> @@ -96,7 +96,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="HoldingSpace.Item.Action.All" enum="HoldingSpaceItemAction" - expires_after="2021-09-24"> + expires_after="2021-11-28"> <owner>dmblack@google.com</owner> <owner>gzadina@google.com</owner> <summary> @@ -159,7 +159,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="HoldingSpace.Pod.Action.All" enum="HoldingSpacePodAction" - expires_after="2021-09-24"> + expires_after="2021-11-28"> <owner>dmblack@google.com</owner> <owner>gzadina@google.com</owner> <summary> @@ -179,7 +179,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="HoldingSpace.TimeFromFirstAvailabilityToFirstEntry" units="ms" - expires_after="2021-09-24"> + expires_after="2021-11-28"> <owner>dmblack@google.com</owner> <owner>gzadina@google.com</owner> <summary> @@ -189,7 +189,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="HoldingSpace.TimeFromFirstEntryToFirstPin" units="ms" - expires_after="2021-09-24"> + expires_after="2021-11-28"> <owner>dmblack@google.com</owner> <owner>gzadina@google.com</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/ios/histograms.xml b/tools/metrics/histograms/histograms_xml/ios/histograms.xml index 37fa6cc98f8db1..3f2fabcef398d8 100644 --- a/tools/metrics/histograms/histograms_xml/ios/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/ios/histograms.xml @@ -1058,7 +1058,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </summary> </histogram> -<histogram name="IOS.Snapshots.ImageSize" units="KB" expires_after="2021-09-12"> +<histogram name="IOS.Snapshots.ImageSize" units="KB" expires_after="2021-11-28"> <owner>ajuma@chromium.org</owner> <owner>edchin@chromium.org</owner> <summary> @@ -1067,7 +1067,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </summary> </histogram> -<histogram name="IOS.Snapshots.PDFSize" units="KB" expires_after="2021-09-12"> +<histogram name="IOS.Snapshots.PDFSize" units="KB" expires_after="2021-11-28"> <owner>ajuma@chromium.org</owner> <owner>edchin@chromium.org</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/memory/histograms.xml b/tools/metrics/histograms/histograms_xml/memory/histograms.xml index 181137e7001e01..259060809c99c6 100644 --- a/tools/metrics/histograms/histograms_xml/memory/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/memory/histograms.xml @@ -1615,7 +1615,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Memory.NativeLibrary.MappedAndResidentMemoryFootprint3" - units="KB" expires_after="2021-09-27"> + units="KB" expires_after="2021-11-28"> <owner>lizeb@chromium.org</owner> <owner>pasko@chromium.org</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/net/histograms.xml b/tools/metrics/histograms/histograms_xml/net/histograms.xml index 87d3e77436444f..5a55518f4e802f 100644 --- a/tools/metrics/histograms/histograms_xml/net/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/net/histograms.xml @@ -5018,7 +5018,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Net.SpdySessionErrorDetails2" enum="SpdyProtocolErrorDetails2" - expires_after="2021-09-26"> + expires_after="2021-11-28"> <owner>dschinazi@chromium.org</owner> <owner>src/net/OWNERS</owner> <summary>The type of SPDY Protocol error encountered.</summary> diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index 9270f71d9fcbf9..58238059ec4356 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml @@ -12267,7 +12267,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Privacy.AccessContextAudit.CookieDomainCount" units="units" - expires_after="2021-09-19"> + expires_after="2021-11-28"> <owner>msramek@chromium.org</owner> <owner>sauski@google.com</owner> <summary> @@ -12278,7 +12278,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Privacy.AccessContextAudit.DatabaseSize" units="KiB" - expires_after="2021-09-19"> + expires_after="2021-11-28"> <owner>msramek@chromium.org</owner> <owner>sauski@google.com</owner> <summary> @@ -12289,7 +12289,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Privacy.AccessContextAudit.RecordCount" units="units" - expires_after="2021-09-19"> + expires_after="2021-11-28"> <owner>msramek@chromium.org</owner> <owner>sauski@google.com</owner> <summary> @@ -12300,7 +12300,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Privacy.AccessContextAudit.StorageOriginCount" units="units" - expires_after="2021-09-19"> + expires_after="2021-11-28"> <owner>msramek@chromium.org</owner> <owner>sauski@google.com</owner> <summary> @@ -12311,7 +12311,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Privacy.AccessContextAudit.TopFrameOriginCount" units="units" - expires_after="2021-09-19"> + expires_after="2021-11-28"> <owner>msramek@chromium.org</owner> <owner>sauski@google.com</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/platform/histograms.xml b/tools/metrics/histograms/histograms_xml/platform/histograms.xml index c35b55c8fce27c..072e727a077170 100644 --- a/tools/metrics/histograms/histograms_xml/platform/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/platform/histograms.xml @@ -213,7 +213,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Platform.Cr50.RlzOfBoardIdMismatch" enum="Cr50CrosRlzCodes" - expires_after="2021-09-26"> + expires_after="2021-11-28"> <owner>vbendeb@chromium.org</owner> <owner>apronin@chromium.org</owner> <owner>cros-hwsec+uma@chromium.org</owner> diff --git a/tools/metrics/histograms/histograms_xml/power/histograms.xml b/tools/metrics/histograms/histograms_xml/power/histograms.xml index 2e6d885b205a7f..9ea7f50ca13aef 100644 --- a/tools/metrics/histograms/histograms_xml/power/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/power/histograms.xml @@ -97,7 +97,7 @@ Also used in tools/metrics/histograms/histograms_xml/others/histograms.xml </histogram> <histogram name="Power.BatteryDischargeRate" units="mW" - expires_after="2021-11-21"> + expires_after="2021-11-28"> <owner>tbroch@chromium.org</owner> <summary> Chrome OS battery discharge rate in mW sampled every 30 seconds while the @@ -316,7 +316,7 @@ Also used in tools/metrics/histograms/histograms_xml/others/histograms.xml </histogram> <histogram name="Power.CpuTimeSecondsPerProcessType" enum="ProcessType2" - expires_after="2021-11-21"> + expires_after="2021-11-28"> <owner>eseckler@chromium.org</owner> <owner>skyostil@chromium.org</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml b/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml index 18aeea86d5225a..479ff77b880fdb 100644 --- a/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/safe_browsing/histograms.xml @@ -1910,7 +1910,7 @@ and applied correctly. --> </histogram> <histogram name="SafeBrowsing.V4Update.Network.Result" - enum="CombinedHttpResponseAndNetErrorCode" expires_after="2021-09-26"> + enum="CombinedHttpResponseAndNetErrorCode" expires_after="2021-11-28"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -1935,7 +1935,7 @@ risk. --> </histogram> <histogram name="SafeBrowsing.V4Update.ResponseSizeKB" units="KB" - expires_after="2021-09-26"> + expires_after="2021-11-28"> <owner>vakh@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/uma/histograms.xml b/tools/metrics/histograms/histograms_xml/uma/histograms.xml index ce5df7e7e2e914..fbb97843b005b6 100644 --- a/tools/metrics/histograms/histograms_xml/uma/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/uma/histograms.xml @@ -589,7 +589,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="UMA.TruncatedEvents.UserAction" units="events" - expires_after="2021-11-21"> + expires_after="2021-11-28"> <owner>rkaplow@chromium.org</owner> <owner>src/base/metrics/OWNERS</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml b/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml index 8faceb4de33939..fe827bb3beed03 100644 --- a/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml @@ -804,7 +804,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="WebRTC.Audio.SpeechExpandRatePercent" units="%" - expires_after="2021-09-26"> + expires_after="2021-11-28"> <owner>hlundin@chromium.org</owner> <summary> Measures the audible expand rate for an incoming WebRTC audio stream. The @@ -1803,7 +1803,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="WebRTC.ReceivedAudioTrackDuration" units="ms" - expires_after="2021-09-26"> + expires_after="2021-11-28"> <owner>perkj@chromium.org</owner> <summary> Durations of audio tracks received over a PeerConnection. The stopwatch @@ -1813,7 +1813,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="WebRTC.ReceivedVideoTrackDuration" units="ms" - expires_after="2021-09-26"> + expires_after="2021-11-28"> <owner>perkj@chromium.org</owner> <summary> Durations of video tracks received over a PeerConnection. The stopwatch @@ -1839,7 +1839,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="WebRTC.SentAudioTrackDuration" units="ms" - expires_after="2021-09-26"> + expires_after="2021-11-28"> <owner>perkj@chromium.org</owner> <summary> Durations of audio tracks sent over a PeerConnection. The stopwatch starts From f8f1ed2c9c6caa43b242687ddfdf7e514bc40922 Mon Sep 17 00:00:00 2001 From: Eriko Kurimoto <elkurin@chromium.org> Date: Tue, 1 Jun 2021 08:28:00 +0000 Subject: [PATCH 08/81] Remove ui/events/ozone/evdev library from wayland build This CL removes ui/events/ozone/evdev library from wayland build since it is not used. By this removal, the binary size of chrome is reduced by 96 byte. Bug: 1211307 Change-Id: I42ec7c463c39f627f12e8d6cdb53128507c2fe84 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2908356 Reviewed-by: Hidehiko Abe <hidehiko@chromium.org> Reviewed-by: Michael Spang <spang@chromium.org> Commit-Queue: Eriko Kurimoto <elkurin@chromium.org> Cr-Commit-Position: refs/heads/master@{#887885} --- ui/ozone/platform/wayland/BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index 40b71e72e90b9b..0368a75a264908 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn @@ -212,7 +212,6 @@ source_set("wayland") { "//ui/events/devices", "//ui/events/keycodes:xkb", "//ui/events/ozone", - "//ui/events/ozone/evdev", "//ui/events/ozone/layout", "//ui/events/platform", "//ui/gfx", From 72a5b9361df5e730d1fa2602ef725620375f767d Mon Sep 17 00:00:00 2001 From: v8-ci-autoroll-builder <v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 08:35:51 +0000 Subject: [PATCH 09/81] Update V8 to version 9.3.39. Summary of changes available at: https://chromium.googlesource.com/v8/v8/+log/115347c2..fe7a5763 Please follow these instructions for assigning/CC'ing issues: https://v8.dev/docs/triage-issues Please close rolling in case of a roll revert: https://v8-roll.appspot.com/ This only works with a Google account. CQ_INCLUDE_TRYBOTS=luci.chromium.try:linux-blink-rel CQ_INCLUDE_TRYBOTS=luci.chromium.try:linux_optional_gpu_tests_rel CQ_INCLUDE_TRYBOTS=luci.chromium.try:mac_optional_gpu_tests_rel CQ_INCLUDE_TRYBOTS=luci.chromium.try:win_optional_gpu_tests_rel CQ_INCLUDE_TRYBOTS=luci.chromium.try:android_optional_gpu_tests_rel R=hablich@chromium.org,vahl@chromium.org,v8-waterfall-sheriff@grotations.appspotmail.com Change-Id: I1d860541926050ea964ebb0c3e937618475f23cd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928799 Bot-Commit: v8-ci-autoroll-builder <v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com> Commit-Queue: v8-ci-autoroll-builder <v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887886} --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index bb1e39b914c789..3b7998fe936df0 100644 --- a/DEPS +++ b/DEPS @@ -213,7 +213,7 @@ vars = { # 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': '115347c24efce03c9f79e62b71430fd13d94eff5', + 'v8_revision': 'fe7a5763a6a008e2c6744390db949308acd5602f', # 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. From e93b7aec81b80da6b80fb186b7bca774e1edefb7 Mon Sep 17 00:00:00 2001 From: Internal Frameworks Autoroller <bling-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 08:42:47 +0000 Subject: [PATCH 10/81] [Frameworks roll] Roll to 376769643 piper revision Change-Id: I7a3b38bd781553609b458f40846571bfb73eb156 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929257 Commit-Queue: Internal Frameworks Autoroller <bling-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com> Bot-Commit: Internal Frameworks Autoroller <bling-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887887} --- .../frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 | 2 +- .../frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 | 2 +- .../chrome_sso_internal_dynamic_framework.arm64.zip.sha1 | 2 +- .../chrome_sso_internal_dynamic_framework.x64.zip.sha1 | 2 +- .../remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 | 2 +- .../remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 | 2 +- .../remoting_internal_dynamic_framework.arm64.zip.sha1 | 2 +- .../frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 | 2 +- .../web_view_shell_internal_dynamic_framework.arm64.zip.sha1 | 2 +- .../web_view_shell_internal_dynamic_framework.x64.zip.sha1 | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 index 5072bb9d2b9f33..62ba4e572b243e 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.arm64.zip.sha1 @@ -1 +1 @@ -0922ae42b0e78d9ebbcf20efa7d8fe38c1b77537 \ No newline at end of file +b165ec4bd7a5979a32893cd52ecd39e61cc65339 \ No newline at end of file diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 index d2db8a059fe6c0..f133e9bca0834b 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.x64.zip.sha1 @@ -1 +1 @@ -af4b9d94863deb39c97c908e28d826cab414f25e \ No newline at end of file +36f7829f239fab66d5af0bde8373c1c97186821f \ No newline at end of file diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 index 43b35ac86acaf4..a0051aab4a1d3e 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.arm64.zip.sha1 @@ -1 +1 @@ -f86a5d873c9b09028636abe715c3e268dd04cc3c \ No newline at end of file +21c7a1e4734ce5005e50a4f07419bb693470d473 \ No newline at end of file diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 index 9ff4743634d1dd..c468ff23ee8150 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.x64.zip.sha1 @@ -1 +1 @@ -1ca63bc557cd10f136305ace705a0204e66bd84f \ No newline at end of file +165894cdafef013703fb57c6dca18ded340f5718 \ No newline at end of file diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 index 36867334146de0..05f1959b8fa287 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.arm64.zip.sha1 @@ -1 +1 @@ -c8e08b808e499fa8915a0911ab5444ba62834c59 \ No newline at end of file +0471019a3826bd272307ab625bf5bb3de791a8eb \ No newline at end of file diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 index caa81dd4191953..6e076187c23d8b 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.x64.zip.sha1 @@ -1 +1 @@ -108b092f9a0f3e22565f030ef7931cbd8bf763d5 \ No newline at end of file +bcf5330f3f49eda35b79d1f397e97b280d4074ec \ No newline at end of file diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 index 9469144c86eda1..a2fd07bf96bc8b 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.arm64.zip.sha1 @@ -1 +1 @@ -8b410ffbd936c68aec0016c62a6c4d6ca707ec10 \ No newline at end of file +ab01efc21b39b87bb64ae359b65ac97c68af8f04 \ No newline at end of file diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 index 38e6089054e3c3..4ae4442ccc725f 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.x64.zip.sha1 @@ -1 +1 @@ -03234f6d1e9d65e72af376880ef03017044d688a \ No newline at end of file +9be3d6042aa1ec76bebc57b2d1a8380abcd058d2 \ No newline at end of file diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 index b04b88312f3751..81df60e3682216 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.arm64.zip.sha1 @@ -1 +1 @@ -4398877ea8a87b8bafffde620a60b8679b6ffcf0 \ No newline at end of file +975c899c4005d936f8734d84cdf0d3470658c282 \ No newline at end of file diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 index 302ae04d658015..f48b80ef278981 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.x64.zip.sha1 @@ -1 +1 @@ -9fb642fd85e02d4044396221433dd9fd416904ff \ No newline at end of file +9deb5535c74ff72c62913f93ee134338bbf3599c \ No newline at end of file From ac730dbaa4a2876204cfc02b937d4381308e0869 Mon Sep 17 00:00:00 2001 From: Kunihiko Sakamoto <ksakamoto@chromium.org> Date: Tue, 1 Jun 2021 08:52:20 +0000 Subject: [PATCH 11/81] Extend expiry of WebFont.DownloadTime.* histograms These are our basic performance metrics for WebFonts. Let's keep them. Bug: 1205091 Change-Id: I2b252f1003eea754778644acf2451a282160b08e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929404 Reviewed-by: Takashi Toyoshima <toyoshim@chromium.org> Commit-Queue: Kunihiko Sakamoto <ksakamoto@chromium.org> Cr-Commit-Position: refs/heads/master@{#887888} --- .../histograms/histograms_xml/others/histograms.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index 58238059ec4356..be157cdfbb7e63 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml @@ -18714,7 +18714,7 @@ regressions. --> </histogram> <histogram name="WebFont.DownloadTime.0.Under10KB" units="ms" - expires_after="2021-08-15"> + expires_after="2022-01-15"> <owner>kenjibaheux@chromium.org</owner> <owner>ksakamoto@chromium.org</owner> <summary> @@ -18724,7 +18724,7 @@ regressions. --> </histogram> <histogram name="WebFont.DownloadTime.1.10KBTo50KB" units="ms" - expires_after="2021-08-15"> + expires_after="2022-01-15"> <owner>kenjibaheux@chromium.org</owner> <owner>ksakamoto@chromium.org</owner> <summary> @@ -18734,7 +18734,7 @@ regressions. --> </histogram> <histogram name="WebFont.DownloadTime.2.50KBTo100KB" units="ms" - expires_after="2021-08-15"> + expires_after="2022-01-15"> <owner>kenjibaheux@chromium.org</owner> <owner>ksakamoto@chromium.org</owner> <summary> @@ -18744,7 +18744,7 @@ regressions. --> </histogram> <histogram name="WebFont.DownloadTime.3.100KBTo1MB" units="ms" - expires_after="2021-08-15"> + expires_after="2022-01-15"> <owner>kenjibaheux@chromium.org</owner> <owner>ksakamoto@chromium.org</owner> <summary> @@ -18754,7 +18754,7 @@ regressions. --> </histogram> <histogram name="WebFont.DownloadTime.4.Over1MB" units="ms" - expires_after="2021-08-15"> + expires_after="2022-01-15"> <owner>kenjibaheux@chromium.org</owner> <owner>ksakamoto@chromium.org</owner> <summary> @@ -18764,7 +18764,7 @@ regressions. --> </histogram> <histogram name="WebFont.DownloadTime.LoadError" units="ms" - expires_after="2021-06-13"> + expires_after="2022-01-15"> <owner>kenjibaheux@chromium.org</owner> <owner>ksakamoto@chromium.org</owner> <summary> From 3925835c30ea34d16d7f9876141e04bda0f89fa0 Mon Sep 17 00:00:00 2001 From: Omar Morsi <omorsi@google.com> Date: Tue, 1 Jun 2021 08:56:10 +0000 Subject: [PATCH 12/81] [Platform Keys Service] Explicitly run callbacks on UI thread This CL doesn't change the behavior of platform keys service, it only makes it more clear to readers that all of the replies of platform keys service operations will run on the UI thread. Bug: 1214848 Change-Id: Ifb87e32d8decc20a0414d7d29dec7a5e249c2b22 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2927590 Commit-Queue: Omar Morsi <omorsi@google.com> Reviewed-by: Maksim Ivanov <emaxx@chromium.org> Cr-Commit-Position: refs/heads/master@{#887889} --- .../platform_keys_service_nss.cc | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service_nss.cc b/chrome/browser/chromeos/platform_keys/platform_keys_service_nss.cc index 80c4c86b17d15c..ff4494c825c596 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_service_nss.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys_service_nss.cc @@ -82,8 +82,7 @@ using ServiceWeakPtr = base::WeakPtr<PlatformKeysServiceImpl>; class NSSOperationState { public: explicit NSSOperationState(ServiceWeakPtr weak_ptr) - : service_weak_ptr_(weak_ptr), - origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) {} + : service_weak_ptr_(weak_ptr) {} virtual ~NSSOperationState() = default; @@ -102,9 +101,6 @@ class NSSOperationState { // Weak pointer to the PlatformKeysServiceImpl that created this state. Used // to check if the callback should be still called. ServiceWeakPtr service_weak_ptr_; - // The task runner on which the NSS operation was called. Any reply must be - // posted to this runner. - scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_; private: DISALLOW_COPY_AND_ASSIGN(NSSOperationState); @@ -192,7 +188,7 @@ class GenerateRSAKeyState : public NSSOperationState { status == Status::kSuccess); auto bound_callback = base::BindOnce(std::move(callback_), public_key_spki_der, status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -231,7 +227,7 @@ class GenerateECKeyState : public NSSOperationState { status == Status::kSuccess); auto bound_callback = base::BindOnce(std::move(callback_), public_key_spki_der, status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -287,7 +283,7 @@ class SignState : public NSSOperationState { EmitOperationStatusToHistogram(status == Status::kSuccess); auto bound_callback = base::BindOnce(std::move(callback_), signature, status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -340,7 +336,7 @@ class SelectCertificatesState : public NSSOperationState { Status status) { auto bound_callback = base::BindOnce(std::move(callback_), std::move(matches), status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -376,7 +372,7 @@ class GetCertificatesState : public NSSOperationState { Status status) { auto bound_callback = base::BindOnce(std::move(callback_), std::move(certs), status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -408,7 +404,7 @@ class GetAllKeysState : public NSSOperationState { Status status) { auto bound_callback = base::BindOnce( std::move(callback_), std::move(public_key_spki_der_list), status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -441,7 +437,7 @@ class ImportCertificateState : public NSSOperationState { private: void CallBack(const base::Location& from, Status status) { auto bound_callback = base::BindOnce(std::move(callback_), status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -474,7 +470,7 @@ class RemoveCertificateState : public NSSOperationState { private: void CallBack(const base::Location& from, Status status) { auto bound_callback = base::BindOnce(std::move(callback_), status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -508,7 +504,7 @@ class RemoveKeyState : public NSSOperationState { private: void CallBack(const base::Location& from, Status status) { auto bound_callback = base::BindOnce(std::move(callback_), status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -540,7 +536,7 @@ class GetTokensState : public NSSOperationState { Status status) { auto bound_callback = base::BindOnce(std::move(callback_), std::move(token_ids), status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -578,7 +574,7 @@ class GetKeyLocationsState : public NSSOperationState { Status status) { auto bound_callback = base::BindOnce(std::move(callback_), token_ids, status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -618,7 +614,7 @@ class SetAttributeForKeyState : public NSSOperationState { private: void CallBack(const base::Location& from, Status status) { auto bound_callback = base::BindOnce(std::move(callback_), status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -659,7 +655,7 @@ class GetAttributeForKeyState : public NSSOperationState { Status status) { auto bound_callback = base::BindOnce(std::move(callback_), attribute_value, status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } @@ -696,7 +692,7 @@ class IsKeyOnTokenState : public NSSOperationState { Status status) { auto bound_callback = base::BindOnce(std::move(callback_), on_token, status); - origin_task_runner_->PostTask( + content::GetUIThreadTaskRunner({})->PostTask( from, base::BindOnce(&NSSOperationState::RunCallback, std::move(bound_callback), service_weak_ptr_)); } From b78919db194dff1e22f6cdba131a5e69b68e8457 Mon Sep 17 00:00:00 2001 From: Chrome Metrics Logs <chrome-metrics-team+robot@google.com> Date: Tue, 1 Jun 2021 08:56:20 +0000 Subject: [PATCH 13/81] Delay expiry of histograms causing alerts. Updates the expires_after attribute for 20 histograms that have been used to generate alerts in the past 180 days and do not already have a date later than or within 60 days of 2021-08-30. TBR=chromium-metrics-reviews@google.com Change-Id: I1b34e7748021531f3f52c3f77249d92674744ee0 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929358 Commit-Queue: Chrome Metrics Logs <chrome-metrics-team+robot@google.com> Bot-Commit: Chrome Metrics Logs <chrome-metrics-team+robot@google.com> Cr-Commit-Position: refs/heads/master@{#887890} --- .../histograms/histograms_xml/android/histograms.xml | 6 +++--- tools/metrics/histograms/histograms_xml/gpu/histograms.xml | 2 +- tools/metrics/histograms/histograms_xml/net/histograms.xml | 2 +- .../metrics/histograms/histograms_xml/others/histograms.xml | 6 +++--- tools/metrics/histograms/histograms_xml/page/histograms.xml | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/metrics/histograms/histograms_xml/android/histograms.xml b/tools/metrics/histograms/histograms_xml/android/histograms.xml index 52052e57c448d4..056dc0b72e6585 100644 --- a/tools/metrics/histograms/histograms_xml/android/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/android/histograms.xml @@ -3295,7 +3295,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Android.WebView.Startup.CreationTime.Stage1.FactoryInit" - units="ms" expires_after="2021-09-26"> + units="ms" expires_after="2021-11-28"> <owner>changwan@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3305,7 +3305,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Android.WebView.Startup.CreationTime.Stage2.ProviderInit.Cold" - units="ms" expires_after="2021-09-26"> + units="ms" expires_after="2021-11-28"> <owner>changwan@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3317,7 +3317,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Android.WebView.Startup.CreationTime.Stage2.ProviderInit.Warm" - units="ms" expires_after="2021-09-26"> + units="ms" expires_after="2021-11-28"> <owner>changwan@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/gpu/histograms.xml b/tools/metrics/histograms/histograms_xml/gpu/histograms.xml index 07d4b69b770bfc..16c5ccb3044aec 100644 --- a/tools/metrics/histograms/histograms_xml/gpu/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/gpu/histograms.xml @@ -500,7 +500,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="GPU.DirectComposition.IsUnderlay" enum="BooleanUnderlay" - expires_after="2021-09-26"> + expires_after="2021-11-28"> <owner>magchen@chromium.org</owner> <owner>zmo@chromium.org</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/net/histograms.xml b/tools/metrics/histograms/histograms_xml/net/histograms.xml index 5a55518f4e802f..f6a5ff637c6cdb 100644 --- a/tools/metrics/histograms/histograms_xml/net/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/net/histograms.xml @@ -1248,7 +1248,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Net.DNS.ProbeSequence.ConfigChange.Failure.AttemptTime" - units="ms" expires_after="2021-09-26"> + units="ms" expires_after="2021-11-28"> <owner>ericorth@chromium.org</owner> <owner>doh-core@google.com</owner> <summary> diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml index be157cdfbb7e63..ce9656c5bce739 100644 --- a/tools/metrics/histograms/histograms_xml/others/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml @@ -781,7 +781,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="appcache.UpdateJob.ExistingResourceCorruptionRecovery" - units="units" expires_after="2021-09-26"> + units="units" expires_after="2021-11-28"> <owner>cmp@chromium.org</owner> <owner>pwnall@chromium.org</owner> <summary> @@ -8346,7 +8346,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="Kiosk.Launch.CryptohomeFailure" enum="LoginFailureReason" - expires_after="2021-09-26"> + expires_after="2021-11-28"> <owner>xiyuan@chromium.org</owner> <owner>apotapchuk@chromium.org</owner> <summary>Tracks cryptohome failure during kiosk launch.</summary> @@ -18690,7 +18690,7 @@ regressions. --> </histogram> <histogram name="WebFont.CacheHit" enum="WebFontCacheHit" - expires_after="2021-09-26"> + expires_after="2021-11-28"> <owner>hajimehoshi@chromium.org</owner> <owner>kenjibaheux@chromium.org</owner> <owner>kouhei@chromium.org</owner> diff --git a/tools/metrics/histograms/histograms_xml/page/histograms.xml b/tools/metrics/histograms/histograms_xml/page/histograms.xml index ad3b3a1dc9019f..8eeb7213adad67 100644 --- a/tools/metrics/histograms/histograms_xml/page/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/page/histograms.xml @@ -611,7 +611,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="PageLoad.Clients.Scheme.HTTP.PaintTiming.UnderStat" - enum="PageLoadTimingUnderStat" expires_after="2021-09-26"> + enum="PageLoadTimingUnderStat" expires_after="2021-11-28"> <owner>tbansal@chromium.org</owner> <summary> Records if the time from navigation to first contentful paint was less than @@ -639,7 +639,7 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </histogram> <histogram name="PageLoad.Clients.Scheme.HTTPS.PaintTiming.UnderStat" - enum="PageLoadTimingUnderStat" expires_after="2021-09-26"> + enum="PageLoadTimingUnderStat" expires_after="2021-11-28"> <owner>tbansal@chromium.org</owner> <summary> Records if the time from navigation to first contentful paint was less than From a658046d90a56bbc9711fb9e0b44234dbf9ae3f3 Mon Sep 17 00:00:00 2001 From: Pi-Hsun Shih <pihsun@chromium.org> Date: Tue, 1 Jun 2021 08:59:00 +0000 Subject: [PATCH 14/81] CCA: Fix closure compiler warning for JSC_DYNAMIC_IMPORT_ALIASING_REQUIRED Closure compiler emits warning JSC_DYNAMIC_IMPORT_ALIASING_REQUIRED [1] when using dynamic import with output target version lower than ECMASCRIPT_2020, and without --dynamic_import_alias. Since we're only using closure compiler for type checking, set the output target to ECMASCRIPT_2020 to solve this issue. [1]: https://github.com/google/closure-compiler/wiki/JS-Modules#dynamic-import-expressions Bug: b/188365424 Test: Compile without warnings Change-Id: I3d08a06e94b37d31beb89c540998b1363d48809d Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928673 Reviewed-by: Shik Chen <shik@chromium.org> Commit-Queue: Pi-Hsun Shih <pihsun@chromium.org> Cr-Commit-Position: refs/heads/master@{#887891} --- chromeos/components/camera_app_ui/resources/js/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/chromeos/components/camera_app_ui/resources/js/BUILD.gn b/chromeos/components/camera_app_ui/resources/js/BUILD.gn index 9fa4f66cb6f46e..5a635f44c58444 100644 --- a/chromeos/components/camera_app_ui/resources/js/BUILD.gn +++ b/chromeos/components/camera_app_ui/resources/js/BUILD.gn @@ -10,6 +10,7 @@ js_type_check("closure_compile") { closure_flags = default_closure_args + [ "language_in=ECMASCRIPT_2020", + "language_out=ECMASCRIPT_2020", "jscomp_error=strictCheckTypes", "conformance_configs=" + rebase_path("externs/conformance_config.textproto", root_build_dir), From 8e82766fd5a117f78ba27fa1c0ccbd48976a7a94 Mon Sep 17 00:00:00 2001 From: Alice Wang <aliceywang@chromium.org> Date: Tue, 1 Jun 2021 09:06:14 +0000 Subject: [PATCH 15/81] [Android] Remove redundant method AccountManagerFacade#isCachePopulated() This CL removes the redundant method isCachePopulated() from AccountManagerFacade API as this method is no longer needed. Bug: 1211294 Change-Id: I960232a81d2db4d4cf50ab12948b15a3977e7625 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2927307 Reviewed-by: Tanmoy Mollik <triploblastic@chromium.org> Commit-Queue: Alice Wang <aliceywang@chromium.org> Cr-Commit-Position: refs/heads/master@{#887892} --- .../chrome/browser/signin/ui/SigninPromoUtil.java | 8 +++----- .../components/signin/AccountManagerFacade.java | 8 -------- .../components/signin/AccountManagerFacadeImpl.java | 10 ---------- .../components/signin/AccountManagerFacadeTest.java | 4 ++-- .../signin/test/util/FakeAccountManagerFacade.java | 5 ----- 5 files changed, 5 insertions(+), 30 deletions(-) diff --git a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninPromoUtil.java b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninPromoUtil.java index 9fe9485d332111..0665dec871aaa8 100644 --- a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninPromoUtil.java +++ b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/SigninPromoUtil.java @@ -24,6 +24,7 @@ import org.chromium.components.signin.metrics.SigninAccessPoint; import org.chromium.components.user_prefs.UserPrefs; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -110,11 +111,8 @@ public static void setupSigninPromoViewFromCache(SigninPromoController signinPro SigninPromoController.OnDismissListener listener) { final AccountManagerFacade accountManagerFacade = AccountManagerFacadeProvider.getInstance(); - if (!accountManagerFacade.isCachePopulated()) { - signinPromoController.setupPromoView(view, /* profileData= */ null, listener); - return; - } - final List<Account> accounts = accountManagerFacade.tryGetGoogleAccounts(); + final List<Account> accounts = + accountManagerFacade.getGoogleAccounts().or(Collections.emptyList()); if (accounts.isEmpty()) { signinPromoController.setupPromoView(view, /* profileData= */ null, listener); return; diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacade.java b/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacade.java index 3dd5682ea151cb..8f69ac804f1064 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacade.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacade.java @@ -48,14 +48,6 @@ interface ChildAccountStatusListener { @MainThread void removeObserver(AccountsChangeObserver observer); - /** - * Returns whether the account cache has already been populated. {@link #tryGetGoogleAccounts()} - * and similar methods will return instantly if the cache has been populated, otherwise these - * methods may block waiting for the cache to be populated. - */ - @AnyThread - boolean isCachePopulated(); - /** * Retrieves all Google accounts on the device from the cache. * Returns an empty array if an error occurs while getting account list. diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacadeImpl.java b/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacadeImpl.java index 74e331e2756243..d38565ad446963 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacadeImpl.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacadeImpl.java @@ -112,16 +112,6 @@ public void removeObserver(AccountsChangeObserver observer) { assert success : "Can't find observer"; } - /** - * Returns whether the account cache has already been populated. {@link #tryGetGoogleAccounts()} - * and similar methods will return instantly if the cache has been populated, otherwise these - * methods may block waiting for the cache to be populated. - */ - @Override - public boolean isCachePopulated() { - return mFilteredAccounts.get() != null; - } - @Override public Optional<List<Account>> getGoogleAccounts() { return Optional.fromNullable(mFilteredAccounts.get()); diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacadeTest.java b/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacadeTest.java index 879d1df5d9b5aa..8722f6b0cd4391 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacadeTest.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacadeTest.java @@ -76,7 +76,7 @@ public void tearDown() { @SmallTest public void testIsCachePopulated() throws InterruptedException { // Cache shouldn't be populated until getAccountsSync is unblocked. - assertFalse(AccountManagerFacadeProvider.getInstance().isCachePopulated()); + assertFalse(AccountManagerFacadeProvider.getInstance().getGoogleAccounts().isPresent()); mDelegate.unblockGetAccounts(); CountDownLatch countDownLatch = new CountDownLatch(1); @@ -86,7 +86,7 @@ public void testIsCachePopulated() throws InterruptedException { }); // Wait for cache population to finish. countDownLatch.await(); - assertTrue(AccountManagerFacadeProvider.getInstance().isCachePopulated()); + assertTrue(AccountManagerFacadeProvider.getInstance().getGoogleAccounts().isPresent()); } @Test diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java b/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java index 2d65cfcff93f30..2ea832f89160a3 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java @@ -70,11 +70,6 @@ public void removeObserver(AccountsChangeObserver observer) { mObservers.remove(observer); } - @Override - public boolean isCachePopulated() { - return true; - } - @Override public Optional<List<Account>> getGoogleAccounts() { List<Account> accounts = new ArrayList<>(); From 151eb05d2a32d66c9f1ec8d6959015ca7699edef Mon Sep 17 00:00:00 2001 From: Jeroen Dhollander <jeroendh@google.com> Date: Tue, 1 Jun 2021 09:06:27 +0000 Subject: [PATCH 16/81] Refactor duplicated building of Web Crypto Algorithm. The logic for building the Web Crypto Algorithm dictionary (which means first checking if the algorithm is RSA or EC, and then calling the correct helper method) was duplicated in 3 places. This fixes the duplication in 2 places. The 3rd place (inside PlatformKeysInternalSelectClientCertificatesFunction::Run) will be fixed in b/189428757. Bug: b/189429737 Test: browser_unittests --gtest_filter="*UnmanagedPlatformKey*" Change-Id: I786b2c5510ed1379e0a91e50c611b85cadbc908a Cq-Include-Trybots: luci.chrome.try:linux-chromeos-chrome Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2920580 Commit-Queue: Jeroen Dhollander <jeroendh@chromium.org> Reviewed-by: Omar Morsi <omorsi@google.com> Cr-Commit-Position: refs/heads/master@{#887893} --- .../chromeos/platform_keys/platform_keys.cc | 71 +++++++++++-------- .../chromeos/platform_keys/platform_keys.h | 13 ++++ .../platform_keys/platform_keys_api_ash.cc | 21 +++--- 3 files changed, 62 insertions(+), 43 deletions(-) diff --git a/chrome/browser/chromeos/platform_keys/platform_keys.cc b/chrome/browser/chromeos/platform_keys/platform_keys.cc index 10d9b0319f735a..709e6609f49122 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys.cc @@ -257,46 +257,57 @@ GetPublicKeyAndAlgorithmOutput GetPublicKeyAndAlgorithm( return output; } - // Currently, the only supported combinations are: - // 1- A certificate declaring rsaEncryption in the SubjectPublicKeyInfo used - // with the RSASSA-PKCS1-v1.5 algorithm. - // 2- A certificate declaring id-ecPublicKey in the SubjectPublicKeyInfo used - // with the ECDSA algorithm. - if (algorithm_name == kWebCryptoRsassaPkcs1v15) { - if (key_info.key_type != net::X509Certificate::kPublicKeyTypeRSA) { - output.status = Status::kErrorAlgorithmNotPermittedByCertificate; - return output; - } - - BuildWebCryptoRSAAlgorithmDictionary(key_info, &output.algorithm); - output.public_key = - std::vector<uint8_t>(key_info.public_key_spki_der.begin(), - key_info.public_key_spki_der.end()); - output.status = Status::kSuccess; + if (GetKeyTypeForAlgorithm(algorithm_name) != key_info.key_type) { + output.status = Status::kErrorAlgorithmNotPermittedByCertificate; return output; } - if (algorithm_name == kWebCryptoEcdsa) { - if (key_info.key_type != net::X509Certificate::kPublicKeyTypeECDSA) { - output.status = Status::kErrorAlgorithmNotPermittedByCertificate; - return output; - } - - BuildWebCryptoEcdsaAlgorithmDictionary(key_info, &output.algorithm); - output.public_key = - std::vector<uint8_t>(key_info.public_key_spki_der.begin(), - key_info.public_key_spki_der.end()); - output.status = Status::kSuccess; - return output; - } + absl::optional<base::DictionaryValue> algorithm = + BuildWebCrypAlgorithmDictionary(key_info); + DCHECK(algorithm.has_value()); + output.algorithm = std::move(algorithm.value()); - output.status = Status::kErrorAlgorithmNotPermittedByCertificate; + output.public_key = std::vector<uint8_t>(key_info.public_key_spki_der.begin(), + key_info.public_key_spki_der.end()); + output.status = Status::kSuccess; return output; } PublicKeyInfo::PublicKeyInfo() = default; PublicKeyInfo::~PublicKeyInfo() = default; +net::X509Certificate::PublicKeyType GetKeyTypeForAlgorithm( + const std::string& algorithm_name) { + // Currently, the only supported combinations are: + // 1- A certificate declaring rsaEncryption in the SubjectPublicKeyInfo used + // with the RSASSA-PKCS1-v1.5 algorithm. + // 2- A certificate declaring id-ecPublicKey in the SubjectPublicKeyInfo used + // with the ECDSA algorithm. + if (algorithm_name == kWebCryptoRsassaPkcs1v15) + return net::X509Certificate::kPublicKeyTypeRSA; + if (algorithm_name == kWebCryptoEcdsa) + return net::X509Certificate::kPublicKeyTypeECDSA; + return net::X509Certificate::kPublicKeyTypeUnknown; +} + +absl::optional<base::DictionaryValue> BuildWebCrypAlgorithmDictionary( + const PublicKeyInfo& key_info) { + switch (key_info.key_type) { + case net::X509Certificate::kPublicKeyTypeRSA: { + base::DictionaryValue result; + BuildWebCryptoRSAAlgorithmDictionary(key_info, &result); + return result; + } + case net::X509Certificate::kPublicKeyTypeECDSA: { + base::DictionaryValue result; + BuildWebCryptoEcdsaAlgorithmDictionary(key_info, &result); + return result; + } + default: + return absl::nullopt; + } +} + void BuildWebCryptoRSAAlgorithmDictionary(const PublicKeyInfo& key_info, base::DictionaryValue* algorithm) { CHECK_EQ(net::X509Certificate::kPublicKeyTypeRSA, key_info.key_type); diff --git a/chrome/browser/chromeos/platform_keys/platform_keys.h b/chrome/browser/chromeos/platform_keys/platform_keys.h index 23dc64de760e8c..1ddc3412684e40 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys.h +++ b/chrome/browser/chromeos/platform_keys/platform_keys.h @@ -15,6 +15,7 @@ #include "base/values.h" #include "chromeos/crosapi/mojom/keystore_error.mojom.h" #include "net/cert/x509_certificate.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace chromeos { namespace platform_keys { @@ -126,6 +127,18 @@ struct PublicKeyInfo { size_t key_size_bits = 0; }; +// Returns the certificate key type that supports the given algorithm, +// or |kPublicKeyTypeUnknown| if the algorithm is unknown or unsupported. +net::X509Certificate::PublicKeyType GetKeyTypeForAlgorithm( + const std::string& algorithm_name); + +// Builds a partial WebCrypto Algorithm object from the parameters available in +// |key_info|. This supports both RSA and EC keys. +// Returns absl::nullopt if the key is of an unsupported type (so not RSA or +// EC). +absl::optional<base::DictionaryValue> BuildWebCrypAlgorithmDictionary( + const PublicKeyInfo& key_info); + // Builds a partial WebCrypto Algorithm object from the parameters available in // |key_info|, which must be the info of an RSA key. This doesn't include // sign/hash parameters and thus isn't complete. platform_keys::GetPublicKey() diff --git a/chrome/browser/extensions/api/platform_keys/platform_keys_api_ash.cc b/chrome/browser/extensions/api/platform_keys/platform_keys_api_ash.cc index 1735e1355dac23..00870460539d92 100644 --- a/chrome/browser/extensions/api/platform_keys/platform_keys_api_ash.cc +++ b/chrome/browser/extensions/api/platform_keys/platform_keys_api_ash.cc @@ -264,20 +264,15 @@ void PlatformKeysInternalSelectClientCertificatesFunction:: result_match.certificate.assign(der_encoded_cert.begin(), der_encoded_cert.end()); - switch (key_info.key_type) { - case net::X509Certificate::kPublicKeyTypeRSA: - chromeos::platform_keys::BuildWebCryptoRSAAlgorithmDictionary( - key_info, &result_match.key_algorithm.additional_properties); - break; - case net::X509Certificate::kPublicKeyTypeECDSA: - chromeos::platform_keys::BuildWebCryptoEcdsaAlgorithmDictionary( - key_info, &result_match.key_algorithm.additional_properties); - break; - default: - LOG(ERROR) << "Skipping unsupported certificate with key type " - << key_info.key_type; - continue; + absl::optional<base::DictionaryValue> algorithm = + BuildWebCrypAlgorithmDictionary(key_info); + if (!algorithm) { + LOG(ERROR) << "Skipping unsupported certificate with key type " + << key_info.key_type; + continue; } + result_match.key_algorithm.additional_properties = + std::move(algorithm.value()); result_matches.push_back(std::move(result_match)); } From cacf6a2b01672c9302de4c801dd8cf48cf783396 Mon Sep 17 00:00:00 2001 From: Sylvain Defresne <sdefresne@chromium.org> Date: Tue, 1 Jun 2021 09:16:30 +0000 Subject: [PATCH 17/81] [ios] Properly cleanup Bookmarks UI during shutdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure that Bookmarks UI properly unregister its observers and cleanup after itself when the app shutdown (or when the UI is closed). Bug: 1213378 Fixed: 1213378 Change-Id: I856fb76ebd309509d3c6d0f5d2542ea0bab20691 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928525 Reviewed-by: Éric Noyau <noyau@chromium.org> Commit-Queue: Sylvain Defresne <sdefresne@chromium.org> Cr-Commit-Position: refs/heads/master@{#887894} --- .../bookmarks/bookmark_edit_view_controller.h | 3 ++ .../bookmark_edit_view_controller.mm | 4 ++ .../ui/bookmarks/bookmark_home_mediator.mm | 3 ++ .../bookmarks/bookmark_home_view_controller.h | 3 ++ .../bookmark_home_view_controller.mm | 17 +++++++-- .../bookmark_interaction_controller.h | 3 ++ .../bookmark_interaction_controller.mm | 37 +++++++++++++------ .../bookmark_model_bridge_observer.mm | 11 +++--- .../ui/bookmarks/bookmark_promo_controller.h | 3 ++ .../ui/bookmarks/bookmark_promo_controller.mm | 7 ++++ .../browser_view/browser_view_controller.mm | 3 ++ 11 files changed, 74 insertions(+), 20 deletions(-) diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h index cd99f65a4852cb..cd028269b79a67 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h +++ b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h @@ -55,6 +55,9 @@ class BookmarkNode; browser:(Browser*)browser NS_DESIGNATED_INITIALIZER; - (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE; +// Called before the instance is deallocated. +- (void)shutdown; + // Closes the edit view as if close button was pressed. - (void)dismiss; diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm index 4e7e54268931e8..89cb7efbac68e3 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm @@ -219,6 +219,10 @@ - (instancetype)initWithBookmark:(const BookmarkNode*)bookmark } - (void)dealloc { + [self shutdown]; +} + +- (void)shutdown { _folderViewController.delegate = nil; } diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_mediator.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_mediator.mm index 0934fac121ed87..e5d3d4a58dd694 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_mediator.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_mediator.mm @@ -120,6 +120,9 @@ - (void)startMediating { } - (void)disconnect { + [_bookmarkPromoController shutdown]; + _bookmarkPromoController = nil; + _modelBridge = nullptr; _syncedBookmarksObserver = nullptr; self.browserState = nullptr; diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.h b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.h index 965332dd804f34..16fe955296a175 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.h +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.h @@ -49,6 +49,9 @@ class GURL; - (instancetype)initWithBrowser:(Browser*)browser NS_DESIGNATED_INITIALIZER; - (instancetype)initWithStyle:(UITableViewStyle)tableViewStyle NS_UNAVAILABLE; +// Called before the instance is deallocated. +- (void)shutdown; + // Setter to set _rootNode value. - (void)setRootNode:(const bookmarks::BookmarkNode*)rootNode; diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm index f40592fb89cca7..c50c21f25eacad 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm @@ -87,6 +87,10 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + using bookmarks::BookmarkNode; using l10n_util::GetNSString; @@ -238,10 +242,6 @@ @interface BookmarkHomeViewController () <BookmarkFolderViewControllerDelegate, @implementation BookmarkHomeViewController -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - #pragma mark - Initializer - (instancetype)initWithBrowser:(Browser*)browser { @@ -272,9 +272,18 @@ - (instancetype)initWithBrowser:(Browser*)browser { } - (void)dealloc { + [self shutdown]; +} + +- (void)shutdown { + [_bookmarkInteractionController shutdown]; + _bookmarkInteractionController = nil; + [self.mediator disconnect]; _sharedState.tableView.dataSource = nil; _sharedState.tableView.delegate = nil; + + _bridge.reset(); } - (void)setRootNode:(const bookmarks::BookmarkNode*)rootNode { diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.h b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.h index 658fde63651d8c..3e791df9f40d85 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.h +++ b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.h @@ -33,6 +33,9 @@ class WebState; NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; +// Called before the instance is deallocated. +- (void)shutdown; + // Adds a bookmark for |URL| with the given |title|. - (void)bookmarkURL:(const GURL&)URL title:(NSString*)title; diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm index 3ac75dc4444cd1..1f211891f86500 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.mm @@ -183,8 +183,19 @@ - (instancetype)initWithBrowser:(Browser*)browser } - (void)dealloc { + [self shutdown]; +} + +- (void)shutdown { + [self bookmarkBrowserDismissed]; + _bookmarkBrowser.homeDelegate = nil; + [_bookmarkBrowser shutdown]; + _bookmarkBrowser = nil; + _bookmarkEditor.delegate = nil; + [_bookmarkEditor shutdown]; + _bookmarkEditor = nil; } - (void)bookmarkURL:(const GURL&)URL title:(NSString*)title { @@ -305,17 +316,7 @@ - (void)dismissBookmarkBrowserAnimated:(BOOL)animated } ProceduralBlock completion = ^{ - // TODO(crbug.com/940856): Make sure navigaton - // controller doesn't keep any controllers. Without - // this there's a memory leak of (almost) every BHVC - // the user visits. - [self.bookmarkNavigationController setViewControllers:@[] animated:NO]; - - self.bookmarkBrowser.homeDelegate = nil; - self.bookmarkBrowser = nil; - self.bookmarkTransitioningDelegate = nil; - self.bookmarkNavigationController = nil; - self.bookmarkNavigationControllerDelegate = nil; + [self bookmarkBrowserDismissed]; if (!openUrlsAfterDismissal) { return; @@ -334,6 +335,20 @@ - (void)dismissBookmarkBrowserAnimated:(BOOL)animated self.currentPresentedState = PresentedState::NONE; } +- (void)bookmarkBrowserDismissed { + // TODO(crbug.com/940856): Make sure navigaton + // controller doesn't keep any controllers. Without + // this there's a memory leak of (almost) every BHVC + // the user visits. + [self.bookmarkNavigationController setViewControllers:@[] animated:NO]; + + self.bookmarkBrowser.homeDelegate = nil; + self.bookmarkBrowser = nil; + self.bookmarkTransitioningDelegate = nil; + self.bookmarkNavigationController = nil; + self.bookmarkNavigationControllerDelegate = nil; +} + - (void)dismissBookmarkEditorAnimated:(BOOL)animated { if (self.currentPresentedState != PresentedState::BOOKMARK_EDITOR) return; diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.mm b/ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.mm index bebb5ab26291e5..0d0ec7b1b923f9 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.mm @@ -26,8 +26,9 @@ } BookmarkModelBridge::~BookmarkModelBridge() { - DCHECK(model_); - model_->RemoveObserver(this); + if (model_) { + model_->RemoveObserver(this); + } } void BookmarkModelBridge::BookmarkModelLoaded(BookmarkModel* model, @@ -36,9 +37,9 @@ } void BookmarkModelBridge::BookmarkModelBeingDeleted(BookmarkModel* model) { - // This is an inconsistent state in the application lifecycle. The bookmark - // model shouldn't disappear. - NOTREACHED(); + DCHECK(model_); + model_->RemoveObserver(this); + model_ = nullptr; } void BookmarkModelBridge::BookmarkNodeMoved(BookmarkModel* model, diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.h b/ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.h index 2a3ec20ccd3f2b..1746295912d76b 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.h +++ b/ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.h @@ -42,6 +42,9 @@ class ChromeBrowserState; (id<BookmarkPromoControllerDelegate>)delegate presenter:(id<SigninPresenter>)presenter; +// Called before the instance is deallocated. +- (void)shutdown; + // Hides the promo cell. It won't be presented again on this profile. - (void)hidePromoCell; diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.mm index b0bbfe56e0eda2..997fed0621dabc 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.mm @@ -67,7 +67,14 @@ - (instancetype)initWithBrowserState:(ChromeBrowserState*)browserState } - (void)dealloc { + [self shutdown]; +} + +- (void)shutdown { [_signinPromoViewMediator signinPromoViewIsRemoved]; + _signinPromoViewMediator = nil; + + _identityManagerObserverBridge.reset(); } - (void)hidePromoCell { 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 a9eba810cbc5eb..d3c959ff4ffa44 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm @@ -1375,6 +1375,9 @@ - (void)shutdown { } _fullscreenDisabler = nullptr; [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [_bookmarkInteractionController shutdown]; + _bookmarkInteractionController = nil; } #pragma mark - NSObject From 3d957e017757eb481a91d40e90800927f6a1cb8e Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 09:24:03 +0000 Subject: [PATCH 18/81] Roll ANGLE from fe93fcdd1b48 to a44b16d39075 (1 revision) https://chromium.googlesource.com/angle/angle.git/+log/fe93fcdd1b48..a44b16d39075 2021-06-01 cnorthrop@google.com Capture/Replay: Force validation on when capturing If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/angle-chromium-autoroll Please CC ynovikov@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win-asan;luci.chromium.try:win_optional_gpu_tests_rel;luci.chromium.try:linux-swangle-try-x64;luci.chromium.try:win-swangle-try-x86 Bug: None Tbr: ynovikov@google.com Test: Test: Genshin Impact MEC Change-Id: I1775300c4a734424db5d1cea2b0a9a52765c4c8c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929897 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887895} --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 3b7998fe936df0..abefdaa75adbfc 100644 --- a/DEPS +++ b/DEPS @@ -221,7 +221,7 @@ vars = { # 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': 'fe93fcdd1b484ee460e6fcdd0e8dbb6624bbc751', + 'angle_revision': 'a44b16d39075af2ba64ac48457bd6f8f3b3aafeb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. From 813e73b87bcf4d63103f2b17a7afef4a8a9af7f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Beaufort?= <beaufort.francois@gmail.com> Date: Tue, 1 Jun 2021 09:28:13 +0000 Subject: [PATCH 19/81] Fix closed captions and subtitles icon sizes in video player MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This CL fix the sizes of video player icons for closed captions and subtitles. Screenshot: https://crbug.com/1213905#c1 Change-Id: I2d4765b18963c3dc08fd04cbf7042f4e0a214122 Bug: 1213905 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2919723 Reviewed-by: Tommy Steimel <steimel@chromium.org> Commit-Queue: François Beaufort <beaufort.francois@gmail.com> Cr-Commit-Position: refs/heads/master@{#887896} --- .../media_controls/resources/mediaControls.css | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css b/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css index e0782ff67943c7..f33684dd27e48d 100644 --- a/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css +++ b/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css @@ -1330,24 +1330,22 @@ video::-internal-media-controls-scrubbing-message { video::-internal-media-controls-text-track-list-kind-captions { -webkit-appearance: none; background-image: -internal-light-dark(-webkit-image-set(url(ic_closed_caption.svg) 1x), -webkit-image-set(url(ic_closed_caption_white.svg) 1x)); - background-size: 32px; + background-size: 18px; background-repeat: no-repeat; background-position: center center; - height: 20px; - width: 20px; - margin-left: 10px; + height: 18px; + width: 18px; vertical-align: middle; } video::-internal-media-controls-text-track-list-kind-subtitles { -webkit-appearance: none; background-image: -internal-light-dark(-webkit-image-set(url(ic_subtitles.svg) 1x), -webkit-image-set(url(ic_subtitles_white.svg) 1x)); - background-size: 32px; + background-size: 18px; background-repeat: no-repeat; background-position: center center; - height: 20px; - width: 20px; - margin-left: 10px; + height: 18px; + width: 18px; vertical-align: middle; } From 5a2df26db36b76f0689a9bc6398bce8b5e0ce3aa Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 09:41:23 +0000 Subject: [PATCH 20/81] Roll Chrome Win32 PGO Profile Roll Chrome Win32 PGO profile from chrome-win32-master-1622489765-425bcb96f463f5ee8cc869a9b78416fde26adec1.profdata to chrome-win32-master-1622527178-9a5352b7412ad6ef11456de74f66a37dcaa3308d.profdata If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/pgo-win32-chromium Please CC pgo-profile-sheriffs@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chrome.try:win-chrome Tbr: pgo-profile-sheriffs@google.com Change-Id: Ia20d375915bb39cbb9949dddd1c61c09956f21d6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929978 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887897} --- chrome/build/win32.pgo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index ea74500e33b1a3..8e2146b4ae6ada 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt @@ -1 +1 @@ -chrome-win32-master-1622489765-425bcb96f463f5ee8cc869a9b78416fde26adec1.profdata +chrome-win32-master-1622527178-9a5352b7412ad6ef11456de74f66a37dcaa3308d.profdata From 735576edeb7d285a2b72f2cd59ba7c66ceb5a266 Mon Sep 17 00:00:00 2001 From: Anders Hartvoll Ruud <andruud@chromium.org> Date: Tue, 1 Jun 2021 09:45:32 +0000 Subject: [PATCH 21/81] Let container-type turn on containment If container-type:inline-size/block-size is used, we enable style containment, layout containment, and the appropriate size containment. The ComputedStyle::Contains* utils now have different semantics. Each of those those functions now represent whether or not containment of a given type should be enabled based on the information stored on ComputedStyle as a whole (not just the 'contain' property itself). Because of this, we no longer need to do an additional check for ComputedStyle::ContainsSize in LayoutObject::ShouldApplyInline- SizeContainment, as ComputedStyle::ContainsInlineSize is already supposed to include this per the new contract. (And similarly for block-size). Bug: 1213888 Change-Id: Ia6757fba243cec4471327b33cdb65debcf9cd1ee Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928858 Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org> Reviewed-by: Morten Stenshorne <mstensho@chromium.org> Cr-Commit-Position: refs/heads/master@{#887898} --- .../properties/longhands/longhands_custom.cc | 12 +- .../renderer/core/layout/layout_object.h | 6 +- .../renderer/core/style/computed_style.h | 45 +++++++- .../container-type-containment.html | 103 ++++++++++++++++++ 4 files changed, 151 insertions(+), 15 deletions(-) create mode 100644 third_party/blink/web_tests/wpt_internal/css/css-conditional/container-queries/container-type-containment.html diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc index a5a0a99f143127..9a8b361f618e3a 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc @@ -1885,19 +1885,19 @@ const CSSValue* Contain::CSSValueFromComputedStyleInternal( return CSSIdentifierValue::Create(CSSValueID::kContent); CSSValueList* list = CSSValueList::CreateSpaceSeparated(); - if (style.ContainsSize()) { + if ((style.Contain() & kContainsSize) == kContainsSize) { list->Append(*CSSIdentifierValue::Create(CSSValueID::kSize)); } else { - if (style.ContainsInlineSize()) + if (style.Contain() & kContainsInlineSize) list->Append(*CSSIdentifierValue::Create(CSSValueID::kInlineSize)); - else if (style.ContainsBlockSize()) + else if (style.Contain() & kContainsBlockSize) list->Append(*CSSIdentifierValue::Create(CSSValueID::kBlockSize)); } - if (style.ContainsLayout()) + if (style.Contain() & kContainsLayout) list->Append(*CSSIdentifierValue::Create(CSSValueID::kLayout)); - if (style.ContainsStyle()) + if (style.Contain() & kContainsStyle) list->Append(*CSSIdentifierValue::Create(CSSValueID::kStyle)); - if (style.ContainsPaint()) + if (style.Contain() & kContainsPaint) list->Append(*CSSIdentifierValue::Create(CSSValueID::kPaint)); DCHECK(list->length()); return list; diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index 4b7258fc44679c..5a194385c83457 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h @@ -618,13 +618,11 @@ class CORE_EXPORT LayoutObject : public ImageResourceObserver, } inline bool ShouldApplyInlineSizeContainment() const { NOT_DESTROYED(); - return (StyleRef().ContainsInlineSize() || StyleRef().ContainsSize()) && - IsEligibleForSizeContainment(); + return StyleRef().ContainsInlineSize() && IsEligibleForSizeContainment(); } inline bool ShouldApplyBlockSizeContainment() const { NOT_DESTROYED(); - return (StyleRef().ContainsBlockSize() || StyleRef().ContainsSize()) && - IsEligibleForSizeContainment(); + return StyleRef().ContainsBlockSize() && IsEligibleForSizeContainment(); } inline bool ShouldApplyStyleContainment() const { NOT_DESTROYED(); diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index e137aa817569da..d9e8564a6f47c1 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h @@ -2040,14 +2040,34 @@ class ComputedStyle : public ComputedStyleBase, } // Contain utility functions. + // + // Containment can be enabled from a variety of sources, not just the + // 'contain' property itself. The return values represent whether or not + // we should enable containment of a given type, taking those different + // sources into account. + // + // Note that even with a return value of |true|, containment may still not + // be applied if the layout object is ineligible for the given containment + // type. See |LayoutObject::IsEligibleForSizeContainment| and similar + // functions. + bool ContainsPaint() const { return Contain() & kContainsPaint; } - bool ContainsStyle() const { return Contain() & kContainsStyle; } - bool ContainsLayout() const { return Contain() & kContainsLayout; } + bool ContainsStyle() const { + return (Contain() & kContainsStyle) || IsInlineOrBlockSizeContainer(); + } + bool ContainsLayout() const { + return (Contain() & kContainsLayout) || IsInlineOrBlockSizeContainer(); + } bool ContainsSize() const { - return (Contain() & kContainsSize) == kContainsSize; + return ((Contain() & kContainsSize) == kContainsSize) || + IsInlineAndBlockSizeContainer(); + } + bool ContainsInlineSize() const { + return (Contain() & kContainsInlineSize) || IsInlineSizeContainer(); + } + bool ContainsBlockSize() const { + return (Contain() & kContainsBlockSize) || IsBlockSizeContainer(); } - bool ContainsInlineSize() const { return Contain() & kContainsInlineSize; } - bool ContainsBlockSize() const { return Contain() & kContainsBlockSize; } // Display utility functions. bool IsDisplayReplacedType() const { @@ -2647,6 +2667,21 @@ class ComputedStyle : public ComputedStyleBase, EFloat Floating() const { return FloatingInternal(); } EResize Resize() const { return ResizeInternal(); } + bool IsInlineSizeContainer() const { + return ContainerType() & kContainerTypeInlineSize; + } + bool IsBlockSizeContainer() const { + return ContainerType() & kContainerTypeBlockSize; + } + bool IsInlineOrBlockSizeContainer() const { + return ContainerType() & + (kContainerTypeInlineSize | kContainerTypeBlockSize); + } + bool IsInlineAndBlockSizeContainer() const { + const unsigned both = (kContainerTypeInlineSize | kContainerTypeBlockSize); + return (ContainerType() & both) == both; + } + void SetInternalVisitedColor(const StyleColor& v) { SetInternalVisitedColorInternal(v); } diff --git a/third_party/blink/web_tests/wpt_internal/css/css-conditional/container-queries/container-type-containment.html b/third_party/blink/web_tests/wpt_internal/css/css-conditional/container-queries/container-type-containment.html new file mode 100644 index 00000000000000..e77abb676a1990 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/css/css-conditional/container-queries/container-type-containment.html @@ -0,0 +1,103 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + /* Note: background colors have no impact on the test result. They are + present to make it easier to visually verify that the test + does the right thing. */ + .square { + width: 50px; + height: 50px; + background: tomato; + } + .half { + width: 25px; + height: 50px; + background: red; + } + div > div:nth-of-type(1) { background: skyblue; } + div > div:nth-of-type(2) { background: hotpink; } +</style> + +<div id=test1 class=square> + <div id=float1 class=half style="float:left"></div> + <div id=child1 class=half style="container-type:inline-size"></div> +</div> +<script> + test(() => { + assert_equals(child1.offsetLeft, test1.offsetLeft + float1.offsetWidth); + }, 'container-type:inline-size turns on layout containment'); +</script> + +<hr> + +<div id=test2 class=square> + <div id=float2 class=half style="float:left"></div> + <div id=child2 class=half style="container-type:block-size"></div> +</div> +<script> + test(() => { + assert_equals(child2.offsetLeft, test2.offsetLeft + float2.offsetWidth); + }, 'container-type:block-size turns on layout containment'); +</script> + +<hr> + +<div id=test3 class=square> + <div id=ref3 style="float:left">A</div> + <div id=child3 style="float:left; container-type:inline-size">A</div> +</div> +<script> + test(() => { + assert_equals(child3.offsetWidth, 0); + assert_equals(child3.offsetHeight, ref3.offsetHeight); + }, 'container-type:inline-size turns on inline-size containment'); +</script> + +<hr> + +<div id=test4 class=square> + <div id=ref4>A</div> + <div id=child4 style="container-type:block-size">A</div> +</div> +<script> + test(() => { + assert_equals(child4.offsetHeight, 0); + assert_equals(child4.offsetWidth, ref4.offsetWidth); + }, 'container-type:block-size turns on block-size containment'); +</script> + +<hr> + +<div id=test5 class=square> + <div id=child5 style="float:left; container-type:inline-size block-size">A</div> +</div> +<script> + test(() => { + assert_equals(child5.offsetHeight, 0); + assert_equals(child5.offsetWidth, 0); + }, 'container-type:inline-size block-size turns on full size containment'); +</script> + +<hr> + +<style> + #ref6::before, #child6::before { + content: counter(foo); + } +</style> +<div id=test6 class=square style="counter-set: foo 5"> + <div id=ref6 style="float:left"></div> + <section style="container-type:inline-size"> + <span style="counter-increment: foo 1000;"></span> + </section> + <section style="container-type:block-size"> + <span style="counter-increment: foo 1000;"></span> + </section> + <div id=child6 style="float:left"></div> +</div> +<script> + test(() => { + assert_equals(child6.offsetWidth, ref6.offsetWidth); + }, 'container-type:inline/block-size turns on style containment'); +</script> From 3b00f0407ce938919f09b6ccf00e9f647bca9c9b Mon Sep 17 00:00:00 2001 From: Wei Lee <wtlee@google.com> Date: Tue, 1 Jun 2021 09:47:08 +0000 Subject: [PATCH 22/81] CCA: Don't save video if the duration is less than 500ms There are some known issues which happen since the recording session is too short: 1. No data chunk is received 2. Data chunk is received but is lack of data from video track This CL handles these cases by not saving the video but showing a toast error message to users. Bug: b:184583382, b:172341285, b:172214187 Test: Manually Change-Id: I0d43a25ac12b729088b503eb7673e5e4ca26939a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928701 Reviewed-by: Inker Kuo <inker@chromium.org> Commit-Queue: Wei Lee <wtlee@chromium.org> Cr-Commit-Position: refs/heads/master@{#887899} --- chromeos/components/camera_app_ui/resources.h | 1 + .../js/models/file_system_access_entry.js | 55 +++++++- .../js/models/lazy_directory_entry.js | 10 ++ .../js/models/mp4_video_processor.js | 18 +++ .../js/models/video_processor_interface.js | 8 ++ .../resources/js/models/video_saver.js | 9 ++ .../camera_app_ui/resources/js/type.js | 14 ++ .../js/views/camera/mode/record_time.js | 38 +++++- .../resources/js/views/camera/mode/video.js | 125 +++++++++++------- .../resources/strings/camera_strings.grd | 3 + .../IDS_ERROR_MSG_VIDEO_TOO_SHORT.png.sha1 | 1 + 11 files changed, 224 insertions(+), 58 deletions(-) create mode 100644 chromeos/components/camera_app_ui/resources/strings/camera_strings_grd/IDS_ERROR_MSG_VIDEO_TOO_SHORT.png.sha1 diff --git a/chromeos/components/camera_app_ui/resources.h b/chromeos/components/camera_app_ui/resources.h index 609aa9e50ee1cc..2c85fffc4a668f 100644 --- a/chromeos/components/camera_app_ui/resources.h +++ b/chromeos/components/camera_app_ui/resources.h @@ -46,6 +46,7 @@ const struct { {"error_msg_take_photo_failed", IDS_ERROR_MSG_TAKE_PHOTO_FAILED}, {"error_msg_take_portrait_bokeh_photo_failed", IDS_ERROR_MSG_TAKE_PORTRAIT_BOKEH_PHOTO_FAILED}, + {"error_msg_video_too_short", IDS_ERROR_MSG_VIDEO_TOO_SHORT}, {"expert_custom_video_parameters", IDS_EXPERT_CUSTOM_VIDEO_PARAMETERS}, {"expert_mode_button", IDS_EXPERT_MODE_BUTTON}, {"expert_preview_metadata", IDS_EXPERT_PREVIEW_METADATA}, diff --git a/chromeos/components/camera_app_ui/resources/js/models/file_system_access_entry.js b/chromeos/components/camera_app_ui/resources/js/models/file_system_access_entry.js index 63921a328621e4..806482fbf8ea68 100644 --- a/chromeos/components/camera_app_ui/resources/js/models/file_system_access_entry.js +++ b/chromeos/components/camera_app_ui/resources/js/models/file_system_access_entry.js @@ -36,8 +36,9 @@ export class FileSystemAccessEntry { export class FileAccessEntry extends FileSystemAccessEntry { /** * @param {!FileSystemFileHandle} handle + * @param {?DirectoryAccessEntryImpl} parent */ - constructor(handle) { + constructor(handle, parent = null) { super(handle); /** @@ -45,6 +46,12 @@ export class FileAccessEntry extends FileSystemAccessEntry { * @private */ this.handle_ = handle; + + /** + * @type {?DirectoryAccessEntryImpl} + * @private + */ + this.parent_ = parent; } /** @@ -92,6 +99,19 @@ export class FileAccessEntry extends FileSystemAccessEntry { const file = await this.file(); return file.lastModified; } + + /** + * Deletes the file. + * @return {!Promise} + * @throws {!Error} Thrown when trying to delete file with no parent + * directory. + */ + async delete() { + if (this.parent_ === null) { + throw new Error('Failed to delete file due to no parent directory'); + } + return this.parent_.removeEntry(this.name); + } } /** @@ -158,6 +178,13 @@ export class DirectoryAccessEntry { * directory. */ async getDirectory({name, createIfNotExist}) {} + + /** + * Removes file by given |name| from the directory. + * @param {string} name The name of the file. + * @return {!Promise} + */ + async removeEntry(name) {} } /** @@ -167,8 +194,9 @@ export class DirectoryAccessEntry { export class DirectoryAccessEntryImpl extends FileSystemAccessEntry { /** * @param {!FileSystemDirectoryHandle} handle + * @param {?DirectoryAccessEntryImpl} parent */ - constructor(handle) { + constructor(handle, parent = null) { super(handle); /** @@ -176,6 +204,12 @@ export class DirectoryAccessEntryImpl extends FileSystemAccessEntry { * @private */ this.handle_ = handle; + + /** + * @type {?DirectoryAccessEntryImpl} + * @private + */ + this.parent_ = parent; } /** @@ -206,7 +240,7 @@ export class DirectoryAccessEntryImpl extends FileSystemAccessEntry { */ async getFile(name) { const handle = await this.handle_.getFileHandle(name, {create: false}); - return new FileAccessEntry(handle); + return new FileAccessEntry(handle, this); } /** @@ -242,7 +276,7 @@ export class DirectoryAccessEntryImpl extends FileSystemAccessEntry { } const handle = await this.handle_.getFileHandle(uniqueName, {create: true}); - return new FileAccessEntry(handle); + return new FileAccessEntry(handle, this); }); } @@ -255,7 +289,7 @@ export class DirectoryAccessEntryImpl extends FileSystemAccessEntry { name, {create: createIfNotExist}); assert(handle !== null); return new DirectoryAccessEntryImpl( - /** @type {!FileSystemDirectoryHandle} */ (handle)); + /** @type {!FileSystemDirectoryHandle} */ (handle), this); } catch (error) { if (!createIfNotExist && error.name === 'NotFoundError') { return null; @@ -264,6 +298,13 @@ export class DirectoryAccessEntryImpl extends FileSystemAccessEntry { } } + /** + * @override + */ + async removeEntry(name) { + return this.handle_.removeEntry(name); + } + /** * Gets the file handles in this directory if |isDirectory| is set to false. * If |isDirectory| is true, gets the directory entries instead. @@ -274,9 +315,9 @@ export class DirectoryAccessEntryImpl extends FileSystemAccessEntry { const results = []; for await (const handle of this.handle_.values()) { if (isDirectory && handle.kind === 'directory') { - results.push(new DirectoryAccessEntryImpl(handle)); + results.push(new DirectoryAccessEntryImpl(handle, this)); } else if (!isDirectory && handle.kind === 'file') { - results.push(new FileAccessEntry(handle)); + results.push(new FileAccessEntry(handle, this)); } } return results; diff --git a/chromeos/components/camera_app_ui/resources/js/models/lazy_directory_entry.js b/chromeos/components/camera_app_ui/resources/js/models/lazy_directory_entry.js index 81a58f9206da98..0c10a718b8bb7a 100644 --- a/chromeos/components/camera_app_ui/resources/js/models/lazy_directory_entry.js +++ b/chromeos/components/camera_app_ui/resources/js/models/lazy_directory_entry.js @@ -114,6 +114,16 @@ class LazyDirectoryEntry { return dir.getDirectory({name, createIfNotExist}); } + /** + * @override + */ + async removeEntry(name) { + if (this.directory_ === null) { + return null; + } + return this.directory_.removeEntry(name); + } + /** * Gets the directory which this entry points to. Create it if it does not * exist. diff --git a/chromeos/components/camera_app_ui/resources/js/models/mp4_video_processor.js b/chromeos/components/camera_app_ui/resources/js/models/mp4_video_processor.js index 0f6db045a3dee4..c0ef1e40ab2196 100644 --- a/chromeos/components/camera_app_ui/resources/js/models/mp4_video_processor.js +++ b/chromeos/components/camera_app_ui/resources/js/models/mp4_video_processor.js @@ -252,6 +252,7 @@ class Mp4VideoProcessor { this.inputDevice_ = new InputDevice(); this.outputDevice_ = new OutputDevice(output); this.jobQueue_ = new AsyncJobQueue(); + this.quitCallback_ = null; const args = [ // Make the procssing pipeline start earlier by shorten the initial @@ -312,6 +313,7 @@ class Mp4VideoProcessor { assert(stdin.fd === 0); assert(stdout.fd === 1); assert(stderr.fd === 2); + this.quitCallback_ = fs.quit; }, }; @@ -362,6 +364,22 @@ class Mp4VideoProcessor { await this.output_.close(); } + /** + * Cancels all the remaining tasks and quits the processor. + * @return {!Promise} Resolved when the processor quits. + */ + async cancel() { + await this.jobQueue_.clear(); + await this.output_.close(); + + // We quit the processor directly instead of calling close() to avoid mp4 + // video processor crashing and entering an unrecoverable state when trying + // to encode video file without receiving any data chunk. + if (this.quitCallback_ !== null) { + this.quitCallback_(); + } + } + /** * Expose the VideoProcessor constructor to given end point. * @param {!Port} endPoint diff --git a/chromeos/components/camera_app_ui/resources/js/models/video_processor_interface.js b/chromeos/components/camera_app_ui/resources/js/models/video_processor_interface.js index 3de4853d78fcc2..ccf3286ec3b63b 100644 --- a/chromeos/components/camera_app_ui/resources/js/models/video_processor_interface.js +++ b/chromeos/components/camera_app_ui/resources/js/models/video_processor_interface.js @@ -22,4 +22,12 @@ export class VideoProcessor { * @abstract */ async close() {} + + /** + * Cancels the remaining tasks and quits the processor. No more write + * operations are allowed. + * @return {!Promise} Resolved when the processor quits. + * @abstract + */ + async cancel() {} } diff --git a/chromeos/components/camera_app_ui/resources/js/models/video_saver.js b/chromeos/components/camera_app_ui/resources/js/models/video_saver.js index 8f18351c009e17..d9393c476282e1 100644 --- a/chromeos/components/camera_app_ui/resources/js/models/video_saver.js +++ b/chromeos/components/camera_app_ui/resources/js/models/video_saver.js @@ -77,6 +77,15 @@ export class VideoSaver { this.processor_.write(blob); } + /** + * Cancels and drops all the written video data. + * @return {!Promise} + */ + async cancel() { + await this.processor_.cancel(); + return this.file_.delete(); + } + /** * Finishes the write of video data parts and returns result video file. * @return {!Promise<!FileAccessEntry>} Result video file. diff --git a/chromeos/components/camera_app_ui/resources/js/type.js b/chromeos/components/camera_app_ui/resources/js/type.js index e79a2d2fa5ae79..c364a72f257c95 100644 --- a/chromeos/components/camera_app_ui/resources/js/type.js +++ b/chromeos/components/camera_app_ui/resources/js/type.js @@ -322,3 +322,17 @@ export class EmptyThumbnailError extends Error { this.name = this.constructor.name; } } + +/** + * Throws when the recording is ended with no chunk returned. + */ +export class NoChunkError extends Error { + /** + * @param {string=} message + * @public + */ + constructor(message = 'No chunk is received during recording session') { + super(message); + this.name = this.constructor.name; + } +} diff --git a/chromeos/components/camera_app_ui/resources/js/views/camera/mode/record_time.js b/chromeos/components/camera_app_ui/resources/js/views/camera/mode/record_time.js index e30c9b134746e5..f037e7f655331d 100644 --- a/chromeos/components/camera_app_ui/resources/js/views/camera/mode/record_time.js +++ b/chromeos/components/camera_app_ui/resources/js/views/camera/mode/record_time.js @@ -32,6 +32,20 @@ export class RecordTime { * @private */ this.ticks_ = 0; + + /** + * The timestamp when the recording starts. + * @type {number} + * @private + */ + this.startTimestamp_ = 0; + + /** + * The total duration of the recording in milliseconds. + * @type {number} + * @private + */ + this.totalDuration_ = 0; } /** @@ -61,6 +75,7 @@ export class RecordTime { start({resume}) { if (!resume) { this.ticks_ = 0; + this.totalDuration_ = 0; } this.update_(this.ticks_); this.recordTime_.hidden = false; @@ -69,12 +84,13 @@ export class RecordTime { this.ticks_++; this.update_(this.ticks_); }, 1000); + + this.startTimestamp_ = performance.now(); } /** * Stops counting and showing the elapsed recording time. * @param {{pause: boolean}} param If the time count is paused temporarily. - * @return {number} Recorded time in 1 minute buckets. */ stop({pause}) { speak('status_msg_recording_stopped'); @@ -82,12 +98,28 @@ export class RecordTime { clearInterval(this.tickTimeout_); this.tickTimeout_ = null; } - const mins = Math.ceil(this.ticks_ / 60); if (!pause) { this.ticks_ = 0; this.recordTime_.hidden = true; this.update_(0); } - return mins; + + this.totalDuration_ += performance.now() - this.startTimestamp_; + } + + /** + * Returns the recorded duration in minutes. + * @return {number} + */ + inMinutes() { + return Math.ceil(this.totalDuration_ / 1000 / 60); + } + + /** + * Returns the recorded duration in milliseconds. + * @return {number} + */ + inMilliseconds() { + return this.totalDuration_; } } diff --git a/chromeos/components/camera_app_ui/resources/js/views/camera/mode/video.js b/chromeos/components/camera_app_ui/resources/js/views/camera/mode/video.js index 5c3b5a71a20f50..9f0fc66129aed7 100644 --- a/chromeos/components/camera_app_ui/resources/js/views/camera/mode/video.js +++ b/chromeos/components/camera_app_ui/resources/js/views/camera/mode/video.js @@ -27,6 +27,7 @@ import * as toast from '../../../toast.js'; import { CanceledError, Facing, // eslint-disable-line no-unused-vars + NoChunkError, PerfEvent, Resolution, ResolutionList, // eslint-disable-line no-unused-vars @@ -54,6 +55,9 @@ const encoderPreference = new Map([ */ let avc1Parameters = null; +// The minimum duration of videos captured via cca. +const MINIMUM_VIDEO_DURATION_IN_MILLISECONDS = 500; + /** * Sets avc1 parameter used in video recording. * @param {?h264.EncoderParameters} params @@ -361,23 +365,44 @@ export class Video extends ModeBase { this.recordTime_.start({resume: false}); let /** ?VideoSaver */ videoSaver = null; - let /** number */ duration = 0; + const isVideoTooShort = () => this.recordTime_.inMilliseconds() < + MINIMUM_VIDEO_DURATION_IN_MILLISECONDS; + try { - videoSaver = await this.captureVideo_(); + try { + videoSaver = await this.captureVideo_(); + } finally { + this.recordTime_.stop({pause: false}); + sound.play(dom.get('#sound-rec-end', HTMLAudioElement)); + await this.snapshots_.flush(); + } } catch (e) { - toast.show('error_msg_empty_recording'); - throw e; - } finally { - duration = this.recordTime_.stop({pause: false}); + // Tolerates the error if it is due to the very short duration. Reports + // for other errors. + if (!(e instanceof NoChunkError && isVideoTooShort())) { + toast.show('error_msg_empty_recording'); + throw e; + } + } + + if (isVideoTooShort()) { + toast.show('error_msg_video_too_short'); + if (videoSaver !== null) { + await videoSaver.cancel(); + } + return; } - sound.play(dom.get('#sound-rec-end', HTMLAudioElement)); const settings = this.stream_.getVideoTracks()[0].getSettings(); const resolution = new Resolution(settings.width, settings.height); state.set(PerfEvent.VIDEO_CAPTURE_POST_PROCESSING, true); try { - await this.handler_.handleResultVideo(new VideoResult( - {resolution, duration, videoSaver, everPaused: this.everPaused_})); + await this.handler_.handleResultVideo(new VideoResult({ + resolution, + duration: this.recordTime_.inMinutes(), + videoSaver, + everPaused: this.everPaused_, + })); state.set( PerfEvent.VIDEO_CAPTURE_POST_PROCESSING, false, {resolution, facing: this.facing_}); @@ -386,8 +411,6 @@ export class Video extends ModeBase { PerfEvent.VIDEO_CAPTURE_POST_PROCESSING, false, {hasError: true}); throw e; } - - await this.snapshots_.flush(); } /** @@ -413,45 +436,51 @@ export class Video extends ModeBase { async captureVideo_() { const saver = await this.handler_.createVideoSaver(); - return new Promise((resolve, reject) => { - let noChunk = true; - - const ondataavailable = (event) => { - if (event.data && event.data.size > 0) { - noChunk = false; - saver.write(event.data); - } - }; - const onstop = (event) => { - state.set(state.State.RECORDING, false); + try { + await new Promise((resolve, reject) => { + let noChunk = true; + + const ondataavailable = (event) => { + if (event.data && event.data.size > 0) { + noChunk = false; + saver.write(event.data); + } + }; + const onstop = async (event) => { + state.set(state.State.RECORDING, false); + state.set(state.State.RECORDING_PAUSED, false); + state.set(state.State.RECORDING_UI_PAUSED, false); + + this.mediaRecorder_.removeEventListener( + 'dataavailable', ondataavailable); + this.mediaRecorder_.removeEventListener('stop', onstop); + + if (noChunk) { + reject(new NoChunkError()); + } else { + // TODO(yuli): Handle insufficient storage. + resolve(saver); + } + }; + const onstart = () => { + state.set(state.State.RECORDING, true); + this.mediaRecorder_.removeEventListener('start', onstart); + }; + this.mediaRecorder_.addEventListener('dataavailable', ondataavailable); + this.mediaRecorder_.addEventListener('stop', onstop); + this.mediaRecorder_.addEventListener('start', onstart); + + window.addEventListener('beforeunload', beforeUnloadListener); + + this.mediaRecorder_.start(100); state.set(state.State.RECORDING_PAUSED, false); state.set(state.State.RECORDING_UI_PAUSED, false); - - this.mediaRecorder_.removeEventListener( - 'dataavailable', ondataavailable); - this.mediaRecorder_.removeEventListener('stop', onstop); - - if (noChunk) { - reject(new Error('Video blob error.')); - } else { - // TODO(yuli): Handle insufficient storage. - resolve(saver); - } - }; - const onstart = () => { - state.set(state.State.RECORDING, true); - this.mediaRecorder_.removeEventListener('start', onstart); - }; - this.mediaRecorder_.addEventListener('dataavailable', ondataavailable); - this.mediaRecorder_.addEventListener('stop', onstop); - this.mediaRecorder_.addEventListener('start', onstart); - - window.addEventListener('beforeunload', beforeUnloadListener); - - this.mediaRecorder_.start(100); - state.set(state.State.RECORDING_PAUSED, false); - state.set(state.State.RECORDING_UI_PAUSED, false); - }); + }); + return saver; + } catch (e) { + await saver.cancel(); + throw e; + } } } diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings.grd b/chromeos/components/camera_app_ui/resources/strings/camera_strings.grd index 407bb6a7cc1463..a109731fb9dc5d 100644 --- a/chromeos/components/camera_app_ui/resources/strings/camera_strings.grd +++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings.grd @@ -466,6 +466,9 @@ If your feedback is about image or video quality, please attach a sample photo o <message desc="Error message shown on camera app window when the app is paused." name="IDS_ERROR_MSG_CAMERA_PAUSED"> Paused </message> + <message desc="Error message shown when users capture a video which is too short." name="IDS_ERROR_MSG_VIDEO_TOO_SHORT"> + The video is not saved since it is too short. + </message> </messages> </release> </grit> diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_grd/IDS_ERROR_MSG_VIDEO_TOO_SHORT.png.sha1 b/chromeos/components/camera_app_ui/resources/strings/camera_strings_grd/IDS_ERROR_MSG_VIDEO_TOO_SHORT.png.sha1 new file mode 100644 index 00000000000000..e940b848eb4560 --- /dev/null +++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_grd/IDS_ERROR_MSG_VIDEO_TOO_SHORT.png.sha1 @@ -0,0 +1 @@ +b2626b33abff403cadccdd79d32901163884e88d \ No newline at end of file From 5836b55d5f633f2c281b745a34d43e41442b8a1c Mon Sep 17 00:00:00 2001 From: Yuki Shiino <yukishiino@chromium.org> Date: Tue, 1 Jun 2021 09:48:17 +0000 Subject: [PATCH 23/81] bind-gen: Update the list of generated bindings files. Bug: 839389 Change-Id: I8d10d6f2d4894d0e8a73a4002c894556b199d9af Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928683 Commit-Queue: Yuki Shiino <yukishiino@chromium.org> Reviewed-by: Kentaro Hara <haraken@chromium.org> Cr-Commit-Position: refs/heads/master@{#887900} --- .../renderer/bindings/generated_in_core.gni | 10 ++++- .../bindings/generated_in_modules.gni | 38 ++++++++++++++++++- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni index efe9dbc32fd466..670831fedc519e 100644 --- a/third_party/blink/renderer/bindings/generated_in_core.gni +++ b/third_party/blink/renderer/bindings/generated_in_core.gni @@ -85,6 +85,10 @@ generated_dictionary_sources_in_core = [ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_playback_event_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_event_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_event_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_options.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_options.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_navigation_options.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_navigation_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_application_cache_error_event_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_application_cache_error_event_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_assigned_nodes_options.cc", @@ -115,6 +119,10 @@ generated_dictionary_sources_in_core = [ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_custom_layout_constraints_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_timeline_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_timeline_options.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_transition_prepare_options.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_transition_prepare_options.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_transition_start_options.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_document_transition_start_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_2d_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_2d_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_dom_matrix_init.cc", @@ -177,8 +185,6 @@ generated_dictionary_sources_in_core = [ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_data_settings.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_encode_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_encode_options.h", - "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_impression_params.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_impression_params.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_input_device_capabilities_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_input_device_capabilities_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_input_event_init.cc", diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index 387be0798e19af..de24a1e063974f 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni @@ -111,6 +111,12 @@ generated_dictionary_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_android_pay_method_data.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_app_banner_prompt_result.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_app_banner_prompt_result.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_auction_ad.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_auction_ad.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_auction_ad_config.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_auction_ad_config.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_auction_ad_interest_group.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_auction_ad_interest_group.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_buffer_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_buffer_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_buffer_source_options.cc", @@ -131,6 +137,8 @@ generated_dictionary_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_encoder_config.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_encoder_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_encoder_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_encoder_support.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_encoder_support.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_node_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_node_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_param_descriptor.cc", @@ -201,6 +209,12 @@ generated_dictionary_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_filter_dictionary.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_rendering_context_2d_settings.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_canvas_rendering_context_2d_settings.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_capture_handle.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_capture_handle.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_capture_handle_change_event_init.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_capture_handle_change_event_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_capture_handle_config.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_capture_handle_config.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_merger_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_merger_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_splitter_options.cc", @@ -389,6 +403,8 @@ generated_dictionary_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_image_copy_texture.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_image_data_layout.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_image_data_layout.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_multisample_state.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_multisample_state.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_object_descriptor_base.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_object_descriptor_base.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_origin_2d_dict.cc", @@ -593,6 +609,10 @@ generated_dictionary_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_permission_descriptor.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_multi_cache_query_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_multi_cache_query_options.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_read_result.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_read_result.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_write_result.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_write_result.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigation_preload_state.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigation_preload_state.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_message_init.cc", @@ -683,6 +703,8 @@ generated_dictionary_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_picture_in_picture_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_plane_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_plane_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_plane_layout.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_plane_layout.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_point_2d.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_point_2d.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_position_options.cc", @@ -717,8 +739,6 @@ generated_dictionary_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_options_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_query_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_query_options.h", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_quic_transport_options.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_quic_transport_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_registration_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_registration_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_related_application.cc", @@ -841,6 +861,8 @@ generated_dictionary_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_stream_abort_info.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sync_event_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sync_event_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_priority_change_event_init.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_priority_change_event_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_decode_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_decode_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_decoder_options.cc", @@ -877,12 +899,18 @@ generated_dictionary_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_encode_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_support.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_support.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame_init.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame_metadata.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame_metadata.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame_plane_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame_plane_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame_read_into_options.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame_read_into_options.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame_region.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_frame_region.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_watch_advertisements_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_watch_advertisements_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wave_shaper_options.cc", @@ -891,6 +919,8 @@ generated_dictionary_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_id_request_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_transport_close_info.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_transport_close_info.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_transport_options.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_web_transport_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_context_attributes.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_context_attributes.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_webgl_context_event_init.cc", @@ -938,6 +968,8 @@ generated_dictionary_sources_in_modules = [ ] generated_enumeration_sources_in_modules = [ + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_alpha_option.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_alpha_option.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_app_banner_prompt_outcome.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_app_banner_prompt_outcome.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_append_mode.cc", @@ -1136,6 +1168,8 @@ generated_enumeration_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port_device_state.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port_type.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port_type.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mode.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mode.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_action_type.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_action_type.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_direction.cc", From 5bd8ca6b5574bc13f5f799568634b8104a1e687a Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 09:48:26 +0000 Subject: [PATCH 24/81] Roll Chrome Win64 PGO Profile Roll Chrome Win64 PGO profile from chrome-win64-master-1622489765-17f517230a1b6a8f215c9f0b82fd2c04108ce54e.profdata to chrome-win64-master-1622527178-f7f002d24b6ce32cbf736f0bf14b7211500ab8a5.profdata If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/pgo-win64-chromium Please CC pgo-profile-sheriffs@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chrome.try:win64-chrome Tbr: pgo-profile-sheriffs@google.com Change-Id: Ie21ac204e30dd2ee7e255276f336aa515c96e335 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929997 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887901} --- chrome/build/win64.pgo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index c9761b6ce3930e..a2d677e8a62c07 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt @@ -1 +1 @@ -chrome-win64-master-1622489765-17f517230a1b6a8f215c9f0b82fd2c04108ce54e.profdata +chrome-win64-master-1622527178-f7f002d24b6ce32cbf736f0bf14b7211500ab8a5.profdata From ed24ed8d5d252861027896878fceecb5a453183b Mon Sep 17 00:00:00 2001 From: sandromaggi <sandromaggi@google.com> Date: Tue, 1 Jun 2021 09:49:22 +0000 Subject: [PATCH 25/81] [Autofill Assistant] Write test for TriggerScript + Keyboard This adds a regression test for b/189283884. Bug: b/189283884 Change-Id: I8d6be7d7668d9829af0af129fddb62f0b2433c8c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929958 Reviewed-by: Clemens Arbesser <arbesser@google.com> Commit-Queue: Sandro Maggi <sandromaggi@google.com> Cr-Commit-Position: refs/heads/master@{#887902} --- ...AssistantTriggerScriptIntegrationTest.java | 34 +++++++++++++++++++ .../AutofillAssistantUiTestUtil.java | 17 ++++++++++ 2 files changed, 51 insertions(+) diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTriggerScriptIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTriggerScriptIntegrationTest.java index 408bbe431ffe1b..97ce013fda4215 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTriggerScriptIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTriggerScriptIntegrationTest.java @@ -23,7 +23,9 @@ import static org.chromium.base.test.util.CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.createDefaultTriggerScriptUI; +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.scrollIntoView; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.tapElement; +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilKeyboardMatchesCondition; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewAssertionTrue; import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewMatchesCondition; @@ -723,4 +725,36 @@ public void onScrollEnded(int scrollOffsetY, int scrollExtentY) { waitUntilViewAssertionTrue(withText("Continue"), doesNotExist(), DEFAULT_MAX_TIME_TO_POLL); Assert.assertTrue(AutofillAssistantPreferencesUtil.getShowOnboarding()); } + + @Test + @MediumTest + @Features.EnableFeatures(ChromeFeatureList.AUTOFILL_ASSISTANT_PROACTIVE_HELP) + public void triggerScriptHidesAndShowsForKeyboard() throws Exception { + TriggerScriptProto.Builder triggerScript = + TriggerScriptProto.newBuilder() + .setTriggerCondition( + TriggerScriptConditionProto.newBuilder().setKeyboardHidden( + Empty.newBuilder())) + .setUserInterface(createDefaultTriggerScriptUI("Hello world", + /* bubbleMessage = */ "", + /* withProgressBar = */ false)); + + GetTriggerScriptsResponseProto triggerScripts = GetTriggerScriptsResponseProto.newBuilder() + .addTriggerScripts(triggerScript) + .build(); + AutofillAssistantTestServiceRequestSender testServiceRequestSender = + setupTriggerScripts(triggerScripts); + startAutofillAssistantOnTab(TEST_PAGE_A); + waitUntilViewMatchesCondition(withText("Hello world"), isCompletelyDisplayed()); + + scrollIntoView(mTestRule.getWebContents(), "input1"); + tapElement(mTestRule, "input1"); + waitUntilKeyboardMatchesCondition(mTestRule, /* isShowing= */ true); + waitUntilViewAssertionTrue( + withText("Hello World"), doesNotExist(), DEFAULT_MAX_TIME_TO_POLL); + + Espresso.closeSoftKeyboard(); + waitUntilKeyboardMatchesCondition(mTestRule, /* isShowing= */ false); + waitUntilViewMatchesCondition(withText("Hello world"), isCompletelyDisplayed()); + } } diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java index ca0f8c65a2708c..b6ccc6ed9fb535 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java @@ -706,6 +706,23 @@ public static String getElementValue(WebContents webContents, String... elementI return result.getString(0); } + /** + * Scroll the element into view. + */ + public static void scrollIntoView(WebContents webContents, String... elementIds) + throws Exception { + if (!checkElementExists(webContents, elementIds)) { + throw new IllegalArgumentException(Arrays.toString(elementIds) + " does not exist"); + } + TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper = + new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper(); + javascriptHelper.evaluateJavaScriptForTests(webContents, + "(function() {" + getElementSelectorString(elementIds) + ".scrollIntoView();" + + "return true;" + + "})()"); + javascriptHelper.waitUntilHasValue(); + } + /** * Converts a view into a bitmap. */ From ddbc489e10646f7483c838b3ed476b39a1e43978 Mon Sep 17 00:00:00 2001 From: Maksim Ivanov <emaxx@chromium.org> Date: Tue, 1 Jun 2021 10:07:23 +0000 Subject: [PATCH 26/81] Add missing explicit specifiers in /login/ code Mark single-argument constructors as explicit throughout the */login/* code. Bug: none Change-Id: I17e642696757725b17cf7577f81fd1b798ce8293 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2927608 Auto-Submit: Maksim Ivanov <emaxx@chromium.org> Reviewed-by: Denis Kuznetsov [CET] <antrim@chromium.org> Commit-Queue: Maksim Ivanov <emaxx@chromium.org> Cr-Commit-Position: refs/heads/master@{#887903} --- ash/login/ui/animated_rounded_image_view.cc | 3 ++- ash/login/ui/bottom_status_indicator.h | 2 +- ash/login/ui/login_base_bubble_view.cc | 2 +- ash/login/ui/login_user_view.cc | 6 +++--- ash/login/ui/public_account_warning_dialog.h | 2 +- chrome/browser/ash/login/app_mode/kiosk_browsertest.cc | 2 +- chrome/browser/ash/login/marketing_backend_connector.h | 2 +- chrome/browser/ash/login/oobe_interactive_ui_test.cc | 2 +- .../login/active_directory_password_change_screen_handler.h | 2 +- chromeos/login/auth/test_attempt_state.h | 2 +- .../login_state/scoped_test_public_session_login_state.h | 2 +- 11 files changed, 14 insertions(+), 13 deletions(-) diff --git a/ash/login/ui/animated_rounded_image_view.cc b/ash/login/ui/animated_rounded_image_view.cc index 1354083b156b0a..bfb4f03e351549 100644 --- a/ash/login/ui/animated_rounded_image_view.cc +++ b/ash/login/ui/animated_rounded_image_view.cc @@ -21,7 +21,8 @@ namespace { class SingleFrameImageDecoder : public AnimatedRoundedImageView::AnimationDecoder { public: - SingleFrameImageDecoder(const gfx::ImageSkia& image) : image_(image) {} + explicit SingleFrameImageDecoder(const gfx::ImageSkia& image) + : image_(image) {} ~SingleFrameImageDecoder() override = default; // AnimatedRoundedImageView::AnimationDecoder: diff --git a/ash/login/ui/bottom_status_indicator.h b/ash/login/ui/bottom_status_indicator.h index c0487e0154faa5..e5ac7916f36661 100644 --- a/ash/login/ui/bottom_status_indicator.h +++ b/ash/login/ui/bottom_status_indicator.h @@ -20,7 +20,7 @@ class BottomStatusIndicator : public views::LabelButton { public: using TappedCallback = base::RepeatingClosure; - BottomStatusIndicator(TappedCallback on_tapped_callback); + explicit BottomStatusIndicator(TappedCallback on_tapped_callback); BottomStatusIndicator(const BottomStatusIndicator&) = delete; BottomStatusIndicator& operator=(const BottomStatusIndicator&) = delete; ~BottomStatusIndicator() override; diff --git a/ash/login/ui/login_base_bubble_view.cc b/ash/login/ui/login_base_bubble_view.cc index e64deeedfff0c9..d2776a715326f1 100644 --- a/ash/login/ui/login_base_bubble_view.cc +++ b/ash/login/ui/login_base_bubble_view.cc @@ -47,7 +47,7 @@ constexpr base::TimeDelta kBubbleAnimationDuration = // associated bubble in response. class LoginBubbleHandler : public ui::EventHandler { public: - LoginBubbleHandler(LoginBaseBubbleView* bubble) : bubble_(bubble) { + explicit LoginBubbleHandler(LoginBaseBubbleView* bubble) : bubble_(bubble) { Shell::Get()->AddPreTargetHandler(this); } diff --git a/ash/login/ui/login_user_view.cc b/ash/login/ui/login_user_view.cc index e9504dec459d6c..df220e6695285c 100644 --- a/ash/login/ui/login_user_view.cc +++ b/ash/login/ui/login_user_view.cc @@ -88,7 +88,7 @@ constexpr char kLoginUserLabelClassName[] = "LoginUserLabel"; class PassthroughAnimationDecoder : public AnimatedRoundedImageView::AnimationDecoder { public: - PassthroughAnimationDecoder(const AnimationFrames& frames) + explicit PassthroughAnimationDecoder(const AnimationFrames& frames) : frames_(frames) {} ~PassthroughAnimationDecoder() override = default; @@ -102,7 +102,7 @@ class PassthroughAnimationDecoder class IconRoundedView : public views::View { public: - IconRoundedView(int size) : size_(size) {} + explicit IconRoundedView(int size) : size_(size) {} ~IconRoundedView() override = default; IconRoundedView(const IconRoundedView&) = delete; @@ -166,7 +166,7 @@ class LoginUserView::UserImage : public NonAccessibleView { LoginUserView::UserImage* const view_; }; - UserImage(LoginDisplayStyle style) + explicit UserImage(LoginDisplayStyle style) : NonAccessibleView(kLoginUserImageClassName) { SetLayoutManager(std::make_unique<views::FillLayout>()); diff --git a/ash/login/ui/public_account_warning_dialog.h b/ash/login/ui/public_account_warning_dialog.h index 189d3461b877a1..b1042cb8bcfb0c 100644 --- a/ash/login/ui/public_account_warning_dialog.h +++ b/ash/login/ui/public_account_warning_dialog.h @@ -17,7 +17,7 @@ class LoginExpandedPublicAccountView; // clicks on the learn more link on the pubic account expanded view. class ASH_EXPORT PublicAccountWarningDialog : public views::DialogDelegateView { public: - PublicAccountWarningDialog( + explicit PublicAccountWarningDialog( base::WeakPtr<LoginExpandedPublicAccountView> controller); ~PublicAccountWarningDialog() override; diff --git a/chrome/browser/ash/login/app_mode/kiosk_browsertest.cc b/chrome/browser/ash/login/app_mode/kiosk_browsertest.cc index e01015a8b41c75..180473c0f03c5f 100644 --- a/chrome/browser/ash/login/app_mode/kiosk_browsertest.cc +++ b/chrome/browser/ash/login/app_mode/kiosk_browsertest.cc @@ -432,7 +432,7 @@ class AppDataLoadWaiter : public KioskAppManagerObserver { // Replaces settings urls for KioskSettingsNavigationThrottle. class ScopedSettingsPages { public: - ScopedSettingsPages( + explicit ScopedSettingsPages( std::vector<KioskSettingsNavigationThrottle::SettingsPage>* pages) { KioskSettingsNavigationThrottle::SetSettingPagesForTesting(pages); } diff --git a/chrome/browser/ash/login/marketing_backend_connector.h b/chrome/browser/ash/login/marketing_backend_connector.h index bc73248b7ad7bc..beccfff14f1c22 100644 --- a/chrome/browser/ash/login/marketing_backend_connector.h +++ b/chrome/browser/ash/login/marketing_backend_connector.h @@ -95,7 +95,7 @@ class MarketingBackendConnector // Scoped callback setter for the MarketingBackendConnector class ScopedRequestCallbackSetter { public: - ScopedRequestCallbackSetter( + explicit ScopedRequestCallbackSetter( std::unique_ptr<base::RepeatingCallback<void(std::string)>> callback); ~ScopedRequestCallbackSetter(); diff --git a/chrome/browser/ash/login/oobe_interactive_ui_test.cc b/chrome/browser/ash/login/oobe_interactive_ui_test.cc index be81a880f31d79..77ebb270359b84 100644 --- a/chrome/browser/ash/login/oobe_interactive_ui_test.cc +++ b/chrome/browser/ash/login/oobe_interactive_ui_test.cc @@ -477,7 +477,7 @@ class NativeWindowVisibilityObserver : public aura::WindowObserver { class NativeWindowVisibilityBrowserMainExtraParts : public ChromeBrowserMainExtraParts { public: - NativeWindowVisibilityBrowserMainExtraParts( + explicit NativeWindowVisibilityBrowserMainExtraParts( NativeWindowVisibilityObserver* observer) : observer_(observer) {} ~NativeWindowVisibilityBrowserMainExtraParts() override = default; diff --git a/chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h index 8a978fee173058..ba724c6b53ab4a 100644 --- a/chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/active_directory_password_change_screen_handler.h @@ -44,7 +44,7 @@ class ActiveDirectoryPasswordChangeScreenHandler public: using TView = ActiveDirectoryPasswordChangeView; - ActiveDirectoryPasswordChangeScreenHandler( + explicit ActiveDirectoryPasswordChangeScreenHandler( JSCallsContainer* js_calls_container); ~ActiveDirectoryPasswordChangeScreenHandler() override; diff --git a/chromeos/login/auth/test_attempt_state.h b/chromeos/login/auth/test_attempt_state.h index 51e88a44414817..b515985e00c913 100644 --- a/chromeos/login/auth/test_attempt_state.h +++ b/chromeos/login/auth/test_attempt_state.h @@ -19,7 +19,7 @@ class UserContext; class COMPONENT_EXPORT(CHROMEOS_LOGIN_AUTH) TestAttemptState : public AuthAttemptState { public: - TestAttemptState(const UserContext& credentials); + explicit TestAttemptState(const UserContext& credentials); ~TestAttemptState() override; diff --git a/chromeos/login/login_state/scoped_test_public_session_login_state.h b/chromeos/login/login_state/scoped_test_public_session_login_state.h index 46053a9df9db4a..f0754abaa0fbb1 100644 --- a/chromeos/login/login_state/scoped_test_public_session_login_state.h +++ b/chromeos/login/login_state/scoped_test_public_session_login_state.h @@ -15,7 +15,7 @@ namespace chromeos { // (so it nicely cleans up after going out of scope). class ScopedTestPublicSessionLoginState { public: - ScopedTestPublicSessionLoginState( + explicit ScopedTestPublicSessionLoginState( LoginState::LoggedInUserType user_type = LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT); ~ScopedTestPublicSessionLoginState(); From 428b9ab9c67f504a745905974d1a67cdd8739706 Mon Sep 17 00:00:00 2001 From: Glen Robertson <glenrob@chromium.org> Date: Tue, 1 Jun 2021 10:07:42 +0000 Subject: [PATCH 27/81] Cleanup the kHandwritingRecognitionWebPlatformApi flag. The flag was originally needed to restrict the availability of the API to specific hardware devices that could support it. The API is now available on all devices and the flag is now enabled by default. The flag is not needed even to turn off the API via Finch, as we have a separate flag for that (kHandwritingRecognitionWebPlatformApiFinch). Bug: 1166910 Change-Id: I79bc81171380739ed457235d6bb983fe0c8eaa99 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2927635 Reviewed-by: Andrew Moylan <amoylan@chromium.org> Reviewed-by: Kinuko Yasuda <kinuko@chromium.org> Commit-Queue: Kinuko Yasuda <kinuko@chromium.org> Auto-Submit: Glen Robertson <glenrob@chromium.org> Cr-Commit-Position: refs/heads/master@{#887904} --- content/browser/browser_interface_binders.cc | 2 - third_party/blink/common/features.cc | 16 +----- third_party/blink/public/common/features.h | 2 - .../origin_trials/origin_trial_context.cc | 56 ++++++++----------- .../platform/runtime_enabled_features.json5 | 2 +- 5 files changed, 27 insertions(+), 51 deletions(-) diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 953409929b031a..24cc886e1c63a0 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc @@ -728,8 +728,6 @@ void PopulateFrameBinders(RenderFrameHostImpl* host, mojo::BinderMap* map) { &RenderFrameHostImpl::CreatePaymentManager, base::Unretained(host))); if (base::FeatureList::IsEnabled( - blink::features::kHandwritingRecognitionWebPlatformApi) && - base::FeatureList::IsEnabled( blink::features::kHandwritingRecognitionWebPlatformApiFinch)) { map->Add<handwriting::mojom::HandwritingRecognitionService>( base::BindRepeating(&CreateHandwritingRecognitionService)); diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index e6c5b184c0e7ad..f19febd1074fc4 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc @@ -33,20 +33,8 @@ const base::Feature kConversionMeasurement{"ConversionMeasurement", const base::Feature kGMSCoreEmoji{"GMSCoreEmoji", base::FEATURE_DISABLED_BY_DEFAULT}; -// Whether the HandwritingRecognition API can be enabled. Disabling this feature -// disables both the origin trial and the mojo interface. Enabling this feature -// allows the API to be controlled by origin trial (see web runtime feature -// `HandwritingRecognition`) and finch (see -// `kHandwritingRecognitionWebPlatformApiFinch`). -// TODO (crbug.com/1166910): Remove once the HandwritingRecognition API is more -// widely available (likely M92). -const base::Feature kHandwritingRecognitionWebPlatformApi{ - "HandwritingRecognitionWebPlatformApi", base::FEATURE_ENABLED_BY_DEFAULT}; - -// Whether the HandwritingRecognition API can be enabled. Disabling this feature -// disables both the origin trial and the mojo interface. Defaults to enabled -// so the feature can be controlled by finch, even when -// `kHandwritingRecognitionWebPlatformApi` is set from command-line. +// Whether the HandwritingRecognition API can be enabled by origin trial. +// Disabling this feature disables both the origin trial and the mojo interface. const base::Feature kHandwritingRecognitionWebPlatformApiFinch{ "HandwritingRecognitionWebPlatformApiFinch", base::FEATURE_ENABLED_BY_DEFAULT}; diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 4f97c5709cba09..307bbdc0a45e33 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h @@ -22,8 +22,6 @@ BLINK_COMMON_EXPORT extern const base::Feature kCOLRV1Fonts; BLINK_COMMON_EXPORT extern const base::Feature kCSSContainerQueries; BLINK_COMMON_EXPORT extern const base::Feature kConversionMeasurement; BLINK_COMMON_EXPORT extern const base::Feature kGMSCoreEmoji; -BLINK_COMMON_EXPORT extern const base::Feature - kHandwritingRecognitionWebPlatformApi; BLINK_COMMON_EXPORT extern const base::Feature kHandwritingRecognitionWebPlatformApiFinch; BLINK_COMMON_EXPORT extern const base::Feature kPaintHolding; diff --git a/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc b/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc index d1f3ee0cd9f7c4..b91d3f8f2de625 100644 --- a/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc +++ b/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc @@ -424,41 +424,33 @@ void OriginTrialContext::AddForceEnabledTrials( bool OriginTrialContext::CanEnableTrialFromName(const StringView& trial_name) { if (trial_name == "HandwritingRecognition") { return base::FeatureList::IsEnabled( - features::kHandwritingRecognitionWebPlatformApi) && - base::FeatureList::IsEnabled( features::kHandwritingRecognitionWebPlatformApiFinch); } - if (trial_name == "Portals" && - !base::FeatureList::IsEnabled(features::kPortals)) { - return false; - } - if (trial_name == "FencedFrames" && - !base::FeatureList::IsEnabled(features::kFencedFrames)) { - return false; - } - if (trial_name == "AppCache" && - !base::FeatureList::IsEnabled(features::kAppCache)) { - return false; - } - if (trial_name == "ComputePressure" && - !base::FeatureList::IsEnabled(features::kComputePressure)) { - return false; - } - if (trial_name == "FledgeInterestGroupAPI" && - !base::FeatureList::IsEnabled(features::kFledgeInterestGroups)) { - return false; - } - if (trial_name == "TrustTokens" && - !base::FeatureList::IsEnabled(network::features::kTrustTokens)) { - return false; - } - if (trial_name == "InterestCohortAPI" && - !base::FeatureList::IsEnabled(features::kInterestCohortAPIOriginTrial)) { - return false; + if (trial_name == "Portals") + return base::FeatureList::IsEnabled(features::kPortals); + + if (trial_name == "FencedFrames") + return base::FeatureList::IsEnabled(features::kFencedFrames); + + if (trial_name == "AppCache") + return base::FeatureList::IsEnabled(features::kAppCache); + + if (trial_name == "ComputePressure") + return base::FeatureList::IsEnabled(features::kComputePressure); + + if (trial_name == "FledgeInterestGroupAPI") + return base::FeatureList::IsEnabled(features::kFledgeInterestGroups); + + if (trial_name == "TrustTokens") + return base::FeatureList::IsEnabled(network::features::kTrustTokens); + + if (trial_name == "InterestCohortAPI") { + return base::FeatureList::IsEnabled( + features::kInterestCohortAPIOriginTrial); } - if (trial_name == "SpeculationRulesPrefetch" && - !base::FeatureList::IsEnabled(features::kSpeculationRulesPrefetchProxy)) { - return false; + if (trial_name == "SpeculationRulesPrefetch") { + return base::FeatureList::IsEnabled( + features::kSpeculationRulesPrefetchProxy); } if (trial_name == "ConversionMeasurement" && !base::FeatureList::IsEnabled(features::kConversionMeasurement)) { diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index ea4e277a5689fa..20b63a703f7d18 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5 @@ -1020,7 +1020,7 @@ { name: "HandwritingRecognition", status: "experimental", - // Trial also requires kHandwritingRecognitionWebPlatformApi enabled. + // Trial also requires kHandwritingRecognitionWebPlatformApiFinch enabled. origin_trial_feature_name: "HandwritingRecognition", origin_trial_os: ["chromeos"] }, From 612ce219847a018cae2e27e4adbcae94698338fa Mon Sep 17 00:00:00 2001 From: Tanmoy Mollik <triploblastic@chromium.org> Date: Tue, 1 Jun 2021 10:10:22 +0000 Subject: [PATCH 28/81] Add fieldtrial entry for MobileIdentityConsistencyVar Bug: 1179632 Change-Id: Ibf98f3ee48cc472b5628f574726f70e79921ed07 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2922083 Reviewed-by: Robert Kaplow <rkaplow@chromium.org> Commit-Queue: Tanmoy Mollik <triploblastic@chromium.org> Cr-Commit-Position: refs/heads/master@{#887905} --- .../variations/fieldtrial_testing_config.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 46b1d81c369649..7774cdf64beb7b 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json @@ -4942,6 +4942,24 @@ ] } ], + "MobileIdentityConsistencyVar": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "EnabledWithConsecutiveActiveDismissal", + "params": { + "consecutive_active_dismissal_limit": "3" + }, + "enable_features": [ + "MobileIdentityConsistencyVar" + ] + } + ] + } + ], "MojoInlineMessagePayloads": [ { "platforms": [ From 27962c8b6790104b75d25ecdaf251b45f511bcd2 Mon Sep 17 00:00:00 2001 From: Marc Treib <treib@chromium.org> Date: Tue, 1 Jun 2021 10:16:24 +0000 Subject: [PATCH 29/81] Small cleanups in/around DataTypeManagerImpl - Updated/removed some old comments. - Removed unused Abort() method. - Removed ConfigureParams::enabled_types field which was (a) misleading (it actually contained the currently-being-configured types) and (b) unused outside of some tests. Bug: 1170318 Change-Id: I2133669eefe975b4779675b2a8a7520d9610ffdc Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2927313 Commit-Queue: Marc Treib <treib@chromium.org> Reviewed-by: Mikel Astiz <mastiz@chromium.org> Cr-Commit-Position: refs/heads/master@{#887906} --- .../sync/driver/data_type_manager_impl.cc | 61 +++++-------------- .../sync/driver/data_type_manager_impl.h | 6 -- .../driver/glue/sync_engine_impl_unittest.cc | 7 +-- .../sync/engine/model_type_configurer.h | 11 +--- .../sync/test/engine/fake_sync_engine.cc | 2 +- 5 files changed, 21 insertions(+), 66 deletions(-) diff --git a/components/sync/driver/data_type_manager_impl.cc b/components/sync/driver/data_type_manager_impl.cc index 44f6bf10597a2f..14701fee27ea76 100644 --- a/components/sync/driver/data_type_manager_impl.cc +++ b/components/sync/driver/data_type_manager_impl.cc @@ -544,58 +544,36 @@ DataTypeManagerImpl::PrepareConfigureParams( const ModelTypeSet inactive_types = GetDataTypesInState(CONFIGURE_INACTIVE, config_state_map); - const ModelTypeSet enabled_types = active_types; ModelTypeSet disabled_types = GetDataTypesInState(DISABLED, config_state_map); disabled_types.PutAll(fatal_types); disabled_types.PutAll(crypto_types); disabled_types.PutAll(unready_types); - DCHECK(Intersection(enabled_types, disabled_types).Empty()); - - // The sync engine's enabled types will be updated by adding |enabled_types| - // to the list then removing |disabled_types|. Any types which are not in - // either of those sets will remain untouched. Types which were not in - // |downloaded_types_| previously are not fully downloaded, so we must ask the - // engine to download them. Any newly supported datatypes won't have been in - // |downloaded_types_|, so they will also be downloaded if they are enabled. - ModelTypeSet types_to_download = Difference(enabled_types, downloaded_types_); - downloaded_types_.PutAll(enabled_types); - downloaded_types_.RemoveAll(disabled_types); + DCHECK(Intersection(active_types, disabled_types).Empty()); + ModelTypeSet types_to_download = Difference(active_types, downloaded_types_); + // Proxy and commit-only types never require downloading. types_to_download.RemoveAll(ProxyTypes()); types_to_download.RemoveAll(CommitOnlyTypes()); - if (!types_to_download.Empty()) - types_to_download.Put(NIGORI); + if (!types_to_download.Empty()) { + types_to_download.PutAll(ControlTypes()); + } + // Already (optimistically) update the |downloaded_types_|, so that the next + // time we get here, it has the correct value. + downloaded_types_.PutAll(active_types); + // Assume that disabled types are not downloaded anymore - if they get + // re-enabled, we'll want to re-download them as well. + downloaded_types_.RemoveAll(disabled_types); force_redownload_types_.RemoveAll(types_to_download); - // TODO(sync): crbug.com/137550. - // It's dangerous to configure types that have progress markers. Types with - // progress markers can trigger a MIGRATION_DONE response. We are not - // prepared to handle a migration during a configure, so we must ensure that - // all our types_to_download actually contain no data before we sync them. - // - // One common way to end up in this situation used to be types which - // downloaded some or all of their data but have not applied it yet. We avoid - // problems with those types by purging the data of any such partially synced - // types soon after we load the Directory. - // - // Another possible scenario is that we have newly supported or newly enabled - // data types being downloaded here but the nigori type, which is always - // included in any GetUpdates request, requires migration. The server has - // code to detect this scenario based on the configure reason, the fact that - // the nigori type is the only requested type which requires migration, and - // that the requested types list includes at least one non-nigori type. It - // will not send a MIGRATION_DONE response in that case. We still need to be - // careful to not send progress markers for non-nigori types, though. If a - // non-nigori type in the request requires migration, a MIGRATION_DONE - // response will be sent. - ModelTypeSet types_to_purge; // If we're using transport-only mode, don't clear any old data. The reason is // that if a user temporarily disables Sync, we don't want to wipe (and later // redownload) all their data, just because Sync restarted in transport-only // mode. + // TODO(crbug.com/1142771): "Purging" logic is only implemented for NIGORI - + // verify whether it is actually needed at all. if (last_requested_context_.sync_mode == SyncMode::kFull) { types_to_purge = Difference(ModelTypeSet::All(), downloaded_types_); types_to_purge.RemoveAll(inactive_types); @@ -612,7 +590,6 @@ DataTypeManagerImpl::PrepareConfigureParams( ModelTypeConfigurer::ConfigureParams params; params.reason = last_requested_context_.reason; - params.enabled_types = enabled_types; params.to_download = types_to_download; params.to_purge = types_to_purge; params.ready_task = @@ -698,16 +675,6 @@ void DataTypeManagerImpl::Stop(ShutdownReason reason) { } } -void DataTypeManagerImpl::Abort(ConfigureStatus status) { - DCHECK_EQ(CONFIGURING, state_); - - StopImpl(STOP_SYNC); - - DCHECK_NE(OK, status); - ConfigureResult result(status, last_requested_types_); - NotifyDone(result); -} - void DataTypeManagerImpl::StopImpl(ShutdownReason reason) { state_ = STOPPING; diff --git a/components/sync/driver/data_type_manager_impl.h b/components/sync/driver/data_type_manager_impl.h index f54b3f777638fe..c44478d0c2db69 100644 --- a/components/sync/driver/data_type_manager_impl.h +++ b/components/sync/driver/data_type_manager_impl.h @@ -111,9 +111,6 @@ class DataTypeManagerImpl : public DataTypeManager, ModelTypeConfigurer::ConfigureParams PrepareConfigureParams( const AssociationTypesInfo& association_types_info); - // Abort configuration and stop all data types due to configuration errors. - void Abort(ConfigureStatus status); - // Divide |types| into sets by their priorities and return the sets from // high priority to low priority. base::queue<ModelTypeSet> PrioritizeTypes(const ModelTypeSet& types); @@ -194,9 +191,6 @@ class DataTypeManagerImpl : public DataTypeManager, // A set of types that should be redownloaded even if initial sync is // completed for them. - // TODO(crbug.com/967677): Once all datatypes are in USS, we should redesign - // this class and for example compute |downloaded_types_|'s initial value - // only after all datatypes have loaded for the first time. ModelTypeSet force_redownload_types_; // Whether an attempt to reconfigure was made while we were busy configuring. diff --git a/components/sync/driver/glue/sync_engine_impl_unittest.cc b/components/sync/driver/glue/sync_engine_impl_unittest.cc index 43420f701be1a5..b96b79761f3e9a 100644 --- a/components/sync/driver/glue/sync_engine_impl_unittest.cc +++ b/components/sync/driver/glue/sync_engine_impl_unittest.cc @@ -260,8 +260,8 @@ class SyncEngineImplTest : public testing::Test { ModelTypeSet ConfigureDataTypesWithUnready(ModelTypeSet unready_types) { ModelTypeConfigurer::ConfigureParams params; params.reason = CONFIGURE_REASON_RECONFIGURATION; - params.enabled_types = Difference(enabled_types_, unready_types); - params.to_download = Difference(params.enabled_types, engine_types_); + ModelTypeSet enabled_types = Difference(enabled_types_, unready_types); + params.to_download = Difference(enabled_types, engine_types_); if (!params.to_download.Empty()) { params.to_download.Put(NIGORI); } @@ -269,8 +269,7 @@ class SyncEngineImplTest : public testing::Test { params.ready_task = base::BindOnce(&SyncEngineImplTest::DownloadReady, base::Unretained(this)); - ModelTypeSet ready_types = - Difference(params.enabled_types, params.to_download); + ModelTypeSet ready_types = Difference(enabled_types, params.to_download); backend_->ConfigureDataTypes(std::move(params)); PumpSyncThread(); diff --git a/components/sync/engine/model_type_configurer.h b/components/sync/engine/model_type_configurer.h index 8c1c5c7d1f9444..4d2cef146bebe7 100644 --- a/components/sync/engine/model_type_configurer.h +++ b/components/sync/engine/model_type_configurer.h @@ -28,16 +28,11 @@ class ModelTypeConfigurer { ConfigureParams& operator=(ConfigureParams&& other); ConfigureReason reason; - ModelTypeSet enabled_types; ModelTypeSet to_download; ModelTypeSet to_purge; - // Run when configuration is done with the set of all types that failed - // configuration (if its argument isn't empty, an error was encountered). - // TODO(akalin): Use a Delegate class with OnConfigureSuccess, - // OnConfigureFailure, and OnConfigureRetry instead of a pair of callbacks. - // The awkward part is handling when SyncEngine calls ConfigureDataTypes on - // itself to configure Nigori. - base::OnceCallback<void(ModelTypeSet, ModelTypeSet)> ready_task; + + base::OnceCallback<void(ModelTypeSet succeeded, ModelTypeSet failed)> + ready_task; // Whether full sync (or sync the feature) is enabled; bool is_sync_feature_enabled; diff --git a/components/sync/test/engine/fake_sync_engine.cc b/components/sync/test/engine/fake_sync_engine.cc index 496cc6628f9d56..956f7bf8019e7a 100644 --- a/components/sync/test/engine/fake_sync_engine.cc +++ b/components/sync/test/engine/fake_sync_engine.cc @@ -94,7 +94,7 @@ void FakeSyncEngine::Shutdown(ShutdownReason reason) { void FakeSyncEngine::ConfigureDataTypes(ConfigureParams params) { std::move(params.ready_task) - .Run(/*succeeded_configuration_types=*/params.enabled_types, + .Run(/*succeeded_configuration_types=*/params.to_download, /*failed_configuration_types=*/ModelTypeSet()); } From efb8608265b818a903e455671d6ab6a17c58dd3c Mon Sep 17 00:00:00 2001 From: Alice Wang <aliceywang@chromium.org> Date: Tue, 1 Jun 2021 10:22:13 +0000 Subject: [PATCH 30/81] [Signin][Android] Rename method AccountInfoService#getAccountInfoByEmailAsync() This CL renames the suffix -async in the method name AccountInfoService#getAccountInfoByEmailAsync() as this method could also be used synchronously. Bug: 1187512 Change-Id: I3ebf9be9fe02a77f28ff5549effd2e7ae74bd02f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928522 Commit-Queue: Alice Wang <aliceywang@chromium.org> Reviewed-by: Tanmoy Mollik <triploblastic@chromium.org> Cr-Commit-Position: refs/heads/master@{#887907} --- .../browser/signin/SigninManagerImpl.java | 6 +----- .../signin/SyncConsentFragmentBase.java | 18 ++++++++---------- .../signin/services/ProfileDataCache.java | 4 ++-- .../identitymanager/AccountInfoService.java | 4 ++-- 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java index b60301a2ee49a7..2a823ad5c93f51 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManagerImpl.java @@ -317,11 +317,7 @@ public void signinAndEnableSync(@SigninAccessPoint int accessPoint, CoreAccountI @Override public void signinAndEnableSync(@SigninAccessPoint int accessPoint, Account account, @Nullable SignInCallback callback) { - mAccountTrackerService.seedAccountsIfNeeded(() -> { - final CoreAccountInfo accountInfo = - mIdentityManager - .findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress( - account.name); + AccountInfoService.get().getAccountInfoByEmail(account.name).then(accountInfo -> { signinInternal( SignInState.createForSigninAndEnableSync(accessPoint, accountInfo, callback)); }); diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncConsentFragmentBase.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncConsentFragmentBase.java index b071c84e91c365..bbde1058f5dce3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncConsentFragmentBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncConsentFragmentBase.java @@ -405,16 +405,14 @@ private boolean areControlsEnabled() { } private void seedAccountsAndSignin(boolean settingsClicked, View confirmationView) { - AccountInfoService.get() - .getAccountInfoByEmailAsync(mSelectedAccountName) - .then(accountInfo -> { - assert accountInfo != null : "The seeded CoreAccountInfo shouldn't be null"; - mConsentTextTracker.recordConsent(accountInfo.getId(), - ConsentAuditorFeature.CHROME_SYNC, (TextView) confirmationView, mView); - if (isResumed()) { - runStateMachineAndSignin(settingsClicked); - } - }); + AccountInfoService.get().getAccountInfoByEmail(mSelectedAccountName).then(accountInfo -> { + assert accountInfo != null : "The seeded CoreAccountInfo shouldn't be null"; + mConsentTextTracker.recordConsent(accountInfo.getId(), + ConsentAuditorFeature.CHROME_SYNC, (TextView) confirmationView, mView); + if (isResumed()) { + runStateMachineAndSignin(settingsClicked); + } + }); } private void runStateMachineAndSignin(boolean settingsClicked) { diff --git a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCache.java b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCache.java index b94816762a4b37..45765f059e61ea 100644 --- a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCache.java +++ b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/ProfileDataCache.java @@ -203,7 +203,7 @@ public void onProfileDataUpdated(ProfileDataSource.ProfileData profileData) { Bitmap avatar = profileData.getAvatar(); if (avatar == null) { // If the avatar is null, try to fetch the monogram from IdentityManager - mAccountInfoService.getAccountInfoByEmailAsync(email).then(accountInfo -> { + mAccountInfoService.getAccountInfoByEmail(email).then(accountInfo -> { updateCacheAndNotifyObservers(email, accountInfo != null ? accountInfo.getAccountImage() : null, profileData.getFullName(), profileData.getGivenName()); @@ -233,7 +233,7 @@ public void onAccountInfoUpdated(AccountInfo accountInfo) { private void populateCache() { AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts(accounts -> { for (Account account : accounts) { - mAccountInfoService.getAccountInfoByEmailAsync(account.name) + mAccountInfoService.getAccountInfoByEmail(account.name) .then(this::onAccountInfoUpdated); } }); diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/AccountInfoService.java b/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/AccountInfoService.java index 04c80c573b7683..e5615ae007e03b 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/AccountInfoService.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/AccountInfoService.java @@ -78,9 +78,9 @@ public static void resetForTests() { } /** - * Gets the corresponding {@link AccountInfo} of the given account email asynchronously. + * Gets the corresponding {@link AccountInfo} of the given account email. */ - public Promise<AccountInfo> getAccountInfoByEmailAsync(String email) { + public Promise<AccountInfo> getAccountInfoByEmail(String email) { final Promise<AccountInfo> accountInfoPromise = new Promise<>(); mAccountTrackerService.seedAccountsIfNeeded(() -> { accountInfoPromise.fulfill( From e055252578c94e8e0b54d1c4cec0a82b1831ef43 Mon Sep 17 00:00:00 2001 From: Kent Tamura <tkent@chromium.org> Date: Tue, 1 Jun 2021 10:23:45 +0000 Subject: [PATCH 31/81] Rename data members of blink::FontMetrics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ascent_ -> float_ascent_ * descent_ -> float_descent_ * ascent_int_ -> int_ascent_ * descent_int_ -> int_descent_ Before this CL, we had two issues: - Ascent() and Descent() represented integer-variants, but ascent_ and descent_ represented float-variants. - FloatAscent() and FloatDescent() had prefixes representing their types, however ascent_int_ and descent_int_ had suffixes representing their types. This CL has no behavior changes, and is for code health. Change-Id: Ieb36233d8803669cfa5e8075c0be5e9b4f8279e2 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929426 Commit-Queue: Dominik Röttsches <drott@chromium.org> Auto-Submit: Kent Tamura <tkent@chromium.org> Reviewed-by: Dominik Röttsches <drott@chromium.org> Cr-Commit-Position: refs/heads/master@{#887908} --- .../renderer/platform/fonts/font_metrics.cc | 20 ++++----- .../renderer/platform/fonts/font_metrics.h | 44 +++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/third_party/blink/renderer/platform/fonts/font_metrics.cc b/third_party/blink/renderer/platform/fonts/font_metrics.cc index e59d727f0b50a7..b5e333a5a643a2 100644 --- a/third_party/blink/renderer/platform/fonts/font_metrics.cc +++ b/third_party/blink/renderer/platform/fonts/font_metrics.cc @@ -154,7 +154,7 @@ float FontMetrics::FloatAscentInternal(FontBaseline baseline_type) const { switch (baseline_type) { case kAlphabeticBaseline: NOTREACHED(); - return ascent_; + return float_ascent_; case kIdeographicBaseline: return FloatHeight() / 2; @@ -167,27 +167,27 @@ float FontMetrics::FloatAscentInternal(FontBaseline baseline_type) const { // TODO(layout-dev): Should refer to 'ideo' in OpenType. return FloatHeight(); case kXMiddleBaseline: - return ascent_ - XHeight() / 2; + return float_ascent_ - XHeight() / 2; case kMathBaseline: // TODO(layout-dev): Should refer to 'math' in OpenType or 'bsln' value 4 // in TrueType AAT. - return ascent_ * 0.5f; + return float_ascent_ * 0.5f; case kHangingBaseline: // TODO(layout-dev): Should refer to 'hang' in OpenType or 'bsln' value 3 // in TrueType AAT. - return ascent_ * 0.2f; + return float_ascent_ * 0.2f; case kTextOverBaseline: return 0; } NOTREACHED(); - return ascent_; + return float_ascent_; } int FontMetrics::IntAscentInternal(FontBaseline baseline_type) const { switch (baseline_type) { case kAlphabeticBaseline: NOTREACHED(); - return ascent_int_; + return int_ascent_; case kIdeographicBaseline: return Height() - Height() / 2; @@ -200,19 +200,19 @@ int FontMetrics::IntAscentInternal(FontBaseline baseline_type) const { // TODO(layout-dev): Should refer to 'ideo' in OpenType. return Height(); case kXMiddleBaseline: - return ascent_int_ - static_cast<int>(XHeight() / 2); + return int_ascent_ - static_cast<int>(XHeight() / 2); case kMathBaseline: // TODO(layout-dev): Should refer to 'math' in OpenType or 'bsln' value 4 // in TrueType AAT. - return ascent_int_ / 2; + return int_ascent_ / 2; case kHangingBaseline: // TODO(layout-dev): Should refer to 'hang' in OpenType or 'bsln' value 3 // in TrueType AAT. - return ascent_int_ * 2 / 10; + return int_ascent_ * 2 / 10; case kTextOverBaseline: return 0; } NOTREACHED(); - return ascent_int_; + return int_ascent_; } } diff --git a/third_party/blink/renderer/platform/fonts/font_metrics.h b/third_party/blink/renderer/platform/fonts/font_metrics.h index 4ca53961ffe77b..38d920712dbd9b 100644 --- a/third_party/blink/renderer/platform/fonts/font_metrics.h +++ b/third_party/blink/renderer/platform/fonts/font_metrics.h @@ -41,14 +41,14 @@ class FontMetrics { public: FontMetrics() : units_per_em_(kGDefaultUnitsPerEm), - ascent_(0), - descent_(0), + float_ascent_(0), + float_descent_(0), line_gap_(0), line_spacing_(0), x_height_(0), zero_width_(0), - ascent_int_(0), - descent_int_(0), + int_ascent_(0), + int_descent_(0), has_x_height_(false), has_zero_width_(false) {} @@ -57,27 +57,27 @@ class FontMetrics { float FloatAscent(FontBaseline baseline_type = kAlphabeticBaseline) const { if (baseline_type == kAlphabeticBaseline) - return ascent_; + return float_ascent_; return FloatAscentInternal(baseline_type); } void SetAscent(float ascent) { - ascent_ = ascent; - ascent_int_ = static_cast<int>(lroundf(ascent)); + float_ascent_ = ascent; + int_ascent_ = static_cast<int>(lroundf(ascent)); } float FloatDescent(FontBaseline baseline_type = kAlphabeticBaseline) const { if (baseline_type == kAlphabeticBaseline) - return descent_; + return float_descent_; return FloatHeight() - FloatAscentInternal(baseline_type); } void SetDescent(float descent) { - descent_ = descent; - descent_int_ = static_cast<int>(lroundf(descent)); + float_descent_ = descent; + int_descent_ = static_cast<int>(lroundf(descent)); } - float FloatHeight() const { return ascent_ + descent_; } + float FloatHeight() const { return float_ascent_ + float_descent_; } float FloatLineGap() const { return line_gap_; } void SetLineGap(float line_gap) { line_gap_ = line_gap; } @@ -97,17 +97,17 @@ class FontMetrics { // Integer variants of certain metrics, used for HTML rendering. int Ascent(FontBaseline baseline_type = kAlphabeticBaseline) const { if (baseline_type == kAlphabeticBaseline) - return ascent_int_; + return int_ascent_; return IntAscentInternal(baseline_type); } int Descent(FontBaseline baseline_type = kAlphabeticBaseline) const { if (baseline_type == kAlphabeticBaseline) - return descent_int_; + return int_descent_; return Height() - IntAscentInternal(baseline_type); } - int Height() const { return ascent_int_ + descent_int_; } + int Height() const { return int_ascent_ + int_descent_; } int LineGap() const { return static_cast<int>(lroundf(line_gap_)); } int LineSpacing() const { return static_cast<int>(lroundf(line_spacing_)); } @@ -187,10 +187,10 @@ class FontMetrics { void Reset() { units_per_em_ = kGDefaultUnitsPerEm; - ascent_ = 0; - descent_ = 0; - ascent_int_ = 0; - descent_int_ = 0; + float_ascent_ = 0; + float_descent_ = 0; + int_ascent_ = 0; + int_descent_ = 0; line_gap_ = 0; line_spacing_ = 0; x_height_ = 0; @@ -203,16 +203,16 @@ class FontMetrics { PLATFORM_EXPORT int IntAscentInternal(FontBaseline baseline_type) const; unsigned units_per_em_; - float ascent_; - float descent_; + float float_ascent_; + float float_descent_; float line_gap_; float line_spacing_; float x_height_; float zero_width_; absl::optional<float> underline_thickness_ = absl::nullopt; absl::optional<float> underline_position_ = absl::nullopt; - int ascent_int_; - int descent_int_; + int int_ascent_; + int int_descent_; bool has_x_height_; bool has_zero_width_; }; From 20a70a7d8ca4da6dc8e4e35be0b154c7916212f7 Mon Sep 17 00:00:00 2001 From: Ben Mason <benmason@chromium.org> Date: Tue, 1 Jun 2021 10:24:25 +0000 Subject: [PATCH 32/81] Updating XTBs based on .GRDs from branch main Change-Id: Ia10d2f0317ace10ba8a5cdffaedc58fd8c90d396 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929202 Auto-Submit: Ben Mason <benmason@chromium.org> Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887909} --- ash/strings/ash_strings_bn.xtb | 1 + ash/strings/ash_strings_gu.xtb | 1 + ash/strings/ash_strings_kn.xtb | 1 + ash/strings/ash_strings_mr.xtb | 1 + ash/strings/ash_strings_ne.xtb | 1 + ash/strings/ash_strings_ur.xtb | 1 + .../android_keyboard_accessory_strings_te.xtb | 2 +- chrome/app/resources/chromium_strings_is.xtb | 2 +- .../app/resources/generated_resources_be.xtb | 2 +- .../app/resources/generated_resources_bn.xtb | 4 +++ .../app/resources/generated_resources_es.xtb | 20 +++++++------- .../app/resources/generated_resources_eu.xtb | 6 ++--- .../app/resources/generated_resources_gu.xtb | 4 +++ .../app/resources/generated_resources_is.xtb | 4 +-- .../app/resources/generated_resources_kn.xtb | 4 +++ .../app/resources/generated_resources_ky.xtb | 2 +- .../app/resources/generated_resources_mr.xtb | 4 +++ .../app/resources/generated_resources_ne.xtb | 6 ++++- .../resources/generated_resources_sr-Latn.xtb | 10 +++---- .../app/resources/generated_resources_sr.xtb | 10 +++---- .../app/resources/generated_resources_ta.xtb | 4 +-- .../app/resources/generated_resources_tr.xtb | 2 +- .../app/resources/generated_resources_ur.xtb | 4 +++ .../app/resources/generated_resources_vi.xtb | 2 +- .../resources/google_chrome_strings_is.xtb | 2 +- .../strings/accessibility_strings_tr.xtb | 26 +++++++++---------- .../android_chrome_strings_am.xtb | 1 + .../android_chrome_strings_ar.xtb | 1 + .../android_chrome_strings_as.xtb | 1 + .../android_chrome_strings_az.xtb | 1 + .../android_chrome_strings_be.xtb | 1 + .../android_chrome_strings_bg.xtb | 1 + .../android_chrome_strings_bs.xtb | 1 + .../android_chrome_strings_ca.xtb | 3 ++- .../android_chrome_strings_cs.xtb | 1 + .../android_chrome_strings_da.xtb | 1 + .../android_chrome_strings_el.xtb | 1 + .../android_chrome_strings_es-419.xtb | 1 + .../android_chrome_strings_es.xtb | 1 + .../android_chrome_strings_et.xtb | 1 + .../android_chrome_strings_eu.xtb | 1 + .../android_chrome_strings_fa.xtb | 1 + .../android_chrome_strings_fi.xtb | 1 + .../android_chrome_strings_fr-CA.xtb | 1 + .../android_chrome_strings_fr.xtb | 1 + .../android_chrome_strings_gl.xtb | 1 + .../android_chrome_strings_hi.xtb | 1 + .../android_chrome_strings_hr.xtb | 1 + .../android_chrome_strings_hu.xtb | 1 + .../android_chrome_strings_hy.xtb | 1 + .../android_chrome_strings_id.xtb | 1 + .../android_chrome_strings_is.xtb | 1 + .../android_chrome_strings_it.xtb | 1 + .../android_chrome_strings_iw.xtb | 1 + .../android_chrome_strings_ka.xtb | 1 + .../android_chrome_strings_kk.xtb | 1 + .../android_chrome_strings_km.xtb | 1 + .../android_chrome_strings_kn.xtb | 3 ++- .../android_chrome_strings_ko.xtb | 1 + .../android_chrome_strings_ky.xtb | 1 + .../android_chrome_strings_lo.xtb | 1 + .../android_chrome_strings_lt.xtb | 1 + .../android_chrome_strings_lv.xtb | 1 + .../android_chrome_strings_mk.xtb | 1 + .../android_chrome_strings_mr.xtb | 1 + .../android_chrome_strings_ms.xtb | 1 + .../android_chrome_strings_my.xtb | 1 + .../android_chrome_strings_nl.xtb | 1 + .../android_chrome_strings_no.xtb | 1 + .../android_chrome_strings_pl.xtb | 1 + .../android_chrome_strings_pt-BR.xtb | 1 + .../android_chrome_strings_pt-PT.xtb | 1 + .../android_chrome_strings_ro.xtb | 1 + .../android_chrome_strings_ru.xtb | 1 + .../android_chrome_strings_sk.xtb | 1 + .../android_chrome_strings_sl.xtb | 1 + .../android_chrome_strings_sr-Latn.xtb | 1 + .../android_chrome_strings_sr.xtb | 1 + .../android_chrome_strings_sv.xtb | 1 + .../android_chrome_strings_sw.xtb | 1 + .../android_chrome_strings_th.xtb | 1 + .../android_chrome_strings_tr.xtb | 1 + .../android_chrome_strings_uk.xtb | 1 + .../android_chrome_strings_vi.xtb | 1 + .../android_chrome_strings_zh-CN.xtb | 1 + .../android_chrome_strings_zh-TW.xtb | 1 + .../android_chrome_strings_zu.xtb | 1 + .../gaiacp/strings/gaia_resources_ru.xtb | 2 +- .../translations/browser_ui_strings_te.xtb | 2 +- .../resources/policy_templates_es-419.xtb | 4 +++ .../policy/resources/policy_templates_es.xtb | 4 +++ .../policy/resources/policy_templates_fr.xtb | 4 +++ .../policy/resources/policy_templates_id.xtb | 4 +++ .../policy/resources/policy_templates_it.xtb | 4 +++ .../policy/resources/policy_templates_ko.xtb | 4 +++ .../policy/resources/policy_templates_nl.xtb | 4 +++ .../resources/policy_templates_pt-BR.xtb | 4 +++ .../policy/resources/policy_templates_ru.xtb | 4 +++ .../policy/resources/policy_templates_th.xtb | 4 +++ .../policy/resources/policy_templates_tr.xtb | 4 +++ .../policy/resources/policy_templates_uk.xtb | 4 +++ .../policy/resources/policy_templates_vi.xtb | 16 +++++++----- .../resources/policy_templates_zh-CN.xtb | 4 +++ .../resources/policy_templates_zh-TW.xtb | 3 +++ components/strings/components_strings_am.xtb | 5 ++++ components/strings/components_strings_ar.xtb | 5 ++++ components/strings/components_strings_as.xtb | 5 ++++ components/strings/components_strings_az.xtb | 5 ++++ components/strings/components_strings_be.xtb | 5 ++++ components/strings/components_strings_bg.xtb | 5 ++++ components/strings/components_strings_bs.xtb | 5 ++++ components/strings/components_strings_ca.xtb | 5 ++++ components/strings/components_strings_cs.xtb | 5 ++++ components/strings/components_strings_da.xtb | 5 ++++ components/strings/components_strings_el.xtb | 5 ++++ .../strings/components_strings_es-419.xtb | 5 ++++ components/strings/components_strings_es.xtb | 5 ++++ components/strings/components_strings_et.xtb | 5 ++++ components/strings/components_strings_eu.xtb | 5 ++++ components/strings/components_strings_fa.xtb | 5 ++++ components/strings/components_strings_fi.xtb | 5 ++++ .../strings/components_strings_fr-CA.xtb | 5 ++++ components/strings/components_strings_fr.xtb | 5 ++++ components/strings/components_strings_gl.xtb | 5 ++++ components/strings/components_strings_hi.xtb | 5 ++++ components/strings/components_strings_hr.xtb | 5 ++++ components/strings/components_strings_hu.xtb | 5 ++++ components/strings/components_strings_hy.xtb | 5 ++++ components/strings/components_strings_id.xtb | 5 ++++ components/strings/components_strings_is.xtb | 5 ++++ components/strings/components_strings_it.xtb | 5 ++++ components/strings/components_strings_iw.xtb | 5 ++++ components/strings/components_strings_ja.xtb | 2 +- components/strings/components_strings_ka.xtb | 5 ++++ components/strings/components_strings_kk.xtb | 5 ++++ components/strings/components_strings_km.xtb | 5 ++++ components/strings/components_strings_kn.xtb | 5 ++++ components/strings/components_strings_ko.xtb | 5 ++++ components/strings/components_strings_ky.xtb | 5 ++++ components/strings/components_strings_lo.xtb | 5 ++++ components/strings/components_strings_lt.xtb | 5 ++++ components/strings/components_strings_lv.xtb | 5 ++++ components/strings/components_strings_mk.xtb | 5 ++++ components/strings/components_strings_mr.xtb | 5 ++++ components/strings/components_strings_ms.xtb | 5 ++++ components/strings/components_strings_my.xtb | 5 ++++ components/strings/components_strings_nl.xtb | 5 ++++ components/strings/components_strings_no.xtb | 5 ++++ components/strings/components_strings_pl.xtb | 5 ++++ .../strings/components_strings_pt-BR.xtb | 5 ++++ .../strings/components_strings_pt-PT.xtb | 5 ++++ components/strings/components_strings_ro.xtb | 5 ++++ components/strings/components_strings_ru.xtb | 5 ++++ components/strings/components_strings_sk.xtb | 5 ++++ components/strings/components_strings_sl.xtb | 5 ++++ .../strings/components_strings_sr-Latn.xtb | 5 ++++ components/strings/components_strings_sr.xtb | 5 ++++ components/strings/components_strings_sv.xtb | 5 ++++ components/strings/components_strings_sw.xtb | 5 ++++ components/strings/components_strings_te.xtb | 2 +- components/strings/components_strings_th.xtb | 5 ++++ components/strings/components_strings_tr.xtb | 5 ++++ components/strings/components_strings_uk.xtb | 5 ++++ components/strings/components_strings_vi.xtb | 7 ++++- .../strings/components_strings_zh-CN.xtb | 5 ++++ .../strings/components_strings_zh-TW.xtb | 5 ++++ components/strings/components_strings_zu.xtb | 5 ++++ extensions/strings/extensions_strings_eu.xtb | 2 +- .../app/strings/resources/ios_strings_am.xtb | 2 ++ .../app/strings/resources/ios_strings_ar.xtb | 2 ++ .../app/strings/resources/ios_strings_as.xtb | 2 ++ .../app/strings/resources/ios_strings_az.xtb | 2 ++ .../app/strings/resources/ios_strings_be.xtb | 2 ++ .../app/strings/resources/ios_strings_bg.xtb | 2 ++ .../app/strings/resources/ios_strings_bs.xtb | 2 ++ .../app/strings/resources/ios_strings_ca.xtb | 2 ++ .../app/strings/resources/ios_strings_cs.xtb | 2 ++ .../app/strings/resources/ios_strings_da.xtb | 2 ++ .../app/strings/resources/ios_strings_el.xtb | 2 ++ .../strings/resources/ios_strings_es-419.xtb | 2 ++ .../app/strings/resources/ios_strings_es.xtb | 2 ++ .../app/strings/resources/ios_strings_et.xtb | 2 ++ .../app/strings/resources/ios_strings_eu.xtb | 2 ++ .../app/strings/resources/ios_strings_fa.xtb | 2 ++ .../app/strings/resources/ios_strings_fi.xtb | 2 ++ .../strings/resources/ios_strings_fr-CA.xtb | 2 ++ .../app/strings/resources/ios_strings_fr.xtb | 2 ++ .../app/strings/resources/ios_strings_gl.xtb | 2 ++ .../app/strings/resources/ios_strings_hi.xtb | 2 ++ .../app/strings/resources/ios_strings_hr.xtb | 2 ++ .../app/strings/resources/ios_strings_hu.xtb | 2 ++ .../app/strings/resources/ios_strings_hy.xtb | 2 ++ .../app/strings/resources/ios_strings_id.xtb | 2 ++ .../app/strings/resources/ios_strings_is.xtb | 2 ++ .../app/strings/resources/ios_strings_it.xtb | 2 ++ .../app/strings/resources/ios_strings_iw.xtb | 2 ++ .../app/strings/resources/ios_strings_ka.xtb | 2 ++ .../app/strings/resources/ios_strings_kk.xtb | 2 ++ .../app/strings/resources/ios_strings_km.xtb | 2 ++ .../app/strings/resources/ios_strings_kn.xtb | 2 ++ .../app/strings/resources/ios_strings_ko.xtb | 2 ++ .../app/strings/resources/ios_strings_ky.xtb | 2 ++ .../app/strings/resources/ios_strings_lo.xtb | 2 ++ .../app/strings/resources/ios_strings_lt.xtb | 2 ++ .../app/strings/resources/ios_strings_lv.xtb | 2 ++ .../app/strings/resources/ios_strings_mk.xtb | 2 ++ .../app/strings/resources/ios_strings_mr.xtb | 2 ++ .../app/strings/resources/ios_strings_ms.xtb | 2 ++ .../app/strings/resources/ios_strings_my.xtb | 2 ++ .../app/strings/resources/ios_strings_nl.xtb | 2 ++ .../app/strings/resources/ios_strings_no.xtb | 2 ++ .../app/strings/resources/ios_strings_pl.xtb | 2 ++ .../strings/resources/ios_strings_pt-BR.xtb | 2 ++ .../strings/resources/ios_strings_pt-PT.xtb | 2 ++ .../app/strings/resources/ios_strings_ro.xtb | 2 ++ .../app/strings/resources/ios_strings_ru.xtb | 2 ++ .../app/strings/resources/ios_strings_sk.xtb | 2 ++ .../app/strings/resources/ios_strings_sl.xtb | 2 ++ .../strings/resources/ios_strings_sr-Latn.xtb | 2 ++ .../app/strings/resources/ios_strings_sr.xtb | 2 ++ .../app/strings/resources/ios_strings_sv.xtb | 2 ++ .../app/strings/resources/ios_strings_sw.xtb | 2 ++ .../app/strings/resources/ios_strings_te.xtb | 2 +- .../app/strings/resources/ios_strings_th.xtb | 2 ++ .../app/strings/resources/ios_strings_tr.xtb | 2 ++ .../app/strings/resources/ios_strings_uk.xtb | 2 ++ .../app/strings/resources/ios_strings_vi.xtb | 2 ++ .../strings/resources/ios_strings_zh-CN.xtb | 2 ++ .../strings/resources/ios_strings_zh-TW.xtb | 2 ++ .../app/strings/resources/ios_strings_zu.xtb | 2 ++ remoting/resources/remoting_strings_eu.xtb | 2 +- 231 files changed, 641 insertions(+), 64 deletions(-) diff --git a/ash/strings/ash_strings_bn.xtb b/ash/strings/ash_strings_bn.xtb index 7d6a697af2fe8d..8839d8bbdb7cc5 100644 --- a/ash/strings/ash_strings_bn.xtb +++ b/ash/strings/ash_strings_bn.xtb @@ -280,6 +280,7 @@ <translation id="3207953481422525583">ব্যবহারকারী সংক্রান্ত সেটিংস</translation> <translation id="3217205077783620295">ভলিউম চালু আছে, টগল করলে অডিও মিউট হয়ে যাবে।</translation> <translation id="3226991577105957773">+ আরও <ph name="COUNT" />টি</translation> +<translation id="324366796737464147">অপ্রয়োজনীয় আওয়াজের বাতিলকরণ</translation> <translation id="3249513730522716925">Window <ph name="WINDOW_TITLE" /> ডেস্ক <ph name="ACTIVE_DESK" /> থেকে ডেস্ক <ph name="TARGET_DESK" />-এ সরানো হয়েছে</translation> <translation id="3255483164551725916">আপনি কি করতে পারেন?</translation> <translation id="3269597722229482060">ডানদিকের বোতামে ক্লিক করুন</translation> diff --git a/ash/strings/ash_strings_gu.xtb b/ash/strings/ash_strings_gu.xtb index 422bd1cfddb78d..ef6290a7a1039c 100644 --- a/ash/strings/ash_strings_gu.xtb +++ b/ash/strings/ash_strings_gu.xtb @@ -280,6 +280,7 @@ <translation id="3207953481422525583">વપરાશકર્તા સેટિંગ</translation> <translation id="3217205077783620295">વૉલ્યૂમ ચાલુ છે, ટૉગલ કરવાથી ઑડિયો મ્યૂટ થશે.</translation> <translation id="3226991577105957773">+ વધુ <ph name="COUNT" /></translation> +<translation id="324366796737464147">અવાજ રદ્દીકરણ</translation> <translation id="3249513730522716925">વિડો <ph name="WINDOW_TITLE" />ને ડેસ્ક <ph name="ACTIVE_DESK" />માંથી ડેસ્ક <ph name="TARGET_DESK" />માં ખસેડી</translation> <translation id="3255483164551725916">તમે શું કરી શકો?</translation> <translation id="3269597722229482060">રાઇટ ક્લિક કરો</translation> diff --git a/ash/strings/ash_strings_kn.xtb b/ash/strings/ash_strings_kn.xtb index 9ac989690d8fdf..93ce5266fec942 100644 --- a/ash/strings/ash_strings_kn.xtb +++ b/ash/strings/ash_strings_kn.xtb @@ -280,6 +280,7 @@ <translation id="3207953481422525583">ಬಳಕೆದಾರರ ಸೆಟ್ಟಿಂಗ್ಗಳು</translation> <translation id="3217205077783620295">ವಾಲ್ಯೂಮ್ ಆನ್ ಆಗಿದೆ, ಟಾಗಲ್ ಮಾಡುವುದರಿಂದ ಆಡಿಯೊ ಮ್ಯೂಟ್ ಆಗುತ್ತದೆ.</translation> <translation id="3226991577105957773">+<ph name="COUNT" /> ಹೆಚ್ಚು</translation> +<translation id="324366796737464147">ಗದ್ದಲ ನಿವಾರಣೆ</translation> <translation id="3249513730522716925"><ph name="WINDOW_TITLE" /> ವಿಂಡೋವನ್ನು <ph name="ACTIVE_DESK" /> ಡೆಸ್ಕ್ನಿಂದ<ph name="TARGET_DESK" /> ಡೆಸ್ಕ್ಗೆ ಸರಿಸಲಾಗಿದೆ</translation> <translation id="3255483164551725916">ನೀವೇನು ಮಾಡಬಲ್ಲಿರಿ?</translation> <translation id="3269597722229482060">ಬಲ-ಕ್ಲಿಕ್</translation> diff --git a/ash/strings/ash_strings_mr.xtb b/ash/strings/ash_strings_mr.xtb index e9a660c0ec9bbe..b5da30ec886297 100644 --- a/ash/strings/ash_strings_mr.xtb +++ b/ash/strings/ash_strings_mr.xtb @@ -280,6 +280,7 @@ <translation id="3207953481422525583">वापरकर्ता सेटिंग्ज</translation> <translation id="3217205077783620295">व्हॉल्यूम सुरू आहे, टॉगल केल्याने ऑडिओ म्यूट होईल.</translation> <translation id="3226991577105957773">आणखी +<ph name="COUNT" /></translation> +<translation id="324366796737464147">नॉइझ कॅंसलेशन</translation> <translation id="3249513730522716925">विंडो <ph name="WINDOW_TITLE" /> डेस्क <ph name="ACTIVE_DESK" /> वरून डेस्क <ph name="TARGET_DESK" /> वर हलवली</translation> <translation id="3255483164551725916">तुला काय करता येते?</translation> <translation id="3269597722229482060">राइट क्लिक</translation> diff --git a/ash/strings/ash_strings_ne.xtb b/ash/strings/ash_strings_ne.xtb index ea166eb28ac544..f88f7623b2407b 100644 --- a/ash/strings/ash_strings_ne.xtb +++ b/ash/strings/ash_strings_ne.xtb @@ -274,6 +274,7 @@ <translation id="3207953481422525583">प्रयोगकर्ताका सेटिङहरू</translation> <translation id="3217205077783620295">भोल्युम सक्रिय छ, टगल गर्नुले अडियो म्युट गर्ने छ।</translation> <translation id="3226991577105957773">+<ph name="COUNT" /> थप</translation> +<translation id="324366796737464147">ध्वनि खारेजी</translation> <translation id="3249513730522716925">विन्डो सारेर <ph name="WINDOW_TITLE" /> डेस्क <ph name="ACTIVE_DESK" /> बाट <ph name="TARGET_DESK" /> डेस्कमा पुर्याइयो</translation> <translation id="3255483164551725916">तपाईं के गर्न सक्नुहुन्छ?</translation> <translation id="3269597722229482060">दायाँ क्लिक गर्नुहोस्</translation> diff --git a/ash/strings/ash_strings_ur.xtb b/ash/strings/ash_strings_ur.xtb index a3c92d8b4a9675..59bee13b720088 100644 --- a/ash/strings/ash_strings_ur.xtb +++ b/ash/strings/ash_strings_ur.xtb @@ -280,6 +280,7 @@ <translation id="3207953481422525583">صارف کی ترتیبات</translation> <translation id="3217205077783620295">والیوم آن ہے۔ ٹوگل کرنے سے آڈیو خاموش ہو جائے گی۔</translation> <translation id="3226991577105957773"><ph name="COUNT" />+ مزید</translation> +<translation id="324366796737464147">شور کو کم کرنا</translation> <translation id="3249513730522716925"><ph name="WINDOW_TITLE" /> ونڈو کو <ph name="ACTIVE_DESK" /> ڈیسک سے <ph name="TARGET_DESK" /> ڈیسک میں منتقل کر دیا گیا ہے</translation> <translation id="3255483164551725916">آپ کیا کر سکتی ہیں؟</translation> <translation id="3269597722229482060">دائیں طرف کلک کریں</translation> diff --git a/chrome/android/features/keyboard_accessory/internal/java/strings/translations/android_keyboard_accessory_strings_te.xtb b/chrome/android/features/keyboard_accessory/internal/java/strings/translations/android_keyboard_accessory_strings_te.xtb index b33bea195711b3..e1dae066d83c08 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/strings/translations/android_keyboard_accessory_strings_te.xtb +++ b/chrome/android/features/keyboard_accessory/internal/java/strings/translations/android_keyboard_accessory_strings_te.xtb @@ -7,7 +7,7 @@ <translation id="207576718733492531">'టచ్ చేసి నింపాల్సిన ఆధారాల జాబితా' మూసివేయబడింది.</translation> <translation id="2610239185026711824">పాస్వర్డ్ని సూచించు</translation> <translation id="2803478378562657435">సేవ్ చేసిన పాస్వర్డ్లు మరియు పాస్వర్డ్ ఎంపికలను చూపిస్తోంది</translation> -<translation id="2903493209154104877">చిరునామాలు</translation> +<translation id="2903493209154104877">అడ్రస్లు</translation> <translation id="3399357656427473483">'టచ్ చేసి నింపాల్సిన ఆధారాల జాబితా'.</translation> <translation id="4660011489602794167">కీబోర్డ్ను చూపు</translation> <translation id="4694050069269396220">మీకు <ph name="ORIGIN" /> మీద నమ్మకం ఉంటే, ఇదివరకే సేవ్ చేసిన మీ పాస్వర్డ్ను మీరు మరొక సైట్కు ఉపయోగించవచ్చు.</translation> diff --git a/chrome/app/resources/chromium_strings_is.xtb b/chrome/app/resources/chromium_strings_is.xtb index d4a6286fe5960f..953b42304a0d9b 100644 --- a/chrome/app/resources/chromium_strings_is.xtb +++ b/chrome/app/resources/chromium_strings_is.xtb @@ -270,7 +270,7 @@ Chromium getur ekki endurheimt stillingarnar þínar.</translation> <translation id="8907580949721785412">Chromium er að reyna að sýna aðgangsorð. Sláðu inn Windows-aðgangsorðið þitt til að heimila þetta.</translation> <translation id="8941642502866065432">Ekki var hægt að uppfæra Chromium</translation> <translation id="8974095189086268230">Chromium OS á tilvist sína að þakka öðrum <ph name="BEGIN_LINK_CROS_OSS" />opnum hugbúnaði<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="8986207147630327271">Þú ert að bæta vinnuprófíl við þennan vafra og veita stjórnanda þínum leyfi til að stjórna vinnuprófílnum eingöngu.</translation> +<translation id="8986207147630327271">Þú ert að bæta vinnusniði við þennan vafra og veita stjórnanda þínum leyfi til að stjórna vinnusniðinu eingöngu.</translation> <translation id="9019929317751753759">Til að gera Chromium öruggara höfum við slökkt á eftirfarandi viðbót sem ekki er á skrá hjá <ph name="IDS_EXTENSION_WEB_STORE_TITLE" /> og kann að hafa verið bætt við án þinnar vitneskju.</translation> <translation id="9047197236183657400">Flytja reikning á nýjan Chromium prófíl?</translation> <translation id="9089354809943900324">Chromium er úrelt</translation> diff --git a/chrome/app/resources/generated_resources_be.xtb b/chrome/app/resources/generated_resources_be.xtb index 6e6c62245fa39b..1105d60f9c3f99 100644 --- a/chrome/app/resources/generated_resources_be.xtb +++ b/chrome/app/resources/generated_resources_be.xtb @@ -1028,7 +1028,7 @@ <translation id="2082187087049518845">Дадаць укладку ў групу</translation> <translation id="2082510809738716738">Выберыце колер тэмы</translation> <translation id="208586643495776849">Паўтарыце спробу</translation> -<translation id="208634871997892083">Заўсёды ўключаны VPN</translation> +<translation id="208634871997892083">Заўсёды ўключаная VPN</translation> <translation id="2087822576218954668">Друк: <ph name="PRINT_NAME" /></translation> <translation id="2088690981887365033">Сетка VPN</translation> <translation id="208928984520943006">Каб у любы момант перайсці на галоўны экран, правядзіце знізу ўверх.</translation> diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb index e8834468532862..47f43951bfa5ca 100644 --- a/chrome/app/resources/generated_resources_bn.xtb +++ b/chrome/app/resources/generated_resources_bn.xtb @@ -2582,6 +2582,7 @@ <translation id="3742666961763734085">এই নামের কোনও প্রতিষ্ঠানের ইউনিট খুঁজে পাওয়া যাচ্ছে না। অনুগ্রহ করে আবার চেষ্টা করুন।</translation> <translation id="3744111561329211289">পটভূমি সিঙ্ক</translation> <translation id="3747077776423672805">অ্যাপগুলি সরাতে, সেটিংস > Google Play স্টোর > Android অভিরুচি ম্যানেজ করুন > অ্যাপ বা অ্যাপ্লিকেশন ম্যানেজার বিকল্পে যান। এরপর যে অ্যাপটিকে আনইনস্টল করতে চান তাতে ট্যাপ করুন (অ্যাপটি খোঁজার জন্য আপনাকে ডানদিক বা বাঁদিকে সোয়াইপ করতে হতে পারে)। এরপর আনইনস্টল করুন বা বন্ধ করুন বিকল্পে ট্যাপ করুন।</translation> +<translation id="3747220812138541072">টাইপ করার সাথে সাথে প্রদর্শিত হবে এমন ইনলাইন লেখার সাজেশন দেখানো হবে</translation> <translation id="3748706263662799310">একটি বাগ রিপোর্ট করুন</translation> <translation id="3752582316358263300">ঠিক আছে...</translation> <translation id="3753033997400164841">একবার সেভ করুন। সব জায়গায় ব্যবহার করুন</translation> @@ -3270,6 +3271,7 @@ <translation id="4510614391273086606">Linux ফাইল ও অ্যাপগুলিকে, ব্যাক-আপ করার সমকালীন অবস্থায় ফিরিয়ে নিয়ে যাওয়া হচ্ছে।</translation> <translation id="451102079304155829">কার্ট</translation> <translation id="4513275008300099962">'উইন্ডো কন্ট্রোলস ওভারলে' বন্ধ করুন</translation> +<translation id="4513872120116766993">লেখার সাজেশন</translation> <translation id="4513946894732546136">প্রতিক্রিয়া</translation> <translation id="451407183922382411"><ph name="COMPANY_NAME" /> এর দ্বারা চালিত</translation> <translation id="4514610446763173167">ভিডিও চালাতে বা থামানোর জন্য টগল করুন</translation> @@ -4434,6 +4436,7 @@ <translation id="5826395379250998812"><ph name="DEVICE_TYPE" />-কে আপনার ফোনের সাথে কানেক্ট করুন। <ph name="LINK_BEGIN" />আরও জানুন<ph name="LINK_END" /></translation> <translation id="5826993284769733527">অর্ধ-স্বচ্ছ</translation> <translation id="5827266244928330802">Safari</translation> +<translation id="5827733057563115968">পরবর্তী শব্দ সনাক্তকরণ</translation> <translation id="5828545842856466741">প্রোফাইল যোগ করুন...</translation> <translation id="5828633471261496623">মুদ্রন হচ্ছে...</translation> <translation id="5830720307094128296">&পৃষ্ঠা সেভ করুন...</translation> @@ -6303,6 +6306,7 @@ <translation id="78526636422538552">আরও Google অ্যাকাউন্ট যোগ করার সুবিধা এখন উপলভ্য নেই</translation> <translation id="7853747251428735">আরও সর&ঞ্জাম</translation> <translation id="7855678561139483478">ট্যাবটি নতুন উইন্ডোতে খুলুন</translation> +<translation id="7857093393627376423">টেক্সট সংক্রান্ত সাজেশন</translation> <translation id="7857117644404132472">ব্যতিক্রম যোগ করুন</translation> <translation id="7857949311770343000">আপনি কি এই পৃষ্ঠাটিকে নতুন ট্যাব পৃষ্ঠা হিসাবে আশা করছিলেন?</translation> <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation> diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb index f90a0144965a0f..f32374af363225 100644 --- a/chrome/app/resources/generated_resources_es.xtb +++ b/chrome/app/resources/generated_resources_es.xtb @@ -200,7 +200,7 @@ <translation id="1203942045716040624">SharedWorker: <ph name="SCRIPT_URL" /></translation> <translation id="1209796539517632982">Servidores de nombres automáticos</translation> <translation id="1211769675100312947">Tú gestionas los accesos directos</translation> -<translation id="1213254615020057352">Envía datos de uso y diagnóstico. Contribuye a mejorar la experiencia de Android de tu hijo enviando automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos no se usarán para identificar a tu hijo, sino para aumentar la estabilidad de las aplicaciones y del sistema, y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y los partners de Google, como los desarrolladores de Android. El propietario ha aplicado este ajuste. El propietario puede elegir si se envían a Google datos de uso y diagnóstico de este dispositivo. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en la cuenta de Google de tu hijo.</translation> +<translation id="1213254615020057352">Envía datos de uso y diagnóstico. Contribuye a mejorar la experiencia de Android de tu hijo enviando automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos no se usarán para identificar a tu hijo, sino para aumentar la estabilidad de las aplicaciones y del sistema, y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y a los partners de Google, como los desarrolladores de Android. El propietario ha aplicado este ajuste. El propietario puede elegir si se envían a Google datos de uso y diagnóstico de este dispositivo. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en la cuenta de Google de tu hijo.</translation> <translation id="121384500095351701">Este archivo no se puede descargar de forma segura</translation> <translation id="1215411991991485844">Nueva aplicación en segundo plano añadida</translation> <translation id="1216542092748365687">Quitar huella digital</translation> @@ -3712,7 +3712,7 @@ Puedes gestionar la configuración de esta cuenta instalando la aplicación Fami <translation id="5017643436812738274">Puedes desplazarte por las páginas con un cursor de texto. Pulsa Ctrl + tecla de búsqueda + 7 para desactivar esta función.</translation> <translation id="5017828934289857214">Recordar más tarde</translation> <translation id="5018207570537526145">Abrir sitio web de la extensión</translation> -<translation id="5018526990965779848">Envía datos de uso y diagnóstico. Contribuye a mejorar tu experiencia de Android enviando automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos servirán para aumentar la estabilidad de las aplicaciones y del sistema y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y los partners de Google, como los desarrolladores de Android. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en tu cuenta de Google.</translation> +<translation id="5018526990965779848">Envía datos de uso y diagnóstico. Contribuye a mejorar tu experiencia de Android enviando automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos servirán para aumentar la estabilidad de las aplicaciones y del sistema y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y a los partners de Google, como los desarrolladores de Android. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en tu cuenta de Google.</translation> <translation id="5021750053540820849">Aún no se ha actualizado</translation> <translation id="5026492829171796515">Inicia sesión para añadir una cuenta de Google</translation> <translation id="5026806129670917316">Activar Wi‑Fi</translation> @@ -3865,7 +3865,7 @@ Puedes gestionar la configuración de esta cuenta instalando la aplicación Fami <translation id="5192062846343383368">Abre la aplicación Family Link para ver la configuración de supervisión</translation> <translation id="5193988420012215838">Se ha copiado al portapapeles</translation> <translation id="5197255632782567636">Internet</translation> -<translation id="5198430103906431024">Envía datos de uso y diagnóstico. Este dispositivo envía automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos servirán para aumentar la estabilidad de las aplicaciones y del sistema y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y los partners de Google, como los desarrolladores de Android. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en tu cuenta de Google.</translation> +<translation id="5198430103906431024">Envía datos de uso y diagnóstico. Este dispositivo envía automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos servirán para aumentar la estabilidad de las aplicaciones y del sistema y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y a los partners de Google, como los desarrolladores de Android. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en tu cuenta de Google.</translation> <translation id="5199729219167945352">Experimentos</translation> <translation id="5203920255089865054">{NUM_EXTENSIONS,plural, =1{Haz clic para ver la extensión}other{Haz clic para ver las extensiones}}</translation> <translation id="5204673965307125349">Realiza un powerwash e inténtalo de nuevo.</translation> @@ -4210,7 +4210,7 @@ Puedes gestionar la configuración de esta cuenta instalando la aplicación Fami <translation id="5583640892426849032">Tecla de retroceso</translation> <translation id="5584088138253955452">¿Quieres guardar el nombre de usuario?</translation> <translation id="5584091888252706332">Al inicio</translation> -<translation id="5584915726528712820"><ph name="BEGIN_PARAGRAPH1" />Estos datos son información general sobre tu dispositivo y cómo lo usas (como el nivel de batería, la actividad de las aplicaciones y del sistema, y los errores). Sirven para mejorar Android, y parte de los datos recogidos también ayudan a las aplicaciones y partners de Google, como los desarrolladores de Android, a mejorar sus productos y aplicaciones.<ph name="END_PARAGRAPH1" /> +<translation id="5584915726528712820"><ph name="BEGIN_PARAGRAPH1" />Estos datos incluyen información general sobre tu dispositivo y sobre cómo lo usas (como el nivel de batería, la actividad de las aplicaciones y del sistema, y los errores). Sirven para mejorar Android, y parte de los datos recogidos también ayudan a las aplicaciones y partners de Google, como los desarrolladores de Android, a mejorar sus productos y aplicaciones.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Si la opción se desactiva, esto no afectará a la capacidad del dispositivo de enviar la información necesaria para recibir servicios esenciales, como actualizaciones del sistema y funciones de seguridad.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />El propietario puede controlar esta función en Ajustes > Configuración avanzada > Enviar automáticamente los datos de uso y diagnóstico a Google.<ph name="END_PARAGRAPH3" /> <ph name="BEGIN_PARAGRAPH4" />Si has activado la opción Actividad en la Web y en Aplicaciones, es posible que estos datos se guarden en tu cuenta de Google. Puedes consultar tus datos, eliminarlos y cambiar la configuración de tu cuenta en la página account.google.com.<ph name="END_PARAGRAPH4" /></translation> @@ -5351,7 +5351,7 @@ Exponente público (<ph name="PUBLIC_EXPONENT_NUM_BITS" /> bits): <translation id="6847125920277401289">Libera espacio para continuar</translation> <translation id="6848388270925200958">Tienes algunas tarjetas que solo se pueden utilizar en este dispositivo</translation> <translation id="6850286078059909152">Color del texto</translation> -<translation id="6851181413209322061">Envía datos de uso y diagnóstico. Este dispositivo envía automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos no se usarán para identificar a tu hijo, sino para aumentar la estabilidad de las aplicaciones y del sistema y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y los partners de Google, como los desarrolladores de Android. El propietario ha aplicado este ajuste. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en la cuenta de Google de tu hijo.</translation> +<translation id="6851181413209322061">Envía datos de uso y diagnóstico. Este dispositivo envía automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos no se usarán para identificar a tu hijo, sino para aumentar la estabilidad de las aplicaciones y del sistema y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y a los partners de Google, como los desarrolladores de Android. El propietario ha aplicado este ajuste. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en la cuenta de Google de tu hijo.</translation> <translation id="6851497530878285708">Aplicación habilitada</translation> <translation id="6853142139292753691">¿Restaurar aplicaciones y páginas de forma predeterminada?</translation> <translation id="6853388645642883916">Herramienta de actualización no disponible</translation> @@ -5672,7 +5672,7 @@ Exponente público (<ph name="PUBLIC_EXPONENT_NUM_BITS" /> bits): <translation id="7203150201908454328">Ampliado</translation> <translation id="7206693748120342859">Descargando <ph name="PLUGIN_NAME" />...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{Salir de la página}other{Salir de las páginas}}</translation> -<translation id="7207457272187520234">Envía datos de uso y diagnóstico. Este dispositivo envía automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos servirán para aumentar la estabilidad de las aplicaciones y del sistema y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y los partners de Google, como los desarrolladores de Android. El propietario ha aplicado este ajuste. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en tu cuenta de Google.</translation> +<translation id="7207457272187520234">Envía datos de uso y diagnóstico. Este dispositivo envía automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos servirán para aumentar la estabilidad de las aplicaciones y del sistema y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y a los partners de Google, como los desarrolladores de Android. El propietario ha aplicado este ajuste. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en tu cuenta de Google.</translation> <translation id="7207631048330366454">Buscar aplicaciones</translation> <translation id="7210499381659830293">Impresoras de extensiones</translation> <translation id="7211769023302873228">Pulsa "<ph name="CURRENTKEY" />" otra vez para confirmar la asignación y salir.</translation> @@ -6680,7 +6680,7 @@ Guarda tu archivo de clave en un lugar seguro, ya que lo necesitarás para crear <translation id="826511437356419340">Se ha cambiado al modo de vista general de ventanas. Desliza el dedo para desplazarte o pulsa el tabulador si estás utilizando un teclado.</translation> <translation id="8266947622852630193">Todos los métodos de introducción de texto</translation> <translation id="8267539814046467575">Añadir impresora</translation> -<translation id="8267961145111171918"><ph name="BEGIN_PARAGRAPH1" />Estos datos son información general sobre tu dispositivo y cómo lo usas (como el nivel de batería, la actividad de las aplicaciones y del sistema, y los errores). Sirven para mejorar Android, y parte de los datos recogidos también ayudan a las aplicaciones y partners de Google, como los desarrolladores de Android, a mejorar sus productos y aplicaciones.<ph name="END_PARAGRAPH1" /> +<translation id="8267961145111171918"><ph name="BEGIN_PARAGRAPH1" />Estos datos incluyen información general sobre tu dispositivo y sobre cómo lo usas (como el nivel de batería, la actividad de las aplicaciones y del sistema, y los errores). Sirven para mejorar Android, y parte de los datos recogidos también ayudan a las aplicaciones y partners de Google, como los desarrolladores de Android, a mejorar sus productos y aplicaciones.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Si la opción se desactiva, esto no afectará a la capacidad del dispositivo de enviar la información necesaria para recibir servicios esenciales, como actualizaciones del sistema y funciones de seguridad.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />El propietario puede controlar esta función en Ajustes > Configuración avanzada > Enviar automáticamente los datos de uso y diagnóstico a Google.<ph name="END_PARAGRAPH3" /> <ph name="BEGIN_PARAGRAPH4" />Si has activado la opción Actividad en la Web y en Aplicaciones, es posible que estos datos se guarden en la cuenta de Google de tu hijo. Consulta más información sobre estos ajustes y sobre cómo configurarlos en families.google.com.<ph name="END_PARAGRAPH4" /></translation> @@ -6983,7 +6983,7 @@ Pulsa un interruptor asignado para quitar la asignación.</translation> <translation id="863903787380594467">PIN incorrecto. Te quedan <ph name="RETRIES" /> intentos.</translation> <translation id="8639047128869322042">Buscando software dañino...</translation> <translation id="8639391553632924850"><ph name="INPUT_LABEL" /> (puerto)</translation> -<translation id="8639635302972078117">Envía datos de uso y diagnóstico. Este dispositivo envía automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos no se usarán para identificar a tu hijo, sino para aumentar la estabilidad de las aplicaciones y del sistema, y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y los partners de Google, como los desarrolladores de Android. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en la cuenta de Google de tu hijo.</translation> +<translation id="8639635302972078117">Envía datos de uso y diagnóstico. Este dispositivo envía automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos no se usarán para identificar a tu hijo, sino para aumentar la estabilidad de las aplicaciones y del sistema, y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y a los partners de Google, como los desarrolladores de Android. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en la cuenta de Google de tu hijo.</translation> <translation id="8642900771896232685">2 segundos</translation> <translation id="8642947597466641025">Ampliar el tamaño del texto</translation> <translation id="8643443571868262066"><ph name="FILE_NAME" /> podría ser peligroso. ¿Quieres enviarlo a Protección Avanzada de Google para que lo analice?</translation> @@ -7276,7 +7276,7 @@ Pulsa un interruptor asignado para quitar la asignación.</translation> <translation id="8929696694736010839">Solo a la sesión de incógnito actual</translation> <translation id="8930351635855238750">La nueva configuración de cookies se aplicará al volver a cargar la página</translation> <translation id="8930622219860340959">Conexión inalámbrica</translation> -<translation id="8931076093143205651">Envía datos de uso y diagnóstico. Contribuye a mejorar tu experiencia de Android enviando automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos servirán para aumentar la estabilidad de las aplicaciones y del sistema y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y los partners de Google, como los desarrolladores de Android. El propietario ha aplicado este ajuste. El propietario puede elegir si se envían a Google datos de uso y diagnóstico de este dispositivo. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en tu cuenta de Google.</translation> +<translation id="8931076093143205651">Envía datos de uso y diagnóstico. Contribuye a mejorar tu experiencia de Android enviando automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos servirán para aumentar la estabilidad de las aplicaciones y del sistema y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y a los partners de Google, como los desarrolladores de Android. El propietario ha aplicado este ajuste. El propietario puede elegir si se envían a Google datos de uso y diagnóstico de este dispositivo. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en tu cuenta de Google.</translation> <translation id="8931475688782629595">Gestionar qué sincronizas</translation> <translation id="8932654652795262306">Detalles de la conexión compartida instantánea</translation> <translation id="8932894639908691771">Opciones de accesibilidad con interruptores</translation> @@ -7510,7 +7510,7 @@ Pulsa un interruptor asignado para quitar la asignación.</translation> <translation id="9170848237812810038">&Deshacer</translation> <translation id="9170884462774788842">Otro programa de tu ordenador ha añadido un tema que puede cambiar el funcionamiento de Chrome.</translation> <translation id="917350715406657904">Has llegado al límite de tiempo de uso de <ph name="APP_NAME" /> que ha establecido tu padre o madre. Podrás usar esta aplicación mañana durante <ph name="TIME_LIMIT" />.</translation> -<translation id="9174401638287877180">Envía datos de uso y diagnóstico. Contribuye a mejorar la experiencia de Android de tu hijo enviando automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos no se usarán para identificar a tu hijo, sino para aumentar la estabilidad de las aplicaciones y del sistema, y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y los partners de Google, como los desarrolladores de Android. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en la cuenta de Google de tu hijo.</translation> +<translation id="9174401638287877180">Envía datos de uso y diagnóstico. Contribuye a mejorar la experiencia de Android de tu hijo enviando automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos no se usarán para identificar a tu hijo, sino para aumentar la estabilidad de las aplicaciones y del sistema, y realizar otras mejoras. Parte de los datos agregados también ayudarán a las aplicaciones y a los partners de Google, como los desarrolladores de Android. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en la cuenta de Google de tu hijo.</translation> <translation id="917510707618656279">Preguntar cuando un sitio web quiera acceder a los dispositivos Bluetooth</translation> <translation id="9176476835295860688">Enviar datos de uso y diagnóstico. Este dispositivo envía automáticamente a Google datos de diagnóstico, del dispositivo y del uso de las aplicaciones. Los datos servirán para aumentar la estabilidad de las aplicaciones y del sistema y realizar otras mejoras. Parte de los datos recogidos también ayudarán a las aplicaciones y los colaboradores de Google, como los desarrolladores de Android. El propietario ha aplicado este <ph name="BEGIN_LINK1" />ajuste<ph name="END_LINK1" />. Si la opción Actividad en la Web y en Aplicaciones Adicional está activada, es posible que estos datos se guarden en tu cuenta de Google. <ph name="BEGIN_LINK2" />Más información<ph name="END_LINK2" /></translation> <translation id="9176611096776448349"><ph name="WINDOW_TITLE" />: dispositivo Bluetooth conectado</translation> diff --git a/chrome/app/resources/generated_resources_eu.xtb b/chrome/app/resources/generated_resources_eu.xtb index 89569e6eada44f..3ce1c92e74f473 100644 --- a/chrome/app/resources/generated_resources_eu.xtb +++ b/chrome/app/resources/generated_resources_eu.xtb @@ -4385,7 +4385,7 @@ Haurrak ikastetxean ez badu Chromebook-ik erabiltzen, edo nahiago baduzu etxean <translation id="5781865261247219930">Bidali aginduak <ph name="EXTENSION_NAME" /> luzapenari</translation> <translation id="5782227691023083829">Itzultzen…</translation> <translation id="57838592816432529">Desaktibatu audioa</translation> -<translation id="5785583009707899920">Chrome-ren fitxategietarako tresnak</translation> +<translation id="5785583009707899920">Chrome-ren fitxategietarako zerbitzu-aplikazioak</translation> <translation id="5787146423283493983">Gakoei buruzko akordioa</translation> <translation id="5787420647064736989">Gailuaren izena</translation> <translation id="5788367137662787332">Ezin izan da muntatu <ph name="DEVICE_LABEL" /> gailuaren partizio bat edo gehiago.</translation> @@ -6331,7 +6331,7 @@ Txartel adimenduna sartuta edukitzea eskatzen du <ph name="DOMAIN" /> domeinuak. <translation id="7903345046358933331">Orri honek ez du erantzuten. Itxaron orriak erantzun arte, edo itxi ezazu.</translation> <translation id="7903742244674067440">Ziurtagiri-emaile hauek identifikatzen dituzten ziurtagiriak dituzu erregistratuta</translation> <translation id="7903859912536385558">egonkorra (probatzaile fidagarria)</translation> -<translation id="7903925330883316394">Zerbitzua: <ph name="UTILITY_TYPE" /></translation> +<translation id="7903925330883316394">Zerbitzu-aplikazioaren prozesua: <ph name="UTILITY_TYPE" /></translation> <translation id="7904094684485781019">Kontu honen administratzaileak saio-hasiera anitzerako baimenak kendu ditu.</translation> <translation id="7904526211178107182">Ezarri Linux-eko atakak sareko beste gailu batzuentzat erabilgarri.</translation> <translation id="7907837847548254634">Erakutsi puntu argi bizkor bat fokuratutako objektuan</translation> @@ -6864,7 +6864,7 @@ Gorde gakoen fitxategia leku seguru batean. Zure luzapenaren bertsio berriak sor <translation id="8492972329130824181">Ez dago erabilgarri etxeko sarea. Datu-ibiltaritzak gaituta egon behar du konektatu ahal izateko.</translation> <translation id="8493236660459102203">Mikrofonoa:</translation> <translation id="8496717697661868878">Abiarazi plugin hau</translation> -<translation id="8497219075884839166">Windows-en tresnak</translation> +<translation id="8497219075884839166">Windows-en zerbitzu-aplikazioak</translation> <translation id="8498214519255567734">Ez zaizu egingo horren nekagarria argi gutxiko inguruetan pantailari begira egotea</translation> <translation id="8498395510292172881">Jarraitu irakurtzen Chrome-n</translation> <translation id="8499083585497694743">Aktibatu mikrofonoa</translation> diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb index f2124c31b8f627..d0631b73d370f7 100644 --- a/chrome/app/resources/generated_resources_gu.xtb +++ b/chrome/app/resources/generated_resources_gu.xtb @@ -2565,6 +2565,7 @@ <translation id="3742666961763734085">તે નામવાળો કોઈ સંસ્થાકીય એકમ શોધી શકાયો નથી. કૃપા કરીને ફરી પ્રયત્ન કરો.</translation> <translation id="3744111561329211289">પૃષ્ઠભૂમિ સમન્વયન</translation> <translation id="3747077776423672805">ઍપને કાઢી નાખવા માટે, સેટિંગ > Google Play સ્ટોર > Android પસંદગીઓ મેનેજ કરો > ઍપ અથવા ઍપ્લિકેશન મેનેજર પર જાઓ. પછી તમે અનઇન્સ્ટૉલ કરવા માગો છો તે ઍપ પર ટૅપ કરો (ઍપ શોધવા માટે તમારે જમણે અથવા ડાબે સ્વાઇપ કરવું જરૂરી હોય શકે છે). પછી અનઇન્સ્ટૉલ કરો અથવા બંધ કરો પર ટૅપ કરો.</translation> +<translation id="3747220812138541072">તમે ટાઇપ કરી રહ્યાં હો ત્યારે દેખાતા ઇનલાઇન લખવાના સૂચનો બતાવો</translation> <translation id="3748706263662799310">બગની જાણ કરો</translation> <translation id="3752582316358263300">બરાબર, સમજાઇ ગયું...</translation> <translation id="3753033997400164841">એકવાર સ્ટોર કરો. ગમે ત્યાં ઉપયોગ કરો</translation> @@ -3253,6 +3254,7 @@ <translation id="4510614391273086606">Linux ફાઇલો અને ઍપને તેની બૅકઅપ લીધેલી સ્થિતિમાં રિસ્ટોર કરવામાં આવી રહ્યાં છે.</translation> <translation id="451102079304155829">કાર્ટ</translation> <translation id="4513275008300099962">વિન્ડો નિયંત્રણોનું ઓવરલે બંધ કરો</translation> +<translation id="4513872120116766993">પૂર્વાનુમાનિત લેખન</translation> <translation id="4513946894732546136">Feedback</translation> <translation id="451407183922382411"><ph name="COMPANY_NAME" /> દ્વારા સંચાલિત</translation> <translation id="4514610446763173167">વીડિઓ ચલાવવા અથવા થોભાવવા માટે તેને ટૉગલ કરો</translation> @@ -4417,6 +4419,7 @@ <translation id="5826395379250998812">તમારા <ph name="DEVICE_TYPE" />ને તમારા ફોન સાથે કનેક્ટ કરો. <ph name="LINK_BEGIN" />વધુ જાણો<ph name="LINK_END" /></translation> <translation id="5826993284769733527">અર્ધ-પારદર્શક</translation> <translation id="5827266244928330802">Safari</translation> +<translation id="5827733057563115968">આગલા શબ્દનું પૂર્વાનુમાન</translation> <translation id="5828545842856466741">પ્રોફાઇલ ઉમેરો...</translation> <translation id="5828633471261496623">છાપકામ...</translation> <translation id="5830720307094128296">પેજ આ &રીતે સાચવો...</translation> @@ -6287,6 +6290,7 @@ USB ડિવાઇસ</translation> <translation id="78526636422538552">Googleના વધુ એકાઉન્ટ ઉમેરી શકાશે નહીં</translation> <translation id="7853747251428735">વધુ સા&ધનો</translation> <translation id="7855678561139483478">ટૅબને નવી વિંડોમાં ખસેડો</translation> +<translation id="7857093393627376423">ટેક્સ્ટ સૂચનો</translation> <translation id="7857117644404132472">અપવાદ ઉમેરો</translation> <translation id="7857949311770343000">શું આ તમારી અપેક્ષા મુજબનું નવું ટેબ પૃષ્ઠ છે?</translation> <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation> diff --git a/chrome/app/resources/generated_resources_is.xtb b/chrome/app/resources/generated_resources_is.xtb index d9268c2c3cdb73..651bffc0a76910 100644 --- a/chrome/app/resources/generated_resources_is.xtb +++ b/chrome/app/resources/generated_resources_is.xtb @@ -2317,7 +2317,7 @@ Annars skaltu skrá þig út núna svo breytingarnar á þessum reikningi taki g <translation id="3462311546193741693">Skráir þig út af flestum vefsvæðum. Þú verður áfram skráð(ur) inn á Google reikninginn þinn svo hægt sé að hreinsa samstillt gögn.</translation> <translation id="3462413494201477527">Hætta við uppsetningu reiknings?</translation> <translation id="346298925039590474">Allir notendur þessa tækis hafa aðgang að þessu farsímakerfi</translation> -<translation id="3464145797867108663">Bæta við vinnuprófíl</translation> +<translation id="3464145797867108663">Bæta við vinnusniði</translation> <translation id="346431825526753">Þetta er reikningur fyrir börn sem <ph name="CUSTODIAN_EMAIL" /> stjórnar.</translation> <translation id="3468298837301810372">Merki</translation> <translation id="3468999815377931311">Android sími</translation> @@ -5243,7 +5243,7 @@ Annars skaltu skrá þig út núna svo breytingarnar á þessum reikningi taki g <translation id="6709133671862442373">Fréttir</translation> <translation id="6709357832553498500">Tengjast með <ph name="EXTENSIONNAME" /></translation> <translation id="6710213216561001401">Til baka</translation> -<translation id="6713233729292711163">Bæta við vinnuprófíl</translation> +<translation id="6713233729292711163">Bæta við vinnusniði</translation> <translation id="6715803357256707211">Villa kom upp við uppsetningu Linux-forritsins. Smelltu á tilkynninguna til að fá nánari upplýsingar.</translation> <translation id="671619610707606484">Þetta hreinsar <ph name="TOTAL_USAGE" /> af gögnum sem vefsvæði geyma</translation> <translation id="671928215901716392">Læsa skjánum</translation> diff --git a/chrome/app/resources/generated_resources_kn.xtb b/chrome/app/resources/generated_resources_kn.xtb index 1fe0489e86d5e2..551f052232f8c6 100644 --- a/chrome/app/resources/generated_resources_kn.xtb +++ b/chrome/app/resources/generated_resources_kn.xtb @@ -2575,6 +2575,7 @@ <translation id="3742666961763734085">ಆ ಹೆಸರಿನ ಸಾಂಸ್ಥಿಕ ಘಟಕವನ್ನು ಕಂಡುಹಿಡಿಯಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.</translation> <translation id="3744111561329211289">ಹಿನ್ನೆಲೆ ಸಿಂಕ್</translation> <translation id="3747077776423672805">ಆ್ಯಪ್ಗಳನ್ನು ತೆಗೆದುಹಾಕಲು, ಸೆಟ್ಟಿಂಗ್ಗಳು > Google Play ಸ್ಟೋರ್ > Android ಆದ್ಯತೆಗಳನ್ನು ನಿರ್ವಹಿಸಿ> ಆ್ಯಪ್ಗಳು ಅಥವಾ ಆ್ಯಪ್ ನಿರ್ವಾಹಕಕ್ಕೆ ಹೋಗಿ ನಂತರ ನೀವು ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಬಯಸುವ ಆ್ಯಪ್ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ (ಆ್ಯಪ್ ಹುಡುಕಲು ನಿಮಗೆ ಎಡಕ್ಕೆ ಅಥವಾ ಬಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡುವ ಅಗತ್ಯವಿರಬಹುದು). ನಂತರ ಅನ್ಇನ್ಸ್ಟಾಲ್ ಅಥವಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ.</translation> +<translation id="3747220812138541072">ನೀವು ಟೈಪ್ ಮಾಡುವಾಗ ಗೋಚರಿಸುವ ಇನ್ಲೈನ್ ಬರವಣಿಗೆಯ ಸಲಹೆಗಳನ್ನು ತೋರಿಸಿ</translation> <translation id="3748706263662799310">ಬಗ್ ವರದಿ ಮಾಡಿ</translation> <translation id="3752582316358263300">ಸರಿ...</translation> <translation id="3753033997400164841">ಒಮ್ಮೆ ಸಂಗ್ರಹಿಸಿ. ಎಲ್ಲೆಡೆ ಬಳಸಿ</translation> @@ -3263,6 +3264,7 @@ <translation id="4510614391273086606">Linux ಫೈಲ್ಗಳು ಮತ್ತು ಆ್ಯಪ್ಗಳನ್ನು, ಅವುಗಳ ಬ್ಯಾಕಪ್ ಮಾಡಲಾದ ಸ್ಥಿತಿಗೆ ಮರುಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ.</translation> <translation id="451102079304155829">ಕಾರ್ಟ್ಗಳು</translation> <translation id="4513275008300099962">ವಿಂಡೋ ನಿಯಂತ್ರಣಗಳ ಓವರ್ಲೇಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ</translation> +<translation id="4513872120116766993">ಮುನ್ಸೂಚಕ ಬರವಣಿಗೆ</translation> <translation id="4513946894732546136">Feedback</translation> <translation id="451407183922382411"><ph name="COMPANY_NAME" /> ಮೂಲಕ ಸಂಚಾಲಿತಗೊಂಡಿದೆ</translation> <translation id="4514610446763173167">ಪ್ಲೇ ಮಾಡಲು ಅಥವಾ ವಿರಾಮಗೊಳಿಸಲು ವೀಡಿಯೊವನ್ನು ಟಾಗಲ್ ಮಾಡಿ</translation> @@ -4428,6 +4430,7 @@ <translation id="5826395379250998812">ನಿಮ್ಮ <ph name="DEVICE_TYPE" /> ಅನ್ನು, ನಿಮ್ಮ ಫೋನ್ಗೆ ಸಂಪರ್ಕಿಸಿ. <ph name="LINK_BEGIN" />ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ<ph name="LINK_END" /></translation> <translation id="5826993284769733527">ಸೆಮಿ-ಟ್ರಾನ್ಸ್ಪರೆಂಟ್</translation> <translation id="5827266244928330802">Safari</translation> +<translation id="5827733057563115968">ಮುಂದಿನ ಪದದ ಮುನ್ನೋಟಗಳು</translation> <translation id="5828545842856466741">ಪ್ರೊಫೈಲ್ ಸೇರಿಸಿ...</translation> <translation id="5828633471261496623">ಮುದ್ರಿಸಲಾಗುತ್ತಿದೆ...</translation> <translation id="5830720307094128296">&ಇದರಂತೆ ಪುಟವನ್ನು ಉಳಿಸಿ...</translation> @@ -6298,6 +6301,7 @@ <translation id="78526636422538552">ಹೆಚ್ಚಿನ Google ಖಾತೆಗಳ ಸೇರಿಸುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ</translation> <translation id="7853747251428735">ಇನ್ನಷ್ಟು ಪರಿಕರ&ಗಳು</translation> <translation id="7855678561139483478">ಟ್ಯಾಬ್ ಅನ್ನು ಹೊಸ ವಿಂಡೋಗೆ ಸರಿಸಿ</translation> +<translation id="7857093393627376423">ಪಠ್ಯ ಸಲಹೆಗಳು</translation> <translation id="7857117644404132472">ವಿನಾಯಿತಿ ಸೇರಿಸು</translation> <translation id="7857949311770343000">ನೀವು ನಿರೀಕ್ಷಿಸುತ್ತಿರುವುದು ಈ ಹೊಸ ಟ್ಯಾಬ್ ಪುಟವೇ?</translation> <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation> diff --git a/chrome/app/resources/generated_resources_ky.xtb b/chrome/app/resources/generated_resources_ky.xtb index 796928e99fd2e0..a01e52af58bb10 100644 --- a/chrome/app/resources/generated_resources_ky.xtb +++ b/chrome/app/resources/generated_resources_ky.xtb @@ -1479,7 +1479,7 @@ Family Link колдонмосун түзмөгүңүзгө орнотуп, бу <translation id="2537927931785713436">Виртуалдык машинанын сүрөтү текшерилүүдө</translation> <translation id="2538084450874617176"><ph name="DEVICE_TYPE" /> түзмөгүн ким колдонуп жатат?</translation> <translation id="2538361623464451692">Шайкештирүү өчүрүлгөн</translation> -<translation id="2540449034743108469">Кеңейтүүнүн аракеттерин угуу үчүн, "Баштоо" баскычын басыңыз</translation> +<translation id="2540449034743108469">Кеңейтүүнүн аракеттерин угуу үчүн "Баштоо" баскычын басыңыз</translation> <translation id="2540651571961486573">Бир жерден ката кетти. Ката коду: <ph name="ERROR_CODE" />.</translation> <translation id="2541002089857695151">Толук экран режиминде трансляциялоо оптималдаштырылсынбы?</translation> <translation id="2541706104884128042">Жаңы уктоочу убакыт коюлду</translation> diff --git a/chrome/app/resources/generated_resources_mr.xtb b/chrome/app/resources/generated_resources_mr.xtb index 3b188695247fa6..e9753498bcf5ec 100644 --- a/chrome/app/resources/generated_resources_mr.xtb +++ b/chrome/app/resources/generated_resources_mr.xtb @@ -2581,6 +2581,7 @@ <translation id="3742666961763734085">त्या नावाचे संस्थात्मक एकक शोधू शकत नाही. कृपया पुन्हा प्रयत्न करा.</translation> <translation id="3744111561329211289">पार्श्वभूमी सिंक</translation> <translation id="3747077776423672805">ॲप्स काढून टाकण्यासाठी, सेटिंग्ज > Google Play स्टोअर > Android प्राधान्ये व्यवस्थापित करा > ॲप्स किंवा अॅप्लिकेशन व्यवस्थापक वर जा. नंतर तुम्हाला अनइंस्टॉल करायच्या असलेल्या ॲपवर टॅप करा (ॲप शोधण्यासाठी तुम्हाला कदाचित उजवीकडे किंवा डावीकडे स्वाइप करावे लागेल). यानंतर अनइंस्टॉल करा किंंवा बंद करा वर टॅप करा.</translation> +<translation id="3747220812138541072">तुम्ही टाइप करत असताना दिसणाऱ्या लिखाणाच्या इनलाइन सूचना दाखवा</translation> <translation id="3748706263662799310">एक दोष नोंदवा</translation> <translation id="3752582316358263300">ठीक आहे...</translation> <translation id="3753033997400164841">एकदा स्टोअर करा. कुठेही वापरा</translation> @@ -3268,6 +3269,7 @@ <translation id="4510614391273086606">Linux फाइल आणि ॲप्स या गोष्टी बॅकअप घेतला होता त्या स्थितीमध्ये रीस्टोअर केल्या जात आहेत.</translation> <translation id="451102079304155829">कार्ट</translation> <translation id="4513275008300099962">विंडो नियंत्रणे ओव्हरले बंद करा</translation> +<translation id="4513872120116766993">अंदाजानुसार लिखाण</translation> <translation id="4513946894732546136">Feedback</translation> <translation id="451407183922382411"><ph name="COMPANY_NAME" />ने समर्थित करा</translation> <translation id="4514610446763173167">प्ले करण्यासाठी किंवा थांबवण्यासाठी व्हिडिओ टॉगल करा</translation> @@ -4431,6 +4433,7 @@ <translation id="5826395379250998812">तुमचे <ph name="DEVICE_TYPE" /> तुमच्या फोनसह कनेक्ट करा. <ph name="LINK_BEGIN" />अधिक जाणून घ्या<ph name="LINK_END" /></translation> <translation id="5826993284769733527">अर्धपारदर्शक</translation> <translation id="5827266244928330802">Safari</translation> +<translation id="5827733057563115968">पुढील शब्दांचा अंदाज</translation> <translation id="5828545842856466741">प्रोफाइल जोडा…</translation> <translation id="5828633471261496623">प्रिंट करत आहे...</translation> <translation id="5830720307094128296">पेज या फॉरमॅटमध्ये सेव्ह करा...</translation> @@ -6300,6 +6303,7 @@ https://www.chromium.org/chromium-os/how-tos-and-troubleshooting/debugging-featu <translation id="78526636422538552">आणखी Google खाती जोडणे बंद केले आहे</translation> <translation id="7853747251428735">अधिक साध&ने</translation> <translation id="7855678561139483478">टॅब नवीन विंडोवर हलवा</translation> +<translation id="7857093393627376423">मजकुराबाबत सूचना</translation> <translation id="7857117644404132472">एक्सेप्शन जोडा</translation> <translation id="7857949311770343000">तुम्ही अपेक्षा करत होता ते हे नवीन पृष्ठ आहे?</translation> <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation> diff --git a/chrome/app/resources/generated_resources_ne.xtb b/chrome/app/resources/generated_resources_ne.xtb index deae6320960576..c71a893376437e 100644 --- a/chrome/app/resources/generated_resources_ne.xtb +++ b/chrome/app/resources/generated_resources_ne.xtb @@ -2559,6 +2559,7 @@ <translation id="3742666961763734085">त्यो नाम भएको सङ्गठनात्मक एकाइ फेला पार्न सकिएन। कृपया फेरि प्रयास गर्नुहोस्।</translation> <translation id="3744111561329211289">पृष्ठभूमिमा सिंक गर्ने सुविधा</translation> <translation id="3747077776423672805">एप हटाउन, सेटिङहरू > Google Play स्टोर > Android का प्राथमिकताहरू व्यवस्थापन गर्नुहोस् > एपहरू वा एप प्रबन्धक नामक विकल्पमा जानुहोस्। त्यसपछि आफूले स्थापना रद्द गर्न चाहेको एपमा ट्याप गर्नुहोस् (उक्त एप फेला पार्न तपाईंले दायाँ वा बायाँतिर स्वाइप गर्नु पर्ने हुन सक्छ)। त्यसपछि स्थापना रद्द गर्नुहोस् वा असक्षम पार्नुहोस् नामक बटनमा ट्याप गर्नुहोस्।</translation> +<translation id="3747220812138541072">मैले टाइप गर्दै जाँदा लेखनसम्बन्धी इनलाइन सुझावहरू देखाइयोस्</translation> <translation id="3748706263662799310">बगका बारेमा रिपोर्ट गर्नुहोस्</translation> <translation id="3752582316358263300">ठिक छ...</translation> <translation id="3753033997400164841">एक पटक भण्डारण गर्नुहोस्। सबैतिर प्रयोग गर्नुहोस्</translation> @@ -3245,6 +3246,7 @@ <translation id="4510614391273086606">Linux का फाइल र एपहरू पुनर्स्थापना गरी तिनको ब्याकअप स्थितिमा लगिँदै छ।</translation> <translation id="451102079304155829">कार्टहरू</translation> <translation id="4513275008300099962">विन्डो कन्ट्रोल ओभरले असक्षम पार्नुहोस्</translation> +<translation id="4513872120116766993">पूर्वानुमानयुक्त लेखन</translation> <translation id="4513946894732546136">पृष्ठपोषण</translation> <translation id="451407183922382411"><ph name="COMPANY_NAME" /> द्वारा संचालित</translation> <translation id="4514610446763173167">भिडियो प्ले वा पज गर्न टगल गर्नुहोस्</translation> @@ -4195,7 +4197,7 @@ <translation id="5583640892426849032">ब्याकस्पेस</translation> <translation id="5584088138253955452">युजरनेम सुरक्षित गर्ने हो?</translation> <translation id="5584091888252706332">सुरुवातमा</translation> -<translation id="5584915726528712820"><ph name="BEGIN_PARAGRAPH1" />यो तपाईंको डिभाइस र तपाईंले गर्ने त्यसको प्रयोग (जस्तै ब्याट्रीको स्तर, प्रणाली तथा एपका क्रियाकलाप र त्रुटिहरू) सम्बन्धी सामान्य जानकारी हो। यो डेटालाई Android मा सुधार गर्ने प्रयोजनका लागि प्रयोग गरिने छ र केही एकत्रित जानकारीले Google का एप तथा Android का विकासकर्ता जस्ता साझेदारहरूलाई तिनका एप र उत्पादनहरू अझ राम्रो बनाउन पनि मद्दत गर्ने छ।<ph name="END_PARAGRAPH1" /> +<translation id="5584915726528712820"><ph name="BEGIN_PARAGRAPH1" />यो तपाईंको डिभाइस र त्यसको प्रयोग (जस्तै ब्याट्रीको स्तर, प्रणाली तथा एपका क्रियाकलाप र त्रुटिहरू) सम्बन्धी सामान्य जानकारी हो। यो डेटालाई Android मा सुधार गर्ने प्रयोजनका लागि प्रयोग गरिने छ र केही एकत्रित जानकारीले Google का एप तथा Android का विकासकर्ता जस्ता साझेदारहरूलाई तिनका एप र उत्पादनहरू अझ राम्रो बनाउन पनि मद्दत गर्ने छ।<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />यो सुविधा निष्क्रिय पार्नुले प्रणालीका अद्यावधिक र सुरक्षा जस्ता अत्यावश्यक सेवाहरूलाई आवश्यक पर्ने जानकारी पठाउने तपाईंको डिभाइसको क्षमतामा भने कुनै असर पर्दैन।<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />यस डिभाइसका मालिक सेटिङहरू > उन्नत > निदान तथा प्रयोगसम्बन्धी डेटा Google मा स्वतः पठाउनुहोस् नामक विकल्पमा गई यो सुविधा नियन्त्रण गर्न सक्नुहुन्छ।<ph name="END_PARAGRAPH3" /> <ph name="BEGIN_PARAGRAPH4" />तपाईंको वेब तथा एपसम्बन्धी अतिरिक्त क्रियाकलापको सेटिङ सक्रिय गरिएको छ भने यो डेटा तपाईंको Google खातामा सुरक्षित गरिन सक्छ। तपाईं account.google.com मा गई आफ्नो डेटा हेर्न, मेटाउन र परिवर्तन गर्न सक्नुहुन्छ।<ph name="END_PARAGRAPH4" /></translation> @@ -4404,6 +4406,7 @@ <translation id="5826395379250998812">आफ्नो <ph name="DEVICE_TYPE" /> आफ्नो फोनमा जोड्नुहोस्। <ph name="LINK_BEGIN" />थप जान्नुहोस्<ph name="LINK_END" /></translation> <translation id="5826993284769733527">अर्धपारदर्शी</translation> <translation id="5827266244928330802">सफारी</translation> +<translation id="5827733057563115968">आउँदो शब्दको पूर्वानुमान</translation> <translation id="5828545842856466741">प्रोफाइल हाल्नुहोस्...</translation> <translation id="5828633471261496623">प्रिन्ट गर्दै...</translation> <translation id="5830720307094128296">पृष्ठलाई यसको &रूपमा बचत गर्नुहोस्...</translation> @@ -6270,6 +6273,7 @@ <translation id="78526636422538552">योभन्दा बढी Google खाताहरू थप्ने सुविधा असक्षम पारिएको छ</translation> <translation id="7853747251428735">थप उपकरणहरू</translation> <translation id="7855678561139483478">ट्याब नयाँ विन्डोमा सार्नुहोस्</translation> +<translation id="7857093393627376423">पाठसम्बन्धी सुझावहरू</translation> <translation id="7857117644404132472">अपवाद थप्नुहोस्</translation> <translation id="7857949311770343000">के यो नै तपाईंले अपेक्षा गर्नुभएको नयाँ ट्याब पृष्ठ हो?</translation> <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation> diff --git a/chrome/app/resources/generated_resources_sr-Latn.xtb b/chrome/app/resources/generated_resources_sr-Latn.xtb index 4c46f634a128a6..d1ce480f0a4b5b 100644 --- a/chrome/app/resources/generated_resources_sr-Latn.xtb +++ b/chrome/app/resources/generated_resources_sr-Latn.xtb @@ -2661,7 +2661,7 @@ a Ctrl+Alt+taster za smanjivanje osvetljenosti da biste umanjili prikaz.</transl <translation id="3834775135533257713">Dodavanje aplikacije „<ph name="TO_INSTALL_APP_NAME" />“ nije uspelo zbog konflikta sa aplikacijom „<ph name="INSTALLED_APP_NAME" />“.</translation> <translation id="3835233591525155343">Korišćenje uređaja</translation> <translation id="3835522725882634757">O, ne! Ovaj server šalje podatke koje <ph name="PRODUCT_NAME" /> ne razume. <ph name="BEGIN_LINK" />Prijavite grešku<ph name="END_LINK" /> i uz nju pošaljite <ph name="BEGIN2_LINK" />osnovnu listu<ph name="END2_LINK" />.</translation> -<translation id="383669374481694771">Ovo su opšte informacije o ovom uređaju i načinu na koji se koristi (poput nivoa napunjenosti baterije, aktivnosti sistema i aplikacija i grešaka). Podaci će se koristiti za poboljšanje Android-a, a neke objedinjene informacije će pomoći i Google aplikacijama i partnerima, kao što su Android programeri, da poboljšaju svoje aplikacije i proizvode.</translation> +<translation id="383669374481694771">Ovo su opšte informacije o ovom uređaju i načinu na koji se koristi (poput nivoa napunjenosti baterije, aktivnosti sistema i aplikacija, i grešaka). Podaci će se koristiti za poboljšanje Android-a, a neke objedinjene informacije će pomoći i Google aplikacijama i partnerima, kao što su Android programeri, da poboljšaju svoje aplikacije i proizvode.</translation> <translation id="3838085852053358637">Učitavanje dodatka nije uspelo</translation> <translation id="3838486795898716504">Još stranica <ph name="PAGE_TITLE" /></translation> <translation id="383891835335927981">Nijedan sajt nije uvećan ni umanjen</translation> @@ -4210,7 +4210,7 @@ a Ctrl+Alt+taster za smanjivanje osvetljenosti da biste umanjili prikaz.</transl <translation id="5583640892426849032">Backspace</translation> <translation id="5584088138253955452">Želite li da sačuvate korisničko ime?</translation> <translation id="5584091888252706332">Pri pokretanju</translation> -<translation id="5584915726528712820"><ph name="BEGIN_PARAGRAPH1" />Ovo su uopštene informacije o uređaju i načinu na koji se koristi (poput nivoa baterije, aktivnosti sistema i aplikacija i grešaka). Podaci će se koristiti za poboljšavanje Android-a, a neke objedinjene informacije će pomoći i Google aplikacijama i partnerima, kao što su Android programeri, da poboljšaju svoje aplikacije i proizvode.<ph name="END_PARAGRAPH1" /> +<translation id="5584915726528712820"><ph name="BEGIN_PARAGRAPH1" />Ovo su uopštene informacije o uređaju i načinu na koji se koristi (poput nivoa baterije, aktivnosti sistema i aplikacija, i grešaka). Podaci će se koristiti za poboljšavanje Android-a, a neke objedinjene informacije će pomoći i Google aplikacijama i partnerima, kao što su Android programeri, da poboljšaju svoje aplikacije i proizvode.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Isključivanje ove funkcije neće uticati na mogućnost uređaja da šalje informacije potrebne za neophodne usluge, poput ažuriranja sistema i bezbednosnih funkcija.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Vlasnik može da upravlja ovom funkcijom u odeljku Podešavanja > Napredno > Automatski šalji dijagnostiku i podatke o korišćenju Google-u.<ph name="END_PARAGRAPH3" /> <ph name="BEGIN_PARAGRAPH4" />Ako je uključeno dodatno podešavanje za Aktivnosti na vebu i u aplikacijama, ovi podaci će se možda čuvati na Google nalogu. Možete da pregledate i brišete podatke i da menjate podešavanja naloga na account.google.com.<ph name="END_PARAGRAPH4" /></translation> @@ -6677,7 +6677,7 @@ Datoteka ključa: <ph name="KEY_FILE" /> <translation id="826511437356419340">Ušli ste u režim pregleda prozora. Prevucite da biste se kretali ili pritisnite Tab ako koristite tastaturu.</translation> <translation id="8266947622852630193">Sve metode unosa</translation> <translation id="8267539814046467575">Dodajte štampač</translation> -<translation id="8267961145111171918"><ph name="BEGIN_PARAGRAPH1" />Ovo su uopštene informacije o ovom uređaju i načinu na koji se koristi (poput nivoa baterije, aktivnosti sistema i aplikacija i grešaka). Podaci će se koristiti za poboljšavanje Android-a, a neke objedinjene informacije će pomoći i Google aplikacijama i partnerima, kao što su Android programeri, da poboljšaju svoje aplikacije i proizvode.<ph name="END_PARAGRAPH1" /> +<translation id="8267961145111171918"><ph name="BEGIN_PARAGRAPH1" />Ovo su uopštene informacije o ovom uređaju i načinu na koji se koristi (poput nivoa baterije, aktivnosti sistema i aplikacija, i grešaka). Podaci će se koristiti za poboljšavanje Android-a, a neke objedinjene informacije će pomoći i Google aplikacijama i partnerima, kao što su Android programeri, da poboljšaju svoje aplikacije i proizvode.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Isključivanje ove funkcije neće uticati na mogućnost ovog uređaja da šalje informacije potrebne za neophodne usluge, poput ažuriranja sistema i bezbednosnih funkcija.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Vlasnik može da upravlja ovom funkcijom u odeljku Podešavanja > Napredno > Automatski šalji dijagnostiku i podatke o korišćenju Google-u.<ph name="END_PARAGRAPH3" /> <ph name="BEGIN_PARAGRAPH4" />Ako za dete uključite dodatne Aktivnosti na vebu i u aplikacijama, ti podaci će se možda čuvati na Google nalogu deteta. Saznajte više o ovim podešavanjima i o tome kako da ih prilagodite na families.google.com.<ph name="END_PARAGRAPH4" /></translation> @@ -6936,7 +6936,7 @@ Pritisnite dodeljeni prekidač da biste uklonili dodelu.</translation> <translation id="8590375307970699841">Podesi automatska ažuriranja</translation> <translation id="8590506940709493916">,</translation> <translation id="8591783563402255548">1 sekunda</translation> -<translation id="8592141010104017453">Ne prikazuj nikakva obaveštenja</translation> +<translation id="8592141010104017453">Ne prikazuj uopšte obaveštenja</translation> <translation id="859246725979739260">Ovom sajtu je zabranjeno da pristupa lokaciji.</translation> <translation id="8593121833493516339">Šaljite podatke o korišćenju i dijagnostičke podatke. Pomozite nam da poboljšamo Android doživljaj za dete tako što ćete automatski slati Google-u podatke o dijagnostici i korišćenju uređaja i aplikacija. Te informacije se neće koristiti za identifikaciju deteta i pomoći će u održavanju stabilnosti sistema i aplikacije i drugim podešavanjima. Neki objedinjeni podaci će takođe pomoći Google aplikacijama i partnerima, poput Android programera. Ako za dete uključite dodatne aktivnosti na vebu i u aplikacijama, ti podaci će se možda čuvati na Google nalogu deteta. <ph name="BEGIN_LINK1" />Saznajte više<ph name="END_LINK1" /></translation> <translation id="8594908476761052472">Snimi video</translation> @@ -7087,7 +7087,7 @@ Pritisnite dodeljeni prekidač da biste uklonili dodelu.</translation> <translation id="8737914367566358838">Odaberite jezik na koji želite da prevedete stranicu</translation> <translation id="8740247629089392745">Možete da predate ovaj Chromebook korisniku <ph name="SUPERVISED_USER_NAME" />. Podešavanje je skoro gotove, pa dolazi vreme za istraživanje.</translation> <translation id="8741944563400125534">Vodič za podešavanje pristupa pomoću prekidača</translation> -<translation id="8742998548129056176">Ovo su opšte informacije o uređaju i načinu na koji ga koristite (poput nivoa napunjenosti baterije, aktivnosti sistema i aplikacija i grešaka). Podaci će se koristiti za poboljšanje Android-a, a neke objedinjene informacije će pomoći i Google aplikacijama i partnerima, kao što su Android programeri, da poboljšaju svoje aplikacije i proizvode.</translation> +<translation id="8742998548129056176">Ovo su opšte informacije o uređaju i načinu na koji ga koristite (poput nivoa napunjenosti baterije, aktivnosti sistema i aplikacija, i grešaka). Podaci će se koristiti za poboljšanje Android-a, a neke objedinjene informacije će pomoći i Google aplikacijama i partnerima, kao što su Android programeri, da poboljšaju svoje aplikacije i proizvode.</translation> <translation id="8743164338060742337"><ph name="NETWORK_INDEX" />. mreža od <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, <ph name="NETWORK_PROVIDER_NAME" />, jačina signala <ph name="SIGNAL_STRENGTH" />%, upravlja administrator, povežite</translation> <translation id="8746654918629346731">Već ste tražili „<ph name="EXTENSION_NAME" />“</translation> <translation id="874689135111202667">{0,plural, =1{Želite li da otpremite jednu datoteku na ovaj sajt?}one{Želite li da otpremite # datoteku na ovaj sajt?}few{Želite li da otpremite # datoteke na ovaj sajt?}other{Želite li da otpremite # datoteka na ovaj sajt?}}</translation> diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb index 6ea92e341cd7b4..97766cc2b03b27 100644 --- a/chrome/app/resources/generated_resources_sr.xtb +++ b/chrome/app/resources/generated_resources_sr.xtb @@ -2661,7 +2661,7 @@ <translation id="3834775135533257713">Додавање апликације „<ph name="TO_INSTALL_APP_NAME" />“ није успело због конфликта са апликацијом „<ph name="INSTALLED_APP_NAME" />“.</translation> <translation id="3835233591525155343">Коришћење уређаја</translation> <translation id="3835522725882634757">О, не! Овај сервер шаље податке које <ph name="PRODUCT_NAME" /> не разуме. <ph name="BEGIN_LINK" />Пријавите грешку<ph name="END_LINK" /> и уз њу пошаљите <ph name="BEGIN2_LINK" />основну листу<ph name="END2_LINK" />.</translation> -<translation id="383669374481694771">Ово су опште информације о овом уређају и начину на који се користи (попут нивоа напуњености батерије, активности система и апликација и грешака). Подаци ће се користити за побољшање Android-а, а неке обједињене информације ће помоћи и Google апликацијама и партнерима, као што су Android програмери, да побољшају своје апликације и производе.</translation> +<translation id="383669374481694771">Ово су опште информације о овом уређају и начину на који се користи (попут нивоа напуњености батерије, активности система и апликација, и грешака). Подаци ће се користити за побољшање Android-а, а неке обједињене информације ће помоћи и Google апликацијама и партнерима, као што су Android програмери, да побољшају своје апликације и производе.</translation> <translation id="3838085852053358637">Учитавање додатка није успело</translation> <translation id="3838486795898716504">Још страница <ph name="PAGE_TITLE" /></translation> <translation id="383891835335927981">Ниједан сајт није увећан ни умањен</translation> @@ -4210,7 +4210,7 @@ <translation id="5583640892426849032">Backspace</translation> <translation id="5584088138253955452">Желите ли да сачувате корисничко име?</translation> <translation id="5584091888252706332">При покретању</translation> -<translation id="5584915726528712820"><ph name="BEGIN_PARAGRAPH1" />Ово су уопштене информације о уређају и начину на који се користи (попут нивоа батерије, активности система и апликација и грешака). Подаци ће се користити за побољшавање Android-а, а неке обједињене информације ће помоћи и Google апликацијама и партнерима, као што су Android програмери, да побољшају своје апликације и производе.<ph name="END_PARAGRAPH1" /> +<translation id="5584915726528712820"><ph name="BEGIN_PARAGRAPH1" />Ово су уопштене информације о уређају и начину на који се користи (попут нивоа батерије, активности система и апликација, и грешака). Подаци ће се користити за побољшавање Android-а, а неке обједињене информације ће помоћи и Google апликацијама и партнерима, као што су Android програмери, да побољшају своје апликације и производе.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Искључивање ове функције неће утицати на могућност уређаја да шаље информације потребне за неопходне услуге, попут ажурирања система и безбедносних функција.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Власник може да управља овом функцијом у одељку Подешавања > Напредно > Аутоматски шаљи дијагностику и податке о коришћењу Google-у.<ph name="END_PARAGRAPH3" /> <ph name="BEGIN_PARAGRAPH4" />Ако је укључено додатно подешавање за Активности на вебу и у апликацијама, ови подаци ће се можда чувати на Google налогу. Можете да прегледате и бришете податке и да мењате подешавања налога на account.google.com.<ph name="END_PARAGRAPH4" /></translation> @@ -6677,7 +6677,7 @@ <translation id="826511437356419340">Ушли сте у режим прегледа прозора. Превуците да бисте се кретали или притисните Tab ако користите тастатуру.</translation> <translation id="8266947622852630193">Све методе уноса</translation> <translation id="8267539814046467575">Додајте штампач</translation> -<translation id="8267961145111171918"><ph name="BEGIN_PARAGRAPH1" />Ово су уопштене информације о овом уређају и начину на који се користи (попут нивоа батерије, активности система и апликација и грешака). Подаци ће се користити за побољшавање Android-а, а неке обједињене информације ће помоћи и Google апликацијама и партнерима, као што су Android програмери, да побољшају своје апликације и производе.<ph name="END_PARAGRAPH1" /> +<translation id="8267961145111171918"><ph name="BEGIN_PARAGRAPH1" />Ово су уопштене информације о овом уређају и начину на који се користи (попут нивоа батерије, активности система и апликација, и грешака). Подаци ће се користити за побољшавање Android-а, а неке обједињене информације ће помоћи и Google апликацијама и партнерима, као што су Android програмери, да побољшају своје апликације и производе.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />Искључивање ове функције неће утицати на могућност овог уређаја да шаље информације потребне за неопходне услуге, попут ажурирања система и безбедносних функција.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Власник може да управља овом функцијом у одељку Подешавања > Напредно > Аутоматски шаљи дијагностику и податке о коришћењу Google-у.<ph name="END_PARAGRAPH3" /> <ph name="BEGIN_PARAGRAPH4" />Ако за дете укључите додатне Активности на вебу и у апликацијама, ти подаци ће се можда чувати на Google налогу детета. Сазнајте више о овим подешавањима и о томе како да их прилагодите на families.google.com.<ph name="END_PARAGRAPH4" /></translation> @@ -6936,7 +6936,7 @@ <translation id="8590375307970699841">Подеси аутоматска ажурирања</translation> <translation id="8590506940709493916">,</translation> <translation id="8591783563402255548">1 секунда</translation> -<translation id="8592141010104017453">Не приказуј никаква обавештења</translation> +<translation id="8592141010104017453">Не приказуј уопште обавештења</translation> <translation id="859246725979739260">Овом сајту је забрањено да приступа локацији.</translation> <translation id="8593121833493516339">Шаљите податке о коришћењу и дијагностичке податке. Помозите нам да побољшамо Android доживљај за дете тако што ћете аутоматски слати Google-у податке о дијагностици и коришћењу уређаја и апликација. Те информације се неће користити за идентификацију детета и помоћи ће у одржавању стабилности система и апликације и другим подешавањима. Неки обједињени подаци ће такође помоћи Google апликацијама и партнерима, попут Android програмера. Ако за дете укључите додатне активности на вебу и у апликацијама, ти подаци ће се можда чувати на Google налогу детета. <ph name="BEGIN_LINK1" />Сазнајте више<ph name="END_LINK1" /></translation> <translation id="8594908476761052472">Сними видео</translation> @@ -7087,7 +7087,7 @@ <translation id="8737914367566358838">Одаберите језик на који желите да преведете страницу</translation> <translation id="8740247629089392745">Можете да предате овај Chromebook кориснику <ph name="SUPERVISED_USER_NAME" />. Подешавање је скоро готове, па долази време за истраживање.</translation> <translation id="8741944563400125534">Водич за подешавање приступа помоћу прекидача</translation> -<translation id="8742998548129056176">Ово су опште информације о уређају и начину на који га користите (попут нивоа напуњености батерије, активности система и апликација и грешака). Подаци ће се користити за побољшање Android-а, а неке обједињене информације ће помоћи и Google апликацијама и партнерима, као што су Android програмери, да побољшају своје апликације и производе.</translation> +<translation id="8742998548129056176">Ово су опште информације о уређају и начину на који га користите (попут нивоа напуњености батерије, активности система и апликација, и грешака). Подаци ће се користити за побољшање Android-а, а неке обједињене информације ће помоћи и Google апликацијама и партнерима, као што су Android програмери, да побољшају своје апликације и производе.</translation> <translation id="8743164338060742337"><ph name="NETWORK_INDEX" />. мрежа од <ph name="NETWORK_COUNT" />, <ph name="NETWORK_NAME" />, <ph name="NETWORK_PROVIDER_NAME" />, јачина сигнала <ph name="SIGNAL_STRENGTH" />%, управља администратор, повежите</translation> <translation id="8746654918629346731">Већ сте тражили „<ph name="EXTENSION_NAME" />“</translation> <translation id="874689135111202667">{0,plural, =1{Желите ли да отпремите једну датотеку на овај сајт?}one{Желите ли да отпремите # датотеку на овај сајт?}few{Желите ли да отпремите # датотеке на овај сајт?}other{Желите ли да отпремите # датотека на овај сајт?}}</translation> diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb index 243a5dbe66046a..78f927de71f9d5 100644 --- a/chrome/app/resources/generated_resources_ta.xtb +++ b/chrome/app/resources/generated_resources_ta.xtb @@ -4051,7 +4051,7 @@ <translation id="538822246583124912">நிறுவனத்தின் கொள்கை மாறியுள்ளது. கருவிப்பட்டியில் ’பரிசோதனைகள்’ பட்டன் சேர்க்கப்பட்டது. பரிசோதனைகளை இயக்குவதற்கான உரையாடலைத் திறக்க, இந்த பட்டனைக் கிளிக் செய்யவும்.</translation> <translation id="5388885445722491159">சேர்க்கப்பட்டவை</translation> <translation id="5390100381392048184">ஒலியை இயக்க, தளங்களை அனுமதி</translation> -<translation id="5390112241331447203">கருத்து அறிக்கைகளில் அனுப்பிய system_logs.txt கோப்பினைச் சேர்க்கும்.</translation> +<translation id="5390112241331447203">கருத்து அறிக்கைகளில் அனுப்பிய system_logs.txt ஃபைலைச் சேர்க்கும்.</translation> <translation id="5390677308841849479">அடர் சிவப்பு & ஆரஞ்சு</translation> <translation id="5390743329570580756">இதற்காக அனுப்பு:</translation> <translation id="5392192690789334093">அறிவிப்புகளை அனுப்ப அனுமதிக்கப்பட்டவை</translation> @@ -4896,7 +4896,7 @@ <translation id="6317318380444133405">இனி ஆதரிக்கப்படாது.</translation> <translation id="6317369057005134371">ஆப்ஸ் சாளரத்திற்காகக் காத்திருக்கிறது...</translation> <translation id="6317608858038767920">பிரத்தியேகப் பெயர்மாற்றி <ph name="INPUT_INDEX" /></translation> -<translation id="6318125393809743217">கொள்கை உள்ளமைவுகளுடன் policies.json கோப்பினைச் சேர்.</translation> +<translation id="6318125393809743217">கொள்கை உள்ளமைவுகளுடன் policies.json ஃபைலைச் சேர்.</translation> <translation id="6318407754858604988">பதிவிறக்கம் தொடங்கியது</translation> <translation id="6318944945640833942">பிரிண்டரைக் கண்டறிய இயலவில்லை. பிரிண்டர் முகரியை மீண்டும் உள்ளிடுக.</translation> <translation id="6321407676395378991">ஸ்கிரீன் சேவரை இயக்குதல்</translation> diff --git a/chrome/app/resources/generated_resources_tr.xtb b/chrome/app/resources/generated_resources_tr.xtb index a1d79178904dc2..2195a3dd27f28c 100644 --- a/chrome/app/resources/generated_resources_tr.xtb +++ b/chrome/app/resources/generated_resources_tr.xtb @@ -1804,7 +1804,7 @@ Sunucunun mesajı: <ph name="SERVER_MSG" /></translation> <translation id="2910318910161511225">Bir ağa bağlanın ve tekrar deneyin</translation> <translation id="291056154577034373">OKUNMAYANLAR</translation> <translation id="2910718431259223434">Bir hata oluştu. Lütfen tekrar deneyin veya cihaz sahibi ya da yöneticisiyle iletişime geçin. Hata kodu: <ph name="ERROR_CODE" />.</translation> -<translation id="2911433807131383493">ChromeVox eğiticiyi aç</translation> +<translation id="2911433807131383493">ChromeVox eğitimini aç</translation> <translation id="2913331724188855103">Sitelerin, çerez verilerini kaydetmelerine ve okumalarına izin ver (önerilir)</translation> <translation id="2915102088417824677">Etkinlik günlüğünü göster</translation> <translation id="2915873080513663243">Otomatik tarama</translation> diff --git a/chrome/app/resources/generated_resources_ur.xtb b/chrome/app/resources/generated_resources_ur.xtb index 28a61a2e5c3be9..a7d0ff0791ad3a 100644 --- a/chrome/app/resources/generated_resources_ur.xtb +++ b/chrome/app/resources/generated_resources_ur.xtb @@ -2567,6 +2567,7 @@ myaccount.google.com/activitycontrols/search پر تبدیل کر سکتے ہي <translation id="3742666961763734085">اس نام کا تنظیمی یونٹ تلاش نہیں کیا جا سکا۔ براہ کرم دوبارہ کوشش کریں۔</translation> <translation id="3744111561329211289">پس منظر کی مطابقت پذیری</translation> <translation id="3747077776423672805">ایپس ہٹانے کے لیے، ترتیبات > Google Play اسٹور > Android کی ترجیحات کا نظم کریں > ایپس یا ایپلیکیشن مینیجر پر جائیں۔ پھر اس ایپ پر تھپتھپائیں جسے آپ اَن انسٹال کرنا چاہتے ہیں (ممکن ہے کہ ایپ تلاش کرنے کے لیے آپ کو دائیں یا بائیں سوائپ کرنا پڑے)۔ پھر 'اَن انسٹال کریں' یا 'غیر فعال کریں' پر تھپتھپائیں۔</translation> +<translation id="3747220812138541072">ان لائن لکھنے کی تجاویز دکھائیں جو آپ کے ٹائپ کرتے ہی ظاہر ہوتے ہیں</translation> <translation id="3748706263662799310">بگ کی اطلاع دیں</translation> <translation id="3752582316358263300">ٹھیک ہے…</translation> <translation id="3753033997400164841">ایک بار اسٹور کریں۔ ہر جگہ استعمال کریں</translation> @@ -3255,6 +3256,7 @@ myaccount.google.com/activitycontrols/search پر تبدیل کر سکتے ہي <translation id="4510614391273086606">Linux فائلز اور ایپس کو ان کی بیک اپ حالت میں بحال کیا جا رہا ہے۔</translation> <translation id="451102079304155829">کارٹس</translation> <translation id="4513275008300099962">ونڈو کنٹرولز اوورلے کو غیر فعال کریں</translation> +<translation id="4513872120116766993">لکھنے میں لفظ کی پیشین گوئی</translation> <translation id="4513946894732546136">تاثرات</translation> <translation id="451407183922382411"><ph name="COMPANY_NAME" /> کی جانب سے تقویت یافتہ</translation> <translation id="4514610446763173167">چلانے یا روکنے کیلئے ویڈیو ٹوگل کریں</translation> @@ -4418,6 +4420,7 @@ myaccount.google.com/activitycontrols/search پر تبدیل کر سکتے ہي <translation id="5826395379250998812">اپنے <ph name="DEVICE_TYPE" /> کو اپنے فون سے منسلک کریں۔ <ph name="LINK_BEGIN" />مزید جانیں<ph name="LINK_END" /></translation> <translation id="5826993284769733527">نیم شفاف</translation> <translation id="5827266244928330802">Safari</translation> +<translation id="5827733057563115968">اگلے لفظ کی پیشن گوئی</translation> <translation id="5828545842856466741">پروفائل شامل کریں...</translation> <translation id="5828633471261496623">پرنٹ کیا جا رہا ہے…</translation> <translation id="5830720307094128296">صفحہ محفوظ کریں &بطور…</translation> @@ -6289,6 +6292,7 @@ myaccount.google.com/activitycontrols/search پر تبدیل کر سکتے ہي <translation id="78526636422538552">مزید Google اکاؤنٹس شامل کرنے کا عمل غیر فعال ہے</translation> <translation id="7853747251428735">مزید ٹولز</translation> <translation id="7855678561139483478">ٹیب کو نئی ونڈو میں منتقل کریں</translation> +<translation id="7857093393627376423">متنی تجاویز</translation> <translation id="7857117644404132472">استثناء شامل کریں</translation> <translation id="7857949311770343000">کیا یہی وہ نیا ٹیب صفحہ ہے جس کی آپ توقع کر رہے تھے؟</translation> <translation id="7858328180167661092"><ph name="APP_NAME" /> (Windows)</translation> diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb index bb97901ad16482..2d5e3242580c8c 100644 --- a/chrome/app/resources/generated_resources_vi.xtb +++ b/chrome/app/resources/generated_resources_vi.xtb @@ -3134,7 +3134,7 @@ và Ctrl+Alt+Giảm độ sáng để thu nhỏ.</translation> <translation id="4363771538994847871">Không tìm thấy đích Truyền nào. Bạn cần trợ giúp?</translation> <translation id="4364327530094270451">Quả dưa</translation> <translation id="4364567974334641491"><ph name="APP_NAME" /> đang chia sẻ một cửa sổ.</translation> -<translation id="4364830672918311045">Hiển thị thông báo</translation> +<translation id="4364830672918311045">Hiện thông báo</translation> <translation id="4366138410738374926">Đã bắt đầu in</translation> <translation id="4370975561335139969">Email và mật khẩu bạn nhập không khớp</translation> <translation id="4373966964907728675">Đang truyền màn hình</translation> diff --git a/chrome/app/resources/google_chrome_strings_is.xtb b/chrome/app/resources/google_chrome_strings_is.xtb index d65a3079d6a344..493332b06a3fc5 100644 --- a/chrome/app/resources/google_chrome_strings_is.xtb +++ b/chrome/app/resources/google_chrome_strings_is.xtb @@ -291,7 +291,7 @@ Google Chrome getur ekki endurheimt stillingarnar þínar.</translation> <translation id="8862326446509486874">Þú hefur ekki tilskilin réttindi til uppsetningar fyrir kerfið allt. Prófaðu að keyra uppsetningarforritið aftur sem stjórnandi.</translation> <translation id="8914504000324227558">Endurræsa Chrome</translation> <translation id="8922193594870374009">Til að senda númer úr <ph name="ORIGIN" /> í Android símann þinn skaltu skrá þig inn á Chrome í báðum tækjunum.</translation> -<translation id="8986207147630327271">Þú ert að bæta vinnuprófíl við þennan vafra og veita stjórnanda þínum leyfi til að stjórna vinnuprófílnum eingöngu.</translation> +<translation id="8986207147630327271">Þú ert að bæta vinnusniði við þennan vafra og veita stjórnanda þínum leyfi til að stjórna vinnusniðinu eingöngu.</translation> <translation id="8999208279178790196">{0,plural, =0{Uppfærsla er í boði fyrir Chrome}=1{Uppfærsla er í boði fyrir Chrome}one{Uppfærsla hefur verið í boði fyrir Chrome í # dag}other{Uppfærsla hefur verið í boði fyrir Chrome í # daga}}</translation> <translation id="9026991721384951619">Chrome OS gat ekki samstillt gögnin þín vegna þess að innskráningarupplýsingar reikningsins eru úreltar.</translation> <translation id="9067395829937117663">Google Chrome krefst Windows 7 eða nýrri útgáfu.</translation> diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_tr.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_tr.xtb index 4add9f9e4fa3be..2225a31612d521 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_tr.xtb +++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_tr.xtb @@ -6,7 +6,7 @@ <translation id="1012173283529841972">Liste öğesi</translation> <translation id="1013742170491673792">srched</translation> <translation id="1014370462248694370">İki parmağınızı sağa kaydırın</translation> -<translation id="1022586497894531524">ChromeVox sözlü geri bildirimini ilk kez mi kullanıyorsunuz? Bu hızlı eğiticide, ChromeVox'ı kullanmaya başlamak için gereken temel bilgiler açıklanmaktadır.</translation> +<translation id="1022586497894531524">ChromeVox sözlü geri bildirimini ilk kez mi kullanıyorsunuz? Bu hızlı eğitimde, ChromeVox'ı kullanmaya başlamak için gereken temel bilgiler açıklanmaktadır.</translation> <translation id="1025074108959230262">Sabit mod devre dışı bırakıldı</translation> <translation id="1031961866430398710">sonra</translation> <translation id="1038643060055067718">Satır sayısı:</translation> @@ -121,7 +121,7 @@ Chrome tarayıcı menüsünü açmak için Alt+F tuşlarına basın.</translatio <translation id="1717267964664691695">Dokunarak kullanma eğitimi tamamlandı</translation> <translation id="1722567105086139392">Bağlantı</translation> <translation id="1727806147743597030">ftr</translation> -<translation id="1730447754326314349">ChromeVox eğiticisine hoş geldiniz. İstediğiniz zaman bu eğiticiden çıkmak için klavyenin sol üst köşesindeki Escape tuşuna basın. ChromeVox'u kapatmak için Control ve Alt tuşlarını basılı tutarken Z tuşuna basın. Hazır olduğunuzda bir sonraki derse geçmek için boşluk tuşunu kullanın.</translation> +<translation id="1730447754326314349">ChromeVox eğitimine hoş geldiniz. İstediğiniz zaman bu eğitimden çıkmak için klavyenin sol üst köşesindeki Escape tuşuna basın. ChromeVox'u kapatmak için Control ve Alt tuşlarını basılı tutarken Z tuşuna basın. Hazır olduğunuzda bir sonraki derse geçmek için boşluk tuşunu kullanın.</translation> <translation id="174268867904053074">Sonraki grafik</translation> <translation id="1756785467854861272">Koyu Macenta</translation> <translation id="1758693804775271377">Bu konuyla ilgili derslere göz atmak için tek parmağınızla ekranı sola veya sağa kaydırın</translation> @@ -216,7 +216,7 @@ Chrome tarayıcı menüsünü açmak için Alt+F tuşlarına basın.</translatio <translation id="2490721194269245365">Pembemsi Kahverengi</translation> <translation id="249330843868392562">Metin okuma ayarlarını aç</translation> <translation id="2497706219848005458">Yeşile Dönük Sarı</translation> -<translation id="2523609930580546572">ChromeVox Eğiticisi</translation> +<translation id="2523609930580546572">ChromeVox Eğitimi</translation> <translation id="2525706221823668172">Chromebook klavye kısayolları</translation> <translation id="2553108862507765288">grammatical mistake</translation> <translation id="2556326187583116255">Devam etmekte olan bir konuşmayı durdurmak için 2 parmağınızla dokunun</translation> @@ -239,7 +239,7 @@ Chrome tarayıcı menüsünü açmak için Alt+F tuşlarına basın.</translatio <translation id="2673280813984708147">düzenleniyor</translation> <translation id="267442004702508783">yenile</translation> <translation id="2675533876313964202">Açık Yeşil</translation> -<translation id="2684412629217766642">ChromeVox Eğiticisi'ni kapat</translation> +<translation id="2684412629217766642">ChromeVox Eğitimini kapat</translation> <translation id="2697408785920771974">autoinl</translation> <translation id="2697786971245905543">Metin dönüşüm adayı</translation> <translation id="2704429362613743330">{COUNT,plural, =1{aç parantez}other{# aç parantez}}</translation> @@ -277,7 +277,7 @@ Chrome tarayıcı menüsünü açmak için Alt+F tuşlarına basın.</translatio <translation id="2894654529758326923">Bilgiler</translation> <translation id="2899328121302785497">{COUNT,plural, =1{sol küme parantezi}other{# sol küme parantezi}}</translation> <translation id="2909584066358367921">Sonraki düğme yok</translation> -<translation id="2911433807131383493">ChromeVox eğiticiyi aç</translation> +<translation id="2911433807131383493">ChromeVox eğitimini aç</translation> <translation id="2912405967290226587">Üç parmağınızı sağa kaydırın</translation> <translation id="2937799153569150791">Sonraki 3. düzey başlık yok</translation> <translation id="2942710183375260152">Koyu Kurşun Mavisi</translation> @@ -288,7 +288,7 @@ Chrome tarayıcı menüsünü açmak için Alt+F tuşlarına basın.</translatio <translation id="2972205263822847197">İpucu</translation> <translation id="2976476721782829799">Bir parmağınızı sürükleyerek de ekranda gezinebilirsiniz. Buna, dokunarak keşfetme denir. Bu dersin geri kalanını okumak için parmağınızı ekranda sürüklemeyi deneyin.</translation> <translation id="297825089465017871">İki parmağınızı sola kaydırın</translation> -<translation id="2988364959384217951">İpucu: Bu eğiticiden çıkmak istiyorsanız iki parmağınızla sağdan sola kaydırın.</translation> +<translation id="2988364959384217951">İpucu: Bu eğitimden çıkmak istiyorsanız iki parmağınızla sağdan sola kaydırın.</translation> <translation id="2998131015536248178">Önceki Karakter</translation> <translation id="2999559350546931576">Sesi kalınlaştır</translation> <translation id="3009352964623081324">Ara + O, ardından S. Sesleri yüklemek, yönetmek ve özelleştirmek için kullanın.</translation> @@ -331,7 +331,7 @@ Chrome tarayıcı menüsünü açmak için Alt+F tuşlarına basın.</translatio <translation id="3172700825913348768">{COUNT,plural, =1{boşluk}other{# boşluk}}</translation> <translation id="3179119189286472195">Bağlantı verilmemiş</translation> <translation id="320041337977930740">Görüntüleme stilini üst üste (interleave) olarak değiştir</translation> -<translation id="3206698050650195442">Eğiticiden çık</translation> +<translation id="3206698050650195442">Eğitimden çık</translation> <translation id="3208346789712025453">Sonraki denetim yok</translation> <translation id="321072937702597574">Orkide</translation> <translation id="3218691001991391708"><ph name="TEXT" />metnini yapıştır.</translation> @@ -361,7 +361,7 @@ Chrome tarayıcı menüsünü açmak için Alt+F tuşlarına basın.</translatio <translation id="3356951775008366684">Kelimenin fonetik telaffuzunu söyler</translation> <translation id="3359142382821736686">seprtr</translation> <translation id="3363015957057974366">Ekranda bir sonraki etkileşimli öğeye geçmek için Sekme tuşunu da kullanabilirsiniz. Arama tuşunun hemen üzerindeki Sekme tuşunu bulun. Devam etmek için Sekme tuşuna basın.</translation> -<translation id="3366946046494222386"><ph name="TOPIC" /> Eğiticisi, <ph name="LESSONS" /> Ders</translation> +<translation id="3366946046494222386"><ph name="TOPIC" /> Eğitimi, <ph name="LESSONS" /> Ders</translation> <translation id="3374537878095184207">{COUNT,plural, =1{artı işareti}other{# artı işareti}}</translation> <translation id="338583716107319301">Ayırıcı</translation> <translation id="3389259863310851658">Önceki form alanı</translation> @@ -401,7 +401,7 @@ Chrome tarayıcı menüsünü açmak için Alt+F tuşlarına basın.</translatio <translation id="3650317109285159359">chkmnuitm</translation> <translation id="3655855170848725876">{COUNT,plural, =1{dolar işareti}other{# dolar işareti}}</translation> <translation id="3659787053479271466">alrt</translation> -<translation id="366419593095697301">İpucu: Bu eğiticiden çıkmak isterseniz Escape tuşuna basın.</translation> +<translation id="366419593095697301">İpucu: Bu eğitimden çıkmak isterseniz Escape tuşuna basın.</translation> <translation id="3676062394766691318">Cihazınızı kurduktan sonra geri dönüp Arama + O tuşlarına, sonra da T tuşuna basarak diğer eğiticileri görüntüleyebilirsiniz.</translation> <translation id="3681531118904532409">Papaya Rengi</translation> <translation id="3692274950075847560">A:<ph name="RESULT" /></translation> @@ -693,7 +693,7 @@ Chrome tarayıcı menüsünü açmak için Alt+F tuşlarına basın.</translatio <translation id="5851548754964597211">Sekme listesi</translation> <translation id="5866042630553435010">Kısmen işaretli</translation> <translation id="5866210856231860256">Bu konuyla ilgili derslere göz atmak için Arama + Sağ Ok veya Arama + Sol Ok tuşlarına basın</translation> -<translation id="5867591286054666064">Bu eğitici sırasında herhangi bir tuşun adını duymak için ilgili tuşa basın.</translation> +<translation id="5867591286054666064">Bu eğitim sırasında herhangi bir tuşun adını duymak için ilgili tuşa basın.</translation> <translation id="5869546221129391014">Tablo</translation> <translation id="5876817486144482042">Konuşma ses düzeyini düşür</translation> <translation id="5878206664863390311">Konulara göz atmak için Arama + Sağ Ok veya Arama + Sol Ok tuşlarına basın</translation> @@ -934,7 +934,7 @@ Chrome tarayıcı menüsünü açmak için Alt+F tuşlarına basın.</translatio <translation id="7701196182766842984">autolst</translation> <translation id="7714340021005120797">Sonraki birleşik giriş kutusu yok</translation> <translation id="772146615414628379">Tebrikler! ChromeVox kullanımıyla ilgili temel bilgileri başarıyla öğrendiniz. ChromeVox komut menüsünü Arama+Nokta tuşlarına basarak istediğiniz zaman açabileceğinizi unutmayın. ChromeVox ve Chrome OS hakkında daha da fazla bilgi edinmek için aşağıdaki makaleleri inceleyin. - Eğiticiyle işiniz bittiğinde, ChromeVox'ı kullanarak Kapat düğmesine gidip düğmeyi tıklayın.</translation> + Eğitimle işiniz bittiğinde, ChromeVox'ı kullanarak Kapat düğmesine gidip düğmeyi tıklayın.</translation> <translation id="7724603315864178912">Kes</translation> <translation id="7731785449856576010">Sonraki medya widget'ı yok</translation> <translation id="7735498529470878067">Dokunarak keşfetmek, ekranda neler olduğunu kısa sürede algılamanıza yardımcı olabilir.</translation> @@ -1052,7 +1052,7 @@ Chrome tarayıcı menüsünü açmak için Alt+F tuşlarına basın.</translatio <translation id="8603071050456974042">ChromeVox Paneli</translation> <translation id="8606621670302093223">Tarih denetimi</translation> <translation id="8613709718990529335">Beyaz Porselen</translation> -<translation id="8614129468475308349">Tebrikler! ChromeVox ile ilgili temel bilgileri öğrendiniz. Tekrar eğiticinin üzerinden geçebilir veya aşağıdaki düğmelerden birini bulup tıklayarak bu eğiticiden çıkabilirsiniz.</translation> +<translation id="8614129468475308349">Tebrikler! ChromeVox ile ilgili temel bilgileri öğrendiniz. Tekrar eğitimin üzerinden geçebilir veya aşağıdaki düğmelerden birini bulup tıklayarak bu eğitimden çıkabilirsiniz.</translation> <translation id="8625173877182443267">Sonraki 6. düzey başlık yok</translation> <translation id="8628186274519446680">Domates</translation> <translation id="8638532244051952400">Geçerli hücre koordinatlarını söyle</translation> @@ -1097,7 +1097,7 @@ Chrome tarayıcı menüsünü açmak için Alt+F tuşlarına basın.</translatio <translation id="8986362086234534611">Unut</translation> <translation id="8989104346085848538">Devam etmekte olan bir ChromeVox konuşmasını durdurmak için Control tuşuna basın.</translation> <translation id="8993737615451556423">Okuma sesini hızlandırma, yavaşlatma ve duraklatma kontrollerini sağlar</translation> -<translation id="9014206344398081366">ChromeVox eğiticisi</translation> +<translation id="9014206344398081366">ChromeVox eğitimi</translation> <translation id="9040132695316389094">Başlık 1</translation> <translation id="9061884144798498064">8 noktalı bir braille tablosu seçin:</translation> <translation id="9065283790526219006">+popup</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb index 9085087d5ee0df..560133e373fead 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">ውርድዎን በማፍጠን ላይ።</translation> <translation id="5454166040603940656">ከ<ph name="PROVIDER" /> ጋር</translation> <translation id="5456381639095306749">ገጽ አውርድ</translation> +<translation id="5458366071038729214">የሚከተሏቸውን ጣቢያዎች እዚህ ያገኛሉ</translation> <translation id="548278423535722844">በካርታዎች መተግበሪያ ውስጥ ይክፈቱ</translation> <translation id="5483197086164197190">Chromeን ያስሱ</translation> <translation id="5487521232677179737">ውሂብን አጽዳ</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb index ac173ec2f9ee2d..09d0c2fdda7b44 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">جارٍ تسريع التنزيل.</translation> <translation id="5454166040603940656">مع <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">تنزيل الصفحة</translation> +<translation id="5458366071038729214">تظهر هنا المواقع الإلكترونية التي تتابعها.</translation> <translation id="548278423535722844">فتح في تطبيق الخرائط</translation> <translation id="5483197086164197190">التنقُّل في Chrome</translation> <translation id="5487521232677179737">محو البيانات</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb index c42cb4358c82d4..925ffc2ff14f1c 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">আপোনাৰ ডাউনল’ড আৰু খৰতকীয়া কৰি থকা হৈছে।</translation> <translation id="5454166040603940656"><ph name="PROVIDER" />ৰ সৈতে</translation> <translation id="5456381639095306749">পৃষ্ঠাটো ডাউনল'ড কৰক</translation> +<translation id="5458366071038729214">আপুনি নিজে ফ'ল' কৰা ছাইটসমূহ ইয়াত বিচাৰি পাব</translation> <translation id="548278423535722844">maps এপত খোলক</translation> <translation id="5483197086164197190">Chromeত নেভিগে’ট কৰা</translation> <translation id="5487521232677179737">ডেটা মচক</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb index c473540658cd24..f61c2a07c272b2 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb @@ -684,6 +684,7 @@ Ayarı dəyişmək üçün <ph name="BEGIN_LINK" />sinxronizasiyanı sıfırlay <translation id="545042621069398927">Endirmənizi sürətləndirin.</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> ilə</translation> <translation id="5456381639095306749">Endirmə səhifəsi</translation> +<translation id="5458366071038729214">İzlədiyiniz saytları burada tapa bilərsiniz</translation> <translation id="548278423535722844">Xəritə tətbiqində açın</translation> <translation id="5483197086164197190">Chrome'u araşdırın</translation> <translation id="5487521232677179737">Datanı silin</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb index bd227b409db36b..a72c5a545b7e90 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb @@ -684,6 +684,7 @@ Privacy Sandbox падтрымлівае адкрытасць інтэрнэту <translation id="545042621069398927">Спампоўка паскараецца.</translation> <translation id="5454166040603940656">крыніца: <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Спампаваць старонку</translation> +<translation id="5458366071038729214">Тут будуць паказвацца сайты, на якія вы падпішацеся</translation> <translation id="548278423535722844">Адкрыць у праграме карт</translation> <translation id="5483197086164197190">Навігацыя ў Chrome</translation> <translation id="5487521232677179737">Ачысціць даныя</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb index afd00224e72318..dceab66a7c86ca 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb @@ -684,6 +684,7 @@ Privacy Sandbox продължава да се разработва активн <translation id="545042621069398927">Изтеглянето се ускорява.</translation> <translation id="5454166040603940656">с/ъс <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Изтегляне на страницата</translation> +<translation id="5458366071038729214">Тук ще виждате сайтовете, които следите</translation> <translation id="548278423535722844">Отваряне в приложение за карти</translation> <translation id="5483197086164197190">Навигиране в Chrome</translation> <translation id="5487521232677179737">Изчиств. на данните</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb index b33b887118e4c2..005ef02ba241bc 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb @@ -684,6 +684,7 @@ Da biste promijenili tu postavku, <ph name="BEGIN_LINK" />poništite sinkronizac <translation id="545042621069398927">Ubrzavanje preuzimanja.</translation> <translation id="5454166040603940656">s pružaocem usluge <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Preuzmi stranicu</translation> +<translation id="5458366071038729214">Ovdje ćete pronaći lokacije koje pratite</translation> <translation id="548278423535722844">Otvori u aplikacijama za mape</translation> <translation id="5483197086164197190">Navigirajte Chromeom</translation> <translation id="5487521232677179737">Obriši podatke</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb index 901fbe0df9f13e..adb9d790c308c8 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb @@ -311,7 +311,7 @@ Mantén premuda qualsevol paraula per cercar-la. Per definir millor la cerca, se <translation id="2956410042958133412"><ph name="PARENT_NAME_1" /> i <ph name="PARENT_NAME_2" /> gestionen aquest compte.</translation> <translation id="2961208450284224863">{READING_LIST_UNREAD_PAGE_COUNT,plural, =1{<ph name="READING_LIST_UNREAD_PAGE_COUNT_ONE" /> pàgina no llegida}other{<ph name="READING_LIST_UNREAD_PAGE_COUNT_MANY" /> pàgines no llegides}}</translation> <translation id="2979025552038692506">Pestanya d'incògnit seleccionada</translation> -<translation id="2979448359891869301">No es pot ampliar la captura de pantalla. Torna-ho a provar quan el telèfon no estigui ocupat.</translation> +<translation id="2979448359891869301">No es pot ampliar la captura de pantalla. Torna-ho a provar quan el telèfon disposi de més recursos.</translation> <translation id="2979639724566107830">Obre-ho en una finestra nova</translation> <translation id="2987620471460279764">Text compartit d'un altre dispositiu</translation> <translation id="2989523299700148168">Visitats últimament</translation> @@ -684,6 +684,7 @@ Per canviar aquesta opció, <ph name="BEGIN_LINK" />restableix la sincronitzaci <translation id="545042621069398927">S'està accelerant la baixada.</translation> <translation id="5454166040603940656">amb <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Baixa la pàgina</translation> +<translation id="5458366071038729214">Aquí veuràs els llocs web que segueixes</translation> <translation id="548278423535722844">Obre en una aplicació de mapes</translation> <translation id="5483197086164197190">Navegar per Chrome</translation> <translation id="5487521232677179737">Esborra les dades</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb index fcff4e963f309c..fec1954c259693 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb @@ -684,6 +684,7 @@ Chcete-toto nastavení změnit, <ph name="BEGIN_LINK" />resetujte synchronizaci< <translation id="545042621069398927">Zrychlování stahování.</translation> <translation id="5454166040603940656">(<ph name="PROVIDER" />)</translation> <translation id="5456381639095306749">Stáhnout stránku</translation> +<translation id="5458366071038729214">Zde najdete weby, které sledujete</translation> <translation id="548278423535722844">Otevřít v mapové aplikaci</translation> <translation id="5483197086164197190">Navigace v Chromu</translation> <translation id="5487521232677179737">Vymazat data</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb index 3dbd0c8c8a0023..c15e1c1b5717d2 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb @@ -684,6 +684,7 @@ Hvis du vil ændre denne indstilling, skal du <ph name="BEGIN_LINK" />nulstille <translation id="545042621069398927">Øger hastigheden på din download.</translation> <translation id="5454166040603940656">med <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Download siden</translation> +<translation id="5458366071038729214">Du kan finde de websites, du følger, her</translation> <translation id="548278423535722844">Åbn i kortapp</translation> <translation id="5483197086164197190">Find rundt i Chrome</translation> <translation id="5487521232677179737">Ryd data</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb index 3e185c6b705580..6f7a76745a8518 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">Επιτάχυνση της λήψης σας.</translation> <translation id="5454166040603940656">με <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Λήψη σελίδας</translation> +<translation id="5458366071038729214">Εδώ θα βρίσκετε τους ιστοτόπους που ακολουθείτε.</translation> <translation id="548278423535722844">Άνοιγμα σε εφαρμογή χαρτών</translation> <translation id="5483197086164197190">Πλοήγηση στο Chrome</translation> <translation id="5487521232677179737">Διαγραφή δεδομένων</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb index 1e470d9f40fb36..502877b0e440ee 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb @@ -684,6 +684,7 @@ Para cambiar esta configuración, <ph name="BEGIN_LINK" />restablece la sincroni <translation id="545042621069398927">Acelerando la descarga</translation> <translation id="5454166040603940656">con <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Descargar página</translation> +<translation id="5458366071038729214">Aquí encontrarás los sitios que sigues.</translation> <translation id="548278423535722844">Abrir en una app de mapas</translation> <translation id="5483197086164197190">Navigate Chrome</translation> <translation id="5487521232677179737">Borrar datos</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb index ca24fd12ffc65a..adb8f3c4215850 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb @@ -684,6 +684,7 @@ Para cambiar esta opción, <ph name="BEGIN_LINK" />restablece la sincronización <translation id="545042621069398927">Acelerando descarga.</translation> <translation id="5454166040603940656">con <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Descargar página</translation> +<translation id="5458366071038729214">Los sitios que sigas aparecerán aquí</translation> <translation id="548278423535722844">Abrirla en una aplicación de mapas</translation> <translation id="5483197086164197190">Desplazarte por Chrome</translation> <translation id="5487521232677179737">Borrar datos</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb index 672cc1c19aa2d1..8d25a943a70886 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb @@ -684,6 +684,7 @@ Seade muutmiseks <ph name="BEGIN_LINK" />lähtestage sünkroonimine<ph name="END <translation id="545042621069398927">Allalaadimise kiirendamine.</translation> <translation id="5454166040603940656">teenusepakkujaga <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Laadi leht alla</translation> +<translation id="5458366071038729214">Jälgitavad saidid leiate siit</translation> <translation id="548278423535722844">Avage kaardirakenduses</translation> <translation id="5483197086164197190">Chrome'is navigeerimine</translation> <translation id="5487521232677179737">Kustuta andmed</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb index 1d5bf42ee7d691..d84ecaefc7a76f 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb @@ -684,6 +684,7 @@ Ezarpena aldatzeko, <ph name="BEGIN_LINK" />berrezarri sinkronizazioa<ph name="E <translation id="545042621069398927">Deskarga bizkortzen.</translation> <translation id="5454166040603940656">Hornitzailea: <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Deskargatu orria</translation> +<translation id="5458366071038729214">Jarraitzaile zaituzten webguneak aurkituko dituzu hemen</translation> <translation id="548278423535722844">Ireki mapa-aplikazio batean</translation> <translation id="5483197086164197190">Chrome-n nabigatzea</translation> <translation id="5487521232677179737">Garbitu datuak</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb index 740c9e3bffb96b..be0132c61b1fb9 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">درحال سرعت بخشیدن به بارگیری.</translation> <translation id="5454166040603940656">با <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">بارگیری صفحه</translation> +<translation id="5458366071038729214">سایتهایی را که دنبال میکنید اینجا پیدا خواهید کرد</translation> <translation id="548278423535722844">باز کردن در برنامه Maps</translation> <translation id="5483197086164197190">پیمایش در Chrome</translation> <translation id="5487521232677179737">پاک کردن دادهها</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb index 8b9ed0fff2895d..20e34d0dbd9bf0 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb @@ -684,6 +684,7 @@ Jos haluat muokata asetusta, <ph name="BEGIN_LINK" />nollaa synkronointi<ph name <translation id="545042621069398927">Lataustasi nopeutetaan</translation> <translation id="5454166040603940656">palvelulla <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Lataa sivu</translation> +<translation id="5458366071038729214">Löydät seuraamasi sivustot täältä</translation> <translation id="548278423535722844">Avaa karttasovelluksessa</translation> <translation id="5483197086164197190">Chromessa siirtyminen</translation> <translation id="5487521232677179737">Poista tiedot</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb index 011c5377635be8..6e27ba6f22a37c 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb @@ -684,6 +684,7 @@ Pour modifier ce paramètre, <ph name="BEGIN_LINK" />réinitialisez la synchroni <translation id="545042621069398927">Accélération de votre téléchargement en cours…</translation> <translation id="5454166040603940656">avec <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Télécharger la page</translation> +<translation id="5458366071038729214">Les sites que vous suivez s'afficheront ici</translation> <translation id="548278423535722844">Ouvrir dans l'application Maps</translation> <translation id="5483197086164197190">Naviguer dans Chrome</translation> <translation id="5487521232677179737">Effacer les données</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb index 970a7ec23bef39..8b5d70579ae98d 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb @@ -684,6 +684,7 @@ Pour modifier ce paramètre, <ph name="BEGIN_LINK" />réinitialisez la synchroni <translation id="545042621069398927">Accélération du téléchargement…</translation> <translation id="5454166040603940656">avec <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Télécharger la page</translation> +<translation id="5458366071038729214">Les sites que vous suivez s'afficheront ici</translation> <translation id="548278423535722844">Ouvrir dans une application de plans</translation> <translation id="5483197086164197190">Navigate Chrome</translation> <translation id="5487521232677179737">Effacer les données</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb index 3ae0a3ae1e2b5d..9c66982fce4e0f 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb @@ -684,6 +684,7 @@ Para cambiar esta opción de configuración, deberás <ph name="BEGIN_LINK" />re <translation id="545042621069398927">Estase acelerando a descarga.</translation> <translation id="5454166040603940656">con <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Descargar páxina</translation> +<translation id="5458366071038729214">Aquí atoparás os sitios que segues</translation> <translation id="548278423535722844">Abrir na aplicación de mapas</translation> <translation id="5483197086164197190">Navega por Chrome</translation> <translation id="5487521232677179737">Borrar datos</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb index d42de2f28f63c8..834297836aefbd 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">आपके डाउनलोड की गति बढ़ाई जा रही है.</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> के साथ</translation> <translation id="5456381639095306749">पेज डाउनलोड करें</translation> +<translation id="5458366071038729214">यहां आपको वे साइटें दिखेंगी जिन्हें आप फ़ॉलो करते हैं</translation> <translation id="548278423535722844">मैप ऐप्लिकेशन में खोलें</translation> <translation id="5483197086164197190">Navigate Chrome</translation> <translation id="5487521232677179737">डेटा साफ़ करें</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb index 7b8ae7872b476b..105bb343031123 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb @@ -683,6 +683,7 @@ Da biste promijenili tu postavku, <ph name="BEGIN_LINK" />poništite sinkronizac <translation id="545042621069398927">Ubrzavanje preuzimanja.</translation> <translation id="5454166040603940656">uz <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Preuzmi stranicu</translation> +<translation id="5458366071038729214">Ovdje ćete pronaći stranice koje pratite</translation> <translation id="548278423535722844">Otvori u aplikaciji za karte</translation> <translation id="5483197086164197190">Kretanje Chromeom</translation> <translation id="5487521232677179737">Izbriši podatke</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb index e6d8cc754acc25..9d622fc9ee1c05 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb @@ -684,6 +684,7 @@ A beállítás módosításához <ph name="BEGIN_LINK" />állítsa vissza a szin <translation id="545042621069398927">Letöltés felgyorsítása…</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> szolgáltatóval</translation> <translation id="5456381639095306749">Oldal letöltése</translation> +<translation id="5458366071038729214">A követett webhelyeket itt láthatja majd</translation> <translation id="548278423535722844">Megnyitás térképalkalmazásban</translation> <translation id="5483197086164197190">Navigáció a Chrome-ban</translation> <translation id="5487521232677179737">Adatok törlése</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb index c07f874308be03..023b38faa28d07 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb @@ -684,6 +684,7 @@ Privacy Sandbox-ը դեռևս մշակման փուլում է և հասանել <translation id="545042621069398927">Ներբեռնումն արագացվում է։</translation> <translation id="5454166040603940656"><ph name="PROVIDER" />-ի հետ</translation> <translation id="5456381639095306749">Ներբեռնել էջը</translation> +<translation id="5458366071038729214">Կայքերը, որոնց հետևում եք, կցուցադրվեն այստեղ</translation> <translation id="548278423535722844">Բացեք Քարտեզներ հավելվածում</translation> <translation id="5483197086164197190">Նավիգացիա Chrome-ում</translation> <translation id="5487521232677179737">Ջնջել տվյալները</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb index 529989e382f3a7..45718c621335b1 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb @@ -684,6 +684,7 @@ Untuk mengubah setelan ini, <ph name="BEGIN_LINK" />reset sinkronisasi<ph name=" <translation id="545042621069398927">Mempercepat download.</translation> <translation id="5454166040603940656">dengan <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Download halaman</translation> +<translation id="5458366071038729214">Anda akan menemukan situs yang Anda ikuti di sini</translation> <translation id="548278423535722844">Buka di aplikasi peta</translation> <translation id="5483197086164197190">Navigate Chrome</translation> <translation id="5487521232677179737">Hapus data</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb index 30839a1816a319..7e45cb462acef1 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb @@ -684,6 +684,7 @@ Til að breyta þessari stillingu skaltu <ph name="BEGIN_LINK" />endurstilla sam <translation id="545042621069398927">Flýtir fyrir niðurhali.</translation> <translation id="5454166040603940656">hjá <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Sækja síðu</translation> +<translation id="5458366071038729214">Hér birtast vefsvæði sem þú fylgir</translation> <translation id="548278423535722844">Opna í kortaforriti</translation> <translation id="5483197086164197190">Flettu í Chrome</translation> <translation id="5487521232677179737">Hreinsa gögn</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb index 7eeb1f2094b91b..96f7cf2a6a2c70 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb @@ -684,6 +684,7 @@ Per cambiare questa impostazione, <ph name="BEGIN_LINK" />reimposta la sincroniz <translation id="545042621069398927">Accelerazione del download in corso.</translation> <translation id="5454166040603940656">con <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Scarica la pagina</translation> +<translation id="5458366071038729214">Qui troverai i siti che segui</translation> <translation id="548278423535722844">Apri nell'app di mappe</translation> <translation id="5483197086164197190">Esplorare Chrome</translation> <translation id="5487521232677179737">Cancella dati</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb index 265a5665501117..0166f70d8b9346 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">הדפדפן מאיץ את ההורדה.</translation> <translation id="5454166040603940656">עם <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">הורדת דף זה</translation> +<translation id="5458366071038729214">כאן יוצגו האתרים שיתווספו למעקב</translation> <translation id="548278423535722844">פתיחה באפליקציית מפות</translation> <translation id="5483197086164197190">ניווט ב-Chrome</translation> <translation id="5487521232677179737">ניקוי נתונים</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb index f1947f8a1a411b..6adba7dac68608 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">მიმდინარეობს ჩამოტვირთვის აჩქარება.</translation> <translation id="5454166040603940656"><ph name="PROVIDER" />-ით</translation> <translation id="5456381639095306749">გვერდის ჩამოტვირთვა</translation> +<translation id="5458366071038729214">აქ იპოვით საიტებს, რომლებსაც თვალს ადევნებთ</translation> <translation id="548278423535722844">რუკების აპში გახსნა</translation> <translation id="5483197086164197190">Chrome-ში ნავიგაცია</translation> <translation id="5487521232677179737">მონაცემების წაშლა</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb index f13c6284794bff..0469225f767e8b 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb @@ -684,6 +684,7 @@ Google есептік жазбасының шолу тарихы басқа Goog <translation id="545042621069398927">Жылдамырақ жүктеп алынуда.</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> провайдерімен</translation> <translation id="5456381639095306749">Жүктеп алу беті</translation> +<translation id="5458366071038729214">Жазылған сайттарыңыз осы жерде көрсетіледі.</translation> <translation id="548278423535722844">Maps қолданбасында ашу</translation> <translation id="5483197086164197190">Chrome браузерін шарлау</translation> <translation id="5487521232677179737">Деректерді жою</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb index 87eae5b502cd71..4d89e548aec6dd 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb @@ -684,6 +684,7 @@ Privacy Sandbox កំពុងស្ថិតនៅក្នុងការអ <translation id="545042621069398927">កំពុងបង្កើនល្បឿននៃការទាញយករបស់អ្នក។</translation> <translation id="5454166040603940656">ជាមួយ <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">ទាញយកទំព័រ</translation> +<translation id="5458366071038729214">អ្នកនឹងឃើញគេហទំព័រដែលអ្នកតាមដាននៅទីនេះ</translation> <translation id="548278423535722844">បើកនៅក្នុងកម្មវិធីផែនទី</translation> <translation id="5483197086164197190">រុករក Chrome</translation> <translation id="5487521232677179737">ជម្រះទិន្នន័យ</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb index 3ac9129d21641d..488445fdceb4bf 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb @@ -473,7 +473,7 @@ <translation id="4062305924942672200">ಕಾನೂನು ಮಾಹಿತಿ</translation> <translation id="4084682180776658562">ಬುಕ್ಮಾರ್ಕ್</translation> <translation id="4084712963632273211"><ph name="PUBLISHER_ORIGIN" /> ಅವರಿಂದ – <ph name="BEGIN_DEEMPHASIZED" />Google ನಿಂದ ವಿತರಿಸಲಾಗಿದೆ<ph name="END_DEEMPHASIZED" /></translation> -<translation id="4095146165863963773">ಅಪ್ಲಿಕೇಶನ್ ಡೇಟಾ ಅಳಿಸುವುದೇ?</translation> +<translation id="4095146165863963773">ಆ್ಯಪ್ ಡೇಟಾ ಅಳಿಸಬೇಕೇ?</translation> <translation id="4095189195365058471">ನಂತರ ಓದಿ <ph name="BEGIN_NEW" />ಹೊಸತು<ph name="END_NEW" /></translation> <translation id="4099578267706723511">Google ಗೆ ಬಳಕೆಯ ಅಂಕಿಅಂಶಗಳು ಮತ್ತು ಕ್ರ್ಯಾಶ್ ವರದಿಗಳನ್ನು ಕಳುಹಿಸುವ ಮೂಲಕ Chrome ಅನ್ನು ಉತ್ತಮಗೊಳಿಸಲು ಸಹಾಯ ಮಾಡಿ.</translation> <translation id="410351446219883937">ಆಟೋಪ್ಲೇ</translation> @@ -684,6 +684,7 @@ <translation id="545042621069398927">ನಿಮ್ಮ ಡೌನ್ಲೋಡ್ನ ವೇಗವನ್ನು ಹೆಚ್ಚಿಸಲಾಗುತ್ತಿದೆ.</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> ಜೊತೆಗೆ</translation> <translation id="5456381639095306749">ಪುಟ ಡೌನ್ಲೋಡ್ ಮಾಡಿ</translation> +<translation id="5458366071038729214">ನೀವು ಫಾಲೋ ಮಾಡುವ ಸೈಟ್ಗಳನ್ನು ಇಲ್ಲಿ ಹುಡುಕಬಹುದು</translation> <translation id="548278423535722844">ನಕ್ಷೆಗಳ ಅಪ್ಲಿಕೇಶನ್ನಲ್ಲಿ ತೆರೆಯಿರಿ</translation> <translation id="5483197086164197190">Chrome ಅನ್ನು ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ</translation> <translation id="5487521232677179737">ಡೇಟಾ ತೆರವುಗೊಳಿಸು</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb index b082edb0f55307..49896d634c3eea 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">다운로드 속도 향상</translation> <translation id="5454166040603940656">제공업체: <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">다운로드 페이지</translation> +<translation id="5458366071038729214">팔로우하는 사이트가 여기에 표시됩니다</translation> <translation id="548278423535722844">지도 앱에서 열기</translation> <translation id="5483197086164197190">Chrome 탐색하기</translation> <translation id="5487521232677179737">인터넷 사용 기록 삭제</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb index 4149477ad148bc..af6c15d6c57a9d 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb @@ -684,6 +684,7 @@ Google аккаунтуңуздун башка Google кызматтарынан <translation id="545042621069398927">Файл ылдам жүктөлүп алынууда.</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> менен</translation> <translation id="5456381639095306749">Баракты жүктөп алуу</translation> +<translation id="5458366071038729214">Жазылган сайттарды ушул жерден табасыз</translation> <translation id="548278423535722844">Карталар колдонмосунан ачыңыз</translation> <translation id="5483197086164197190">Chrome'до чабыттаңыз</translation> <translation id="5487521232677179737">Дайын-даректерди өчүрүү</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb index 8c7029b310f52a..ae2192ebdc17d7 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb @@ -684,6 +684,7 @@ Privacy Sandbox ຍັງຢູ່ໃນລະຫວ່າງການພັດ <translation id="545042621069398927">ກຳລັງເພີ່ມຄວາມໄວໃຫ້ການດາວໂຫຼດຂອງທ່ານ.</translation> <translation id="5454166040603940656">ກັບ <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">ໜ້າການດາວໂຫຼດ</translation> +<translation id="5458366071038729214">ທ່ານຈະພົບເວັບໄຊທີ່ທ່ານຕິດຕາມຢູ່ບ່ອນນີ້</translation> <translation id="548278423535722844">ເປີດໃນແອັບແຜນທີ່</translation> <translation id="5483197086164197190">ໄປຍັງສ່ວນຕ່າງໆຂອງ Chrome</translation> <translation id="5487521232677179737">ລຶບລ້າງຂໍ້ມູນ</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb index e9bfd83854e409..e2994249602147 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb @@ -684,6 +684,7 @@ Jei norite pakeisti šį nustatymą, <ph name="BEGIN_LINK" />iš naujo nustatyki <translation id="545042621069398927">Paspartinamas atsisiuntimas.</translation> <translation id="5454166040603940656">naudojant <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Atsisiųsti puslapį</translation> +<translation id="5458366071038729214">Stebimas svetaines rasite čia</translation> <translation id="548278423535722844">Atidaryti Žemėlapių programoje</translation> <translation id="5483197086164197190">Naršyti „Chrome“</translation> <translation id="5487521232677179737">Išvalyti duomenis</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb index 27c68cdb02ef22..cb3a8c2259b9b8 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb @@ -684,6 +684,7 @@ Lai mainītu šo iestatījumu, <ph name="BEGIN_LINK" />atiestatiet sinhronizāci <translation id="545042621069398927">Lejupielāde tiek paātrināta.</translation> <translation id="5454166040603940656">izmantojot <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Lejupielādēt lapu</translation> +<translation id="5458366071038729214">Šeit būs redzamas vietnes, kurām sekojat</translation> <translation id="548278423535722844">Atvērt karšu lietotnē</translation> <translation id="5483197086164197190">Navigācija pārlūkā Chrome</translation> <translation id="5487521232677179737">Notīrīt datus</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb index 0d8579f3078c58..44d53174138b43 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb @@ -684,6 +684,7 @@ Privacy Sandbox сѐ уште активно се развива и таа е д <translation id="545042621069398927">Го забрзуваме вашето преземање.</translation> <translation id="5454166040603940656">со <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Преземете ја страницата</translation> +<translation id="5458366071038729214">Сајтовите што ги следите ќе ги најдете тука</translation> <translation id="548278423535722844">Отвори во апликацијата „Карти“</translation> <translation id="5483197086164197190">Навигација во Chrome</translation> <translation id="5487521232677179737">Избриши податоци</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb index 845391c2c27b96..e88d7889b7e205 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">तुमच्या डाउनलोडचा वेग वाढवत आहे.</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> सह</translation> <translation id="5456381639095306749">पेज डाउनलोड करा</translation> +<translation id="5458366071038729214">तुम्ही फॉलो करत असलेल्या साइट तुम्हाला येथे दिसतील</translation> <translation id="548278423535722844">नकाशे ॲपमध्ये उघडा</translation> <translation id="5483197086164197190">Chrome नेव्हिगेट करा</translation> <translation id="5487521232677179737">डेटा साफ करा</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb index d146d013c154d0..d9bd29aad0929f 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb @@ -684,6 +684,7 @@ Untuk menukar tetapan ini, <ph name="BEGIN_LINK" />tetapkan semula penyegerakan< <translation id="545042621069398927">Mempercepatkan muat turun anda.</translation> <translation id="5454166040603940656">dengan <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Muat turun halaman</translation> +<translation id="5458366071038729214">Anda akan menemukan laman yang anda ikuti di sini</translation> <translation id="548278423535722844">Buka dalam apl peta</translation> <translation id="5483197086164197190">Navigasi Chrome</translation> <translation id="5487521232677179737">Kosongkan data</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb index 03fa68c806a5ca..cb47e894ed1ac9 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">သင်၏ ဒေါင်းလုဒ်ကို အရှိန်မြှင့်တင်ခြင်း။</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> ဖြင့်</translation> <translation id="5456381639095306749">ဒေါင်းလုဒ်စာမျက်နှာ</translation> +<translation id="5458366071038729214">သင်လိုက်ကြည့်သော ဝဘ်ဆိုက်များကို ဤနေရာတွင် တွေ့ရပါမည်</translation> <translation id="548278423535722844">မြေပုံအက်ပ်တွင် ဖွင့်ပါ</translation> <translation id="5483197086164197190">Navigate Chrome</translation> <translation id="5487521232677179737">ဒေတာများကို ရှင်းလင်းပါ</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb index e6fb23587044c5..671c3212505fc7 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb @@ -684,6 +684,7 @@ Voor je Google-account kunnen andere vormen van browsegeschiedenis (zoals zoekop <translation id="545042621069398927">Je download wordt versneld.</translation> <translation id="5454166040603940656">met <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Pagina downloaden</translation> +<translation id="5458366071038729214">Hier vind je de sites die je volgt</translation> <translation id="548278423535722844">Openen in app voor passen</translation> <translation id="5483197086164197190">Navigeren in Chrome</translation> <translation id="5487521232677179737">Gegevens wissen</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb index 8dce969f42f27b..a20928d5614fb3 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb @@ -684,6 +684,7 @@ For å endre denne innstillingen, <ph name="BEGIN_LINK" />tilbakestill synkronis <translation id="545042621069398927">Øker hastigheten på nedlastingen.</translation> <translation id="5454166040603940656">med <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Last ned siden</translation> +<translation id="5458366071038729214">Her finner du nettsteder du følger</translation> <translation id="548278423535722844">Åpne i en kartapp</translation> <translation id="5483197086164197190">Naviger i Chrome</translation> <translation id="5487521232677179737">Slett data</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb index 9ab0358b676384..7585102f133980 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb @@ -684,6 +684,7 @@ Aby zmienić to ustawienie, <ph name="BEGIN_LINK" />zresetuj synchronizację<ph <translation id="545042621069398927">Przyspieszam pobieranie.</translation> <translation id="5454166040603940656">za pomocą <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Pobierz stronę</translation> +<translation id="5458366071038729214">Tu znajdziesz witryny, które obserwujesz</translation> <translation id="548278423535722844">Otwórz w aplikacji z mapami</translation> <translation id="5483197086164197190">Poruszanie się w Chrome</translation> <translation id="5487521232677179737">Wyczyść dane</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb index 2d676b1080f67c..46080ffbebd5db 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb @@ -685,6 +685,7 @@ Para alterar essa configuração, <ph name="BEGIN_LINK" />redefina a sincroniza <translation id="545042621069398927">Acelerando seu download.</translation> <translation id="5454166040603940656">com <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Fazer o download da página</translation> +<translation id="5458366071038729214">Você verá os sites que você seguir aqui</translation> <translation id="548278423535722844">Abrir no app de mapa</translation> <translation id="5483197086164197190">Navegar no Chrome</translation> <translation id="5487521232677179737">Limpar dados</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb index dddbe1cfc44c5d..58f064ce8977c7 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb @@ -684,6 +684,7 @@ Para alterar esta definição, <ph name="BEGIN_LINK" />reponha a sincronização <translation id="545042621069398927">A acelerar a transferência…</translation> <translation id="5454166040603940656">com <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Transferir página</translation> +<translation id="5458366071038729214">Encontrará os sites que segue aqui</translation> <translation id="548278423535722844">Abrir na aplicação de mapas</translation> <translation id="5483197086164197190">Navegue no Chrome</translation> <translation id="5487521232677179737">Limpar dados</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb index 0555bb8f6835d4..c7c8c7c06dfc91 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb @@ -684,6 +684,7 @@ Pentru a modifica această setare, <ph name="BEGIN_LINK" />resetează sincroniza <translation id="545042621069398927">Se accelerează descărcarea.</translation> <translation id="5454166040603940656">cu <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Descarcă pagina</translation> +<translation id="5458366071038729214">Aici vei vedea site-urile pe care le urmărești</translation> <translation id="548278423535722844">Deschide în aplicația Maps</translation> <translation id="5483197086164197190">Navigarea în Chrome</translation> <translation id="5487521232677179737">Șterge datele</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb index f4d2fdcdd2064a..6548584fec7e5a 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">Ускорение скачивания…</translation> <translation id="5454166040603940656">с помощью <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Скачать страницу</translation> +<translation id="5458366071038729214">Здесь будут сайты, на которые вы подпишетесь.</translation> <translation id="548278423535722844">Показать на карте</translation> <translation id="5483197086164197190">Navigate Chrome</translation> <translation id="5487521232677179737">Удалить данные</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb index f266cf2747ead8..fe460e39528b1e 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb @@ -684,6 +684,7 @@ Ak chcete toto nastavenie zmeniť, <ph name="BEGIN_LINK" />resetujte synchroniz <translation id="545042621069398927">Sťahovanie sa zrýchľuje.</translation> <translation id="5454166040603940656">s poskytovateľom <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Stránka sťahovania</translation> +<translation id="5458366071038729214">Tu nájdete weby, ktoré sledujete</translation> <translation id="548278423535722844">Otvorte v aplikácii pre mapy</translation> <translation id="5483197086164197190">Navigácia v Chrome</translation> <translation id="5487521232677179737">Vymazať dáta</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb index 487f9f9691ec73..cef73690c5ed51 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb @@ -684,6 +684,7 @@ V Google Računu so morda druge vrste zgodovine brskanja, kot so iskanja in deja <translation id="545042621069398927">Pospeševanje prenosa.</translation> <translation id="5454166040603940656">pri ponudniku <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Prenos strani</translation> +<translation id="5458366071038729214">Tukaj boste našli spletna mesta, ki jih spremljate.</translation> <translation id="548278423535722844">Odpiranje v aplikaciji z zemljevidi</translation> <translation id="5483197086164197190">Premikanju po Chromu</translation> <translation id="5487521232677179737">Izbriši podatke</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr-Latn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr-Latn.xtb index e253fcebf3dd67..eedd9552ed1f70 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr-Latn.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr-Latn.xtb @@ -684,6 +684,7 @@ Da biste promenili ovo podešavanje, <ph name="BEGIN_LINK" />resetujte sinhroniz <translation id="545042621069398927">Preuzimanje se ubrzava.</translation> <translation id="5454166040603940656">sa dobavljačem <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Preuzmi stranicu</translation> +<translation id="5458366071038729214">Ovde ćete pronaći sajtove koje pratite</translation> <translation id="548278423535722844">Otvorite u aplikaciji za mape</translation> <translation id="5483197086164197190">Krećite se po Chrome-u</translation> <translation id="5487521232677179737">Obriši podatke</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb index 705f3bbeb05989..09d3293ea903fc 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb @@ -684,6 +684,7 @@ Google налог можда има друге облике историје п <translation id="545042621069398927">Преузимање се убрзава.</translation> <translation id="5454166040603940656">са добављачем <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Преузми страницу</translation> +<translation id="5458366071038729214">Овде ћете пронаћи сајтове које пратите</translation> <translation id="548278423535722844">Отворите у апликацији за мапе</translation> <translation id="5483197086164197190">Крећите се по Chrome-у</translation> <translation id="5487521232677179737">Обриши податке</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb index eb28ebdea16afa..4feaa64920260f 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb @@ -684,6 +684,7 @@ Det kan finnas andra former av webbhistorik i Google-kontot på <ph name="BEGIN_ <translation id="545042621069398927">Nedladdningen görs snabbare.</translation> <translation id="5454166040603940656">med <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Ladda ned sida</translation> +<translation id="5458366071038729214">Här hittar du webbplatser som du följer</translation> <translation id="548278423535722844">Öppna i kartapp</translation> <translation id="5483197086164197190">Navigera i Chrome</translation> <translation id="5487521232677179737">Rensa data</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb index 77c9501bc16294..1bfc00c6957679 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb @@ -684,6 +684,7 @@ Ili ubadilishe mipangilio hii, <ph name="BEGIN_LINK" />fanya usawazishaji upya<p <translation id="545042621069398927">Inaongeza kasi ya kupakua faili yako.</translation> <translation id="5454166040603940656">na <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Pakua ukurasa</translation> +<translation id="5458366071038729214">Utapata tovuti unazofuatilia hapa</translation> <translation id="548278423535722844">Fungua katika programu ya ramani</translation> <translation id="5483197086164197190">Kutumia Chrome</translation> <translation id="5487521232677179737">Futa data</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb index b5495d2d1557d9..29eb281f25eea3 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb @@ -684,6 +684,7 @@ Privacy Sandbox ยังอยู่ในระหว่างการพั <translation id="545042621069398927">กำลังเพิ่มความเร็วในการดาวน์โหลด</translation> <translation id="5454166040603940656">กับ <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">ดาวน์โหลดหน้า</translation> +<translation id="5458366071038729214">คุณจะเห็นเว็บไซต์ที่ติดตามที่นี่</translation> <translation id="548278423535722844">เปิดในแอปแผนที่</translation> <translation id="5483197086164197190">ไปยังส่วนต่างๆ ของ Chrome</translation> <translation id="5487521232677179737">ล้างข้อมูล</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb index 7c7e517ed60163..8c2d4bcaf1504f 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb @@ -684,6 +684,7 @@ Bu ayarı değiştirmek için <ph name="BEGIN_LINK" />senkronizasyonu sıfırlay <translation id="545042621069398927">İndirme işleminiz hızlandırılıyor.</translation> <translation id="5454166040603940656"><ph name="PROVIDER" /> ile</translation> <translation id="5456381639095306749">Sayfayı indir</translation> +<translation id="5458366071038729214">Takip ettiğiniz siteleri burada bulursunuz</translation> <translation id="548278423535722844">Haritalar uygulamasında aç</translation> <translation id="5483197086164197190">Chrome'da gezinme</translation> <translation id="5487521232677179737">Verileri temizle</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb index 45b9b5caeeef47..13135ffb195693 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb @@ -684,6 +684,7 @@ Privacy Sandbox підтримує існування відкритої мер <translation id="545042621069398927">Прискорюється завантаження.</translation> <translation id="5454166040603940656">за допомогою <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Завантажити сторінку</translation> +<translation id="5458366071038729214">Тут відображатимуться сайти, на які ви підпишетеся</translation> <translation id="548278423535722844">Відкрити в додатку Карти</translation> <translation id="5483197086164197190">Навігація в Chrome</translation> <translation id="5487521232677179737">Видалити дані</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb index d921b9f25d4496..8d979603be7127 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb @@ -684,6 +684,7 @@ Tài khoản Google của bạn có thể có các dạng lịch sử duyệt we <translation id="545042621069398927">Đang tăng tốc độ tải xuống.</translation> <translation id="5454166040603940656">với <ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Tải trang xuống</translation> +<translation id="5458366071038729214">Bạn sẽ thấy các trang web mình theo dõi tại đây</translation> <translation id="548278423535722844">Mở trong ứng dụng bản đồ</translation> <translation id="5483197086164197190">Thao tác trong Chrome</translation> <translation id="5487521232677179737">Xóa dữ liệu</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb index 62c089b6c150e5..9a8d8322899a9d 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb @@ -684,6 +684,7 @@ <translation id="545042621069398927">正在加快您的下载速度。</translation> <translation id="5454166040603940656">提供方:<ph name="PROVIDER" /></translation> <translation id="5456381639095306749">下载网页</translation> +<translation id="5458366071038729214">您会在此处看到自己已关注的网站</translation> <translation id="548278423535722844">在地图应用中打开</translation> <translation id="5483197086164197190">探索 Chrome</translation> <translation id="5487521232677179737">清除数据</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb index 27d37c817f6e58..b7fc6d2e88a0ff 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb @@ -684,6 +684,7 @@ Privacy Sandbox 仍在開發階段,目前開放地區有限。現在網站可 <translation id="545042621069398927">正在加快下載速度。</translation> <translation id="5454166040603940656">提供者:<ph name="PROVIDER" /></translation> <translation id="5456381639095306749">下載網頁</translation> +<translation id="5458366071038729214">這裡會顯示你追蹤的網站</translation> <translation id="548278423535722844">在地圖應用程式中開啟</translation> <translation id="5483197086164197190">Navigate Chrome</translation> <translation id="5487521232677179737">清除資料</translation> diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb index a9eb2daec7294c..91d431a56c974c 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb @@ -684,6 +684,7 @@ Ukuze ushintshe lesi silungiselelo, <ph name="BEGIN_LINK" />setha kabusha ukuvum <translation id="545042621069398927">Isheshisa ukulanda kwakho.</translation> <translation id="5454166040603940656">ne-<ph name="PROVIDER" /></translation> <translation id="5456381639095306749">Landa ikhasi</translation> +<translation id="5458366071038729214">Uzothola amasayithi owalandelayo lapha</translation> <translation id="548278423535722844">Uhlelo lokusebenza lokuvula kumamephu</translation> <translation id="5483197086164197190">Zulazula ku-Chrome</translation> <translation id="5487521232677179737">Sula idatha</translation> diff --git a/chrome/credential_provider/gaiacp/strings/gaia_resources_ru.xtb b/chrome/credential_provider/gaiacp/strings/gaia_resources_ru.xtb index af8f2db25cbc8f..5308d3f4c1be24 100644 --- a/chrome/credential_provider/gaiacp/strings/gaia_resources_ru.xtb +++ b/chrome/credential_provider/gaiacp/strings/gaia_resources_ru.xtb @@ -10,7 +10,7 @@ <translation id="2844349213149998955">На этом устройстве запрещен вход с личным аккаунтом. Войдите в рабочий аккаунт.</translation> <translation id="3217145568844727893">Если вы продолжите работу, не вводя текущий пароль для Windows, данные на устройстве могут быть безвозвратно утеряны.</translation> <translation id="3306357053520292004">Указанный аккаунт уже используется на этом компьютере. Выполните вход, используя другой аккаунт.</translation> -<translation id="3355053591933237049">Убедитесь, что устройство подключено к Интернету, и повторите попытку.</translation> +<translation id="3355053591933237049">Убедитесь, что устройство подключено к интернету, и повторите попытку.</translation> <translation id="3926852373333893095">Вход разрешен только пользователям G Suite Enterprise.</translation> <translation id="399130515869721714">Не удалось загрузить экран входа в аккаунт Google из-за проблемы, связанной с установкой Chrome. Обратитесь к администратору.</translation> <translation id="4057329986137569701">Произошла внутренняя ошибка.</translation> diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_te.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_te.xtb index 6f3e60c721e5d8..6660b2405d51ad 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_te.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_te.xtb @@ -74,7 +74,7 @@ <translation id="2822354292072154809">మీరు <ph name="CHOSEN_OBJECT_NAME" /> కోసం అన్ని సైట్ అనుమతులను ఖచ్చితంగా రీసెట్ చేయాలనుకుంటున్నారా ?</translation> <translation id="2870560284913253234">సైట్</translation> <translation id="2874939134665556319">మునుపటి ట్రాక్</translation> -<translation id="2903493209154104877">చిరునామాలు</translation> +<translation id="2903493209154104877">అడ్రస్లు</translation> <translation id="2910701580606108292">సైట్లు రక్షిత కంటెంట్ను ప్లే చేయడానికి ముందు అనుమతి కోసం అడుగుతాయి</translation> <translation id="2913331724188855103">కుక్కీ డేటాను సేవ్ చేయడానికి, చదవడానికి సైట్లను అనుమతిస్తుంది (సిఫార్సు చేయబడింది)</translation> <translation id="2968755619301702150">ప్రమాణపత్రం వ్యూయర్</translation> diff --git a/components/policy/resources/policy_templates_es-419.xtb b/components/policy/resources/policy_templates_es-419.xtb index 375f0401dc19fd..e9cc612544fa43 100644 --- a/components/policy/resources/policy_templates_es-419.xtb +++ b/components/policy/resources/policy_templates_es-419.xtb @@ -3896,6 +3896,10 @@ Si ninguna de las entradas tiene un valor de <ph name="CHROMEOS_VERSION_PROPERTY De lo contrario, se ocultarán las direcciones IP locales con nombres de host de mDNS. Ten en cuenta que esta política afecta la protección de las IP locales, si los administradores la habilitan.</translation> <translation id="614662973812186053">Esta política también controla la recopilación de datos de diagnóstico y uso de Android.</translation> +<translation id="6154509171634387825">Advertencia: 3DES se quitará por completo en la versión 95 de <ph name="PRODUCT_NAME" /> (alrededor de octubre de 2021) y esta política dejará de funcionar. + + Si estableces la política como verdadera, se habilitarán los conjuntos de algoritmos de cifrado 3DES en TLS. Si la estableces como falsa, se inhabilitarán los conjuntos. Si no la estableces, los conjuntos de algoritmos de cifrado 3DES estarán inhabilitados de forma predeterminada. Esta política podrá usarse para asegurar la compatibilidad de forma temporal con un servidor desactualizado. Esta es una medida provisoria; deberás volver a configurar el servidor. + </translation> <translation id="6155350825868160236">Permitir que el usuario decida si se usarán los servicios web de Google para solucionar errores de ortografía</translation> <translation id="6155936611791017817">Establece el estado predeterminado del cursor grande en la pantalla de acceso.</translation> <translation id="6157537876488211233">Lista separada por comas de las normas de omisión de proxy</translation> diff --git a/components/policy/resources/policy_templates_es.xtb b/components/policy/resources/policy_templates_es.xtb index 4929b3fc1a6ee9..f01405efb96a52 100644 --- a/components/policy/resources/policy_templates_es.xtb +++ b/components/policy/resources/policy_templates_es.xtb @@ -3912,6 +3912,10 @@ Si se le asigna el valor False, <ph name="PRODUCT_NAME" /> no utilizará notific De lo contrario, las direcciones IP locales se ocultarán con nombres de host mDNS. Ten en cuenta que esta política debilita la protección de las IP locales si así lo necesitan los administradores.</translation> <translation id="614662973812186053">Esta política también controla la recopilación de los datos de uso y diagnóstico de Android.</translation> +<translation id="6154509171634387825">Advertencia: 3DES se eliminará totalmente en la versión 95 de <ph name="PRODUCT_NAME" /> (en torno a octubre del 2021) y esta política dejará de funcionar en ese momento. + + Si se asigna el valor true a esta política, se habilitarán los paquetes de cifrado 3DES en TLS. Si se le asigna el valor false, se inhabilitarán estos paquetes. Si no se le asigna ningún valor, los paquetes de cifrado 3DES estarán inhabilitados de forma predeterminada. Esta política se puede usar para mantener temporalmente la compatibilidad con un servidor obsoleto. Se trata de una solución provisional y se debería volver a configurar el servidor. + </translation> <translation id="6155350825868160236">Permitir que el usuario elija si se utilizan servicios web de Google para corregir errores ortográficos</translation> <translation id="6155936611791017817">Establecer el estado predeterminado del cursor grande en la pantalla de inicio de sesión</translation> <translation id="6157537876488211233">Lista de reglas de omisión de proxy separadas por comas</translation> diff --git a/components/policy/resources/policy_templates_fr.xtb b/components/policy/resources/policy_templates_fr.xtb index 4b7da6f7113997..5ddc76bde876db 100644 --- a/components/policy/resources/policy_templates_fr.xtb +++ b/components/policy/resources/policy_templates_fr.xtb @@ -3886,6 +3886,10 @@ Lorsque cette règle n'est pas configurée, le paramètre par défaut utilisé c Sinon, les adresses IP locales sont masquées avec les noms d'hôte mDNS. Veuillez noter que cette règle affaiblit la protection des adresses IP locales, dans le cas où celle-ci serait requise par les administrateurs.</translation> <translation id="614662973812186053">Cette règle permet également de contrôler la collecte des données d'utilisation et de diagnostic sur les appareils Android.</translation> +<translation id="6154509171634387825">Avertissement : 3DES sera complètement supprimé de <ph name="PRODUCT_NAME" /> dans la version 95 (autour d'octobre 2021). Cette règle cessera alors de fonctionner. + + Si cette règle est définie sur "True", les suites de chiffrement 3DES dans TLS seront activées. Si cette règle est définie sur "False", celles-ci seront désactivées. Si cette règle n'est pas configurée, les suites de chiffrement 3DES sont désactivées par défaut. Cette règle peut être utilisée pour assurer temporairement la compatibilité avec un serveur obsolète. Il s'agit d'une solution provisoire, et il est conseillé de reconfigurer le serveur. + </translation> <translation id="6155350825868160236">Autoriser l'utilisateur à choisir si des services Web Google peuvent être utilisés pour corriger les fautes d'orthographe</translation> <translation id="6155936611791017817">Définir l'état par défaut du grand curseur sur l'écran de connexion</translation> <translation id="6157537876488211233">Liste de règles de contournement de proxy séparées par des virgules</translation> diff --git a/components/policy/resources/policy_templates_id.xtb b/components/policy/resources/policy_templates_id.xtb index 6d5a13b13307dc..fd5970cd5f620a 100644 --- a/components/policy/resources/policy_templates_id.xtb +++ b/components/policy/resources/policy_templates_id.xtb @@ -3913,6 +3913,10 @@ Jika disetel ke Salah (False), <ph name="PRODUCT_NAME" /> tidak akan menggunakan Jika tidak, alamat IP lokal akan disembunyikan dengan hostname mDNS. Perlu diingat bahwa kebijakan ini akan melemahkan perlindungan IP lokal jika dibutuhkan oleh administrator.</translation> <translation id="614662973812186053">Kebijakan ini juga mengontrol pengumpulan data diagnostik dan penggunaan Android.</translation> +<translation id="6154509171634387825">Peringatan: 3DES akan dihapus sepenuhnya dari <ph name="PRODUCT_NAME" /> versi 95 (sekitar Oktober 2021) dan kebijakan ini akan berhenti berfungsi. + + Jika kebijakan disetel ke benar (true), cipher suite 3DES di TLS akan diaktifkan. Jika kebijakan disetel ke salah (false), cipher suite 3DES di TLS akan dinonaktifkan. Jika kebijakan tidak disetel, cipher suite 3DES akan dinonaktifkan secara default. Kebijakan ini dapat digunakan untuk sementara waktu mempertahankan kompatibilitas dengan server yang sudah tidak berlaku. Ini adalah tindakan sementara dan server harus dikonfigurasi ulang. + </translation> <translation id="6155350825868160236">Izinkan pengguna memilih apakah akan menggunakan layanan web Google untuk mengatasi kesalahan ejaan</translation> <translation id="6155936611791017817">Setel status default kursor besar di layar masuk</translation> <translation id="6157537876488211233">Peraturan mengabaikan proxy yang dipisahkan koma</translation> diff --git a/components/policy/resources/policy_templates_it.xtb b/components/policy/resources/policy_templates_it.xtb index 0ea1b5139545fd..8d2053038e0083 100644 --- a/components/policy/resources/policy_templates_it.xtb +++ b/components/policy/resources/policy_templates_it.xtb @@ -3865,6 +3865,10 @@ Per ulteriori informazioni sui contesti sicuri, visita il sito https://www.w3.or In caso contrario, gli indirizzi IP locali vengono nascosti tramite nomi host mDNS. Tieni presente che questo criterio riduce la sicurezza degli indirizzi IP locali se richiesto dagli amministratori.</translation> <translation id="614662973812186053">Questa norma controlla anche la raccolta dei dati diagnostici e sull'utilizzo di Android.</translation> +<translation id="6154509171634387825">Avviso: 3DES verrà completamente rimosso da <ph name="PRODUCT_NAME" /> nella versione 95 (indicativamente a ottobre 2021); in quel momento, questo criterio smetterà di funzionare. + + Se il criterio viene impostato su vero, le suite di crittografia 3DES in TLS verranno attivate. Se viene impostato su falso, verranno disattivate. Se il criterio non viene configurato, le suite di crittografia 3DES sono disattivate per impostazione predefinita. Questo criterio potrebbe essere usato per mantenere momentaneamente la compatibilità con un server obsoleto. Si tratta di una misura temporanea ed è necessario riconfigurare il server. + </translation> <translation id="6155350825868160236">Consenti all'utente di decidere se usare o meno servizi web di Google per correggere gli errori ortografici</translation> <translation id="6155936611791017817">Impostazione stato predefinito del puntatore grande nella schermata di accesso</translation> <translation id="6157537876488211233">Elenco separato da virgole delle regole di bypass proxy</translation> diff --git a/components/policy/resources/policy_templates_ko.xtb b/components/policy/resources/policy_templates_ko.xtb index be1ea8c70c1287..5901036f14fe68 100644 --- a/components/policy/resources/policy_templates_ko.xtb +++ b/components/policy/resources/policy_templates_ko.xtb @@ -3908,6 +3908,10 @@ False로 설정하면 <ph name="PRODUCT_NAME" />에서 시스템 알림을 사 그러지 않으면 로컬 IP 주소가 mDNS 호스트 이름으로 숨겨집니다. 관리자가 필요로 하는 경우 이 정책은 로컬 IP의 보안 수준을 낮춥니다.</translation> <translation id="614662973812186053">이 정책은 Android 사용 및 진단 데이터 수집도 제어합니다.</translation> +<translation id="6154509171634387825">경고: 3DES는 버전 95(2021년 10월경)부터 <ph name="PRODUCT_NAME" />에서 완전히 삭제되고 그 이후에는 정책이 작동하지 않습니다. + + 정책이 true로 설정되면 TLS의 3DES 암호화 스위트가 사용 설정됩니다. false로 설정되면 사용 중지됩니다. 설정되지 않으면 3DES 암호화 스위트가 기본적으로 사용 중지됩니다. 정책은 오래된 서버와 일시적으로 호환성을 유지하는 데 사용될 수 있습니다. 임시방편이므로 서버를 다시 구성해야 합니다. + </translation> <translation id="6155350825868160236">사용자가 맞춤법 오류를 해결하는 Google 웹 서비스의 사용 여부를 선택하도록 허용</translation> <translation id="6155936611791017817">로그인 화면에서 큰 커서의 기본 상태를 설정</translation> <translation id="6157537876488211233">쉼표로 구분된 프록시 우회 규칙 목록</translation> diff --git a/components/policy/resources/policy_templates_nl.xtb b/components/policy/resources/policy_templates_nl.xtb index 7905f7f6651158..ab2d5f994cbf4c 100644 --- a/components/policy/resources/policy_templates_nl.xtb +++ b/components/policy/resources/policy_templates_nl.xtb @@ -3842,6 +3842,10 @@ Voor meer informatie over een beveiligde context ga je naar https://www.w3.org/T Anders worden lokale IP-adressen verborgen met mDNS-hostnamen. Houd er rekening mee dat dit beleid de beveiliging van lokale IP's verzwakt als beheerders dit nodig hebben.</translation> <translation id="614662973812186053">Met dit beleid wordt ook het gebruik van Android en het verzamelen van diagnostische gegevens bepaald.</translation> +<translation id="6154509171634387825">Waarschuwing: 3DES wordt volledig verwijderd uit <ph name="PRODUCT_NAME" /> vanaf versie 95 (rond oktober 2021). Dit beleid werkt dan niet meer. + + Als je het beleid instelt op True, worden 3DES cipher suites in TLS aangezet. Als je het beleid instelt op False, worden ze uitgezet. Als je het beleid niet instelt, staan 3DES cipher suites standaard uit. Je kunt dit beleid gebruiken om de compatibiliteit met een verouderde server tijdelijk te behouden. Dit is slechts een noodoplossing. De server moet opnieuw worden ingesteld. + </translation> <translation id="6155350825868160236">Toestaan dat gebruikers kiezen of Google-webservices worden gebruikt om spelfouten op te lossen</translation> <translation id="6155936611791017817">De standaardstatus van de grote muisaanwijzer op het inlogscherm instellen</translation> <translation id="6157537876488211233">Door komma's gescheiden lijst van regels voor proxyomzeiling</translation> diff --git a/components/policy/resources/policy_templates_pt-BR.xtb b/components/policy/resources/policy_templates_pt-BR.xtb index e3b0956d1a0be5..9758a3c1aa0bdf 100644 --- a/components/policy/resources/policy_templates_pt-BR.xtb +++ b/components/policy/resources/policy_templates_pt-BR.xtb @@ -3888,6 +3888,10 @@ Se esta política for definida como "Falsa", o <ph name="PRODUCT_NAME" /> não u Caso contrário, os endereços IP locais serão ocultos com os nomes de host de mDNS. Observe que, se exigida pelos administradores, esta política enfraquece a proteção dos IPs locais.</translation> <translation id="614662973812186053">Esta política também controla a coleta de dados de uso e diagnóstico do Android.</translation> +<translation id="6154509171634387825">Aviso: o padrão 3DES será completamente removido na versão 95 do <ph name="PRODUCT_NAME" /> por volta de outubro de 2021, e esta política só funcionará até essa data. + + Se esta política for definida como verdadeira, os pacotes de criptografia 3DES em TLS serão ativados. Se ela for definida como falsa, eles serão desativados. Se for deixada sem definição, os pacotes de criptografia 3DES serão desativados por padrão. Esta política pode ser usada para manter temporariamente a compatibilidade com um servidor desatualizado. Esta é uma medida provisória e o servidor precisará ser reconfigurado. + </translation> <translation id="6155350825868160236">Permitir que o usuário escolha se serviços da Web do Google serão usados para solucionar erros de ortografia</translation> <translation id="6155936611791017817">Definir estado padrão do cursor grande na tela de login</translation> <translation id="6157537876488211233">Lista separada por vírgulas das regras de proxies ignoráveis</translation> diff --git a/components/policy/resources/policy_templates_ru.xtb b/components/policy/resources/policy_templates_ru.xtb index 738a0257695f94..aa67873ef7d3ee 100644 --- a/components/policy/resources/policy_templates_ru.xtb +++ b/components/policy/resources/policy_templates_ru.xtb @@ -3874,6 +3874,10 @@ В противном случае локальные IP-адреса скрываются с помощью имен хоста mDNS. Обратите внимание, что это правило ослабляет защиту локальных IP-адресов (если это нужно администратору).</translation> <translation id="614662973812186053">Это правило также контролирует сбор данных об использовании и диагностике Android.</translation> +<translation id="6154509171634387825">Внимание! Начиная с версии 95 (появится приблизительно в октябре 2021 года) в <ph name="PRODUCT_NAME" /> будет полностью прекращена поддержка 3DES. Это правило больше не будет работать. + + Если для правила задано значение True, наборы шифров 3DES в TLS включены. При значении False они отключены. Если правило не настроено, наборы шифров 3DES по умолчанию включены. Правило можно использовать, чтобы временно обеспечить совместимость с устаревшим сервером. Помните, что это временное решение и сервер следует настроить заново. + </translation> <translation id="6155350825868160236">Разрешить пользователю самому решать, использовать ли веб-сервисы Google для проверки правописания</translation> <translation id="6155936611791017817">Наличие или отсутствие большого курсора по умолчанию на экране входа</translation> <translation id="6157537876488211233">Список правил для игнорирования прокси-сервера</translation> diff --git a/components/policy/resources/policy_templates_th.xtb b/components/policy/resources/policy_templates_th.xtb index 943a20231b576a..732fcec58bcffd 100644 --- a/components/policy/resources/policy_templates_th.xtb +++ b/components/policy/resources/policy_templates_th.xtb @@ -3834,6 +3834,10 @@ หากไม่ ระบบจะปกปิดที่อยู่ IP ของเครื่องโดยใช้ชื่อโฮสต์ mDNS แทน โปรดทราบว่าหากผู้ดูแลระบบจำเป็นต้องปกป้อง IP ของเครื่อง นโยบายนี้จะทำให้การปกป้องนั้นด้อยประสิทธิภาพลง</translation> <translation id="614662973812186053">นโยบายนี้จะยังควบคุมการใช้งาน Android และการรวบรวมข้อมูลการวินิจฉัยด้วยเช่นกัน</translation> +<translation id="6154509171634387825">คำเตือน: 3DES จะถูกนำออกจาก <ph name="PRODUCT_NAME" /> เวอร์ชัน 95 อย่างสมบูรณ์ (ประมาณเดือนตุลาคม 2021) และเมื่อนั้นนโยบายนี้จะหยุดทำงาน + + หากตั้งค่านโยบายนี้เป็น "จริง" จะเปิดใช้ชุดการเข้ารหัส 3DES ใน TLS หากตั้งค่าเป็น "เท็จ" จะปิดใช้ชุดการเข้ารหัสดังกล่าว หากไม่ได้ตั้งค่านโยบาย โดยค่าเริ่มต้นชุดการเข้ารหัส 3DES จะปิดใช้อยู่ ระบบอาจใช้นโยบายนี้เพื่อรักษาความเข้ากันได้กับเซิร์ฟเวอร์ที่ล้าสมัยเป็นการชั่วคราว ซึ่งเป็นมาตรการที่ใช้ทดแทนและควรจะต้องมีการกำหนดค่าเซิร์ฟเวอร์ใหม่ + </translation> <translation id="6155350825868160236">อนุญาตให้ผู้ใช้เลือกหากใช้บริการเว็บของ Google เพื่อแก้ไขข้อผิดพลาดของการสะกดคำ</translation> <translation id="6155936611791017817">ตั้งค่าสถานะเริ่มต้นของเคอร์เซอร์ขนาดใหญ่บนหน้าจอการเข้าสู่ระบบ</translation> <translation id="6157537876488211233">รายการกฎการข้ามพร็อกซีที่คั่นด้วยเครื่องหมายจุลภาค</translation> diff --git a/components/policy/resources/policy_templates_tr.xtb b/components/policy/resources/policy_templates_tr.xtb index f630484370679c..95a2dc1a5bc68c 100644 --- a/components/policy/resources/policy_templates_tr.xtb +++ b/components/policy/resources/policy_templates_tr.xtb @@ -3855,6 +3855,10 @@ Bu ayarı etkinleştirirseniz veya yapılandırmazsanız kullanıcılar şifrele Aksi takdirde, yerel IP adresleri mDNS ana makine adlarıyla gizlenir. Bu politikanın, yöneticilerin ihtiyaç duyması halinde yerel IP'lerin korunmasını zayıflattığını lütfen unutmayın.</translation> <translation id="614662973812186053">Bu politika, Android kullanımını ve teşhis verilerini toplama çalışmalarını da kontrol eder.</translation> +<translation id="6154509171634387825">Uyarı: 3DES, 95 sürümünde (Ekim 2021 civarında) <ph name="PRODUCT_NAME" /> ürününden tamamen kaldırılacak ve bu politika artık kullanılamayacaktır. + + Politika doğru değerine ayarlanırsa TLS'de 3DES şifre paketleri etkinleştirilir. Politika yanlış değerine ayarlanırsa bunlar devre dışı bırakılır. Politika ayarlanmazsa 3DES şifre paketleri varsayılan olarak devre dışı bırakılır. Bu politika eski bir sunucuyla uyumluluğu sürdürmek için geçici olarak kullanılabilir. Bu geçici bir tedbir olup sunucu yeniden yapılandırılmalıdır. + </translation> <translation id="6155350825868160236">Kullanıcının, Google web hizmetlerinin yazım hatalarını çözmek için kullanılıp kullanılmayacağını seçmesine izin ver</translation> <translation id="6155936611791017817">Giriş ekranında büyük imleç modunun varsayılan durumunu ayarla</translation> <translation id="6157537876488211233">Proxy atlama kurallarının noktalı virgül ile ayrılmış listesi</translation> diff --git a/components/policy/resources/policy_templates_uk.xtb b/components/policy/resources/policy_templates_uk.xtb index b89793dae060e8..634aebd3264e59 100644 --- a/components/policy/resources/policy_templates_uk.xtb +++ b/components/policy/resources/policy_templates_uk.xtb @@ -3911,6 +3911,10 @@ В інших випадках імена хостів mDNS приховують локальні IP-адреси. Зауважте, що це правило послаблює захист локальних IP-адрес (якщо це вимагають адміністратори).</translation> <translation id="614662973812186053">Це правило також керує збиранням даних про використання та діагностику додатків Android.</translation> +<translation id="6154509171634387825">Попередження: шифри 3DES буде видалено з <ph name="PRODUCT_NAME" /> у версії 95 (приблизно в жовтні 2021 року). Тоді ж перестане працювати це правило. + + Якщо для цього правила вибрати значення true, набори шрифтів 3DES у TLS буде ввімкнено. Якщо вибрати значення false, їх буде вимкнено. Якщо це правило не налаштувати, набори шрифтів 3DES будуть вимкнені за умовчанням. Це правило можна застосовувати, щоб підтримувати сумісність із застарілим сервером. Це тимчасовий захід, налаштування сервера потрібно змінити. + </translation> <translation id="6155350825868160236">Дозволити користувачам вибирати, чи використовувати веб-сервіси Google для виправлення орфографічних помилок</translation> <translation id="6155936611791017817">Налаштувати стан великого курсора за умовчанням на екрані входу</translation> <translation id="6157537876488211233">Розділений комами список правил обходу проксі-сервера</translation> diff --git a/components/policy/resources/policy_templates_vi.xtb b/components/policy/resources/policy_templates_vi.xtb index 2277ad84b4958d..f81a014eddd12c 100644 --- a/components/policy/resources/policy_templates_vi.xtb +++ b/components/policy/resources/policy_templates_vi.xtb @@ -1871,7 +1871,7 @@ Khi chính sách này được đặt thành false hoặc không được địn Chỉ định khoảng thời gian kể từ lần cuối cùng người dùng nhập cho đến thời điểm hộp thoại cảnh báo hiển thị khi chạy bằng pin. - Khi bạn đặt, chính sách này sẽ chỉ định khoảng thời gian người dùng phải duy trì chế độ tạm vắng trước khi <ph name="PRODUCT_OS_NAME" /> hiển thị hộp thoại cảnh báo cho người dùng biết rằng hành động ở chế độ tạm vắng đó sắp được thực hiện. + Khi bạn đặt, chính sách này sẽ chỉ định khoảng thời gian người dùng phải duy trì chế độ tạm vắng trước khi <ph name="PRODUCT_OS_NAME" /> hiện hộp thoại cảnh báo cho người dùng biết rằng hành động ở chế độ tạm vắng đó sắp được thực hiện. Khi bạn không đặt chính sách này, sẽ không có hộp thoại cảnh báo nào hiển thị. @@ -3781,7 +3781,7 @@ Nếu bạn đặt chính sách thành Tắt, thì <ph name="PRODUCT_NAME" /> s <translation id="5950069117106131681">Nếu bạn đặt chính sách này thành Bật, đầu trang và chân trang ở chế độ xem trước bản in sẽ được bật. Nếu bạn đặt chính sách này thành Tắt, đầu trang và chân trang ở chế độ xem trước bản in sẽ bị tắt. Nếu bạn đặt chính sách này, người dùng sẽ không thể thay đổi được. Nếu bạn không đặt chính sách này, người dùng sẽ quyết định có để đầu trang và chân trang xuất hiện hay không.</translation> -<translation id="5951418260805607969">Hiển thị thông báo khi dung lượng ổ đĩa sắp hết</translation> +<translation id="5951418260805607969">Hiện thông báo khi dung lượng ổ đĩa sắp hết</translation> <translation id="5958746038080720143">Bật tính năng tối ưu hóa Web Proxy Auto-Discovery (WPAD) (Tự động phát hiện proxy web)</translation> <translation id="5959428851851090097">Nếu đặt chính sách này thành Bật, thì chính sách đám mây sẽ được ưu tiên nếu chính sách này xung đột với chính sách nền tảng. @@ -3916,6 +3916,10 @@ Nếu bạn đặt chính sách thành Tắt, thì <ph name="PRODUCT_NAME" /> s Nếu không, địa chỉ IP cục bộ sẽ được che giấu bằng tên máy chủ mDNS. Xin lưu ý rằng chính sách này sẽ làm yếu đi chức năng bảo vệ của IP cục bộ nếu quản trị viên cần.</translation> <translation id="614662973812186053">Chính sách này cũng kiểm soát việc thu thập dữ liệu chẩn đoán và sử dụng Android.</translation> +<translation id="6154509171634387825">Cảnh báo: Bộ thuật toán mật mã 3DES sẽ bị xóa hoàn toàn khỏi <ph name="PRODUCT_NAME" /> trong phiên bản 95 (vào khoảng tháng 10 năm 2021). Khi đó, chính sách này sẽ ngừng hoạt động. + + Nếu bạn đặt chính sách này thành bật, bộ thuật toán mật mã 3DES trong TLS sẽ được bật. Bộ thuật toán mật mã sẽ bị tắt nếu bạn đặt chính sách này thành tắt. Nếu bạn không đặt chính sách này, bộ thuật toán mật mã 3DES sẽ bị tắt theo mặc định. Bạn có thể dùng chính sách này để tạm thời duy trì khả năng tương thích với một máy chủ lỗi thời. Đây chỉ là giải pháp thay thế tạm thời nên bạn cần thiết lập lại máy chủ. + </translation> <translation id="6155350825868160236">Cho phép người dùng chọn xem có sử dụng các dịch vụ web của Google để sửa lỗi chính tả hay không</translation> <translation id="6155936611791017817">Đặt trạng thái của con trỏ lớn mặc định trên màn hình đăng nhập</translation> <translation id="6157537876488211233">Danh sách quy tắc bỏ qua proxy được phân cách bằng dấu phẩy</translation> @@ -4038,7 +4042,7 @@ Nếu bạn đặt chính sách thành Tắt, thì <ph name="PRODUCT_NAME" /> s Chỉ định khoảng thời gian kể từ lần cuối cùng người dùng nhập cho đến thời điểm hộp thoại cảnh báo hiển thị khi chạy bằng nguồn điện xoay chiều. - Khi bạn đặt, chính sách này sẽ chỉ định khoảng thời gian người dùng phải duy trì chế độ tạm vắng trước khi <ph name="PRODUCT_OS_NAME" /> hiển thị hộp thoại cảnh báo cho người dùng biết rằng hành động ở chế độ tạm vắng đó sắp được thực hiện. + Khi bạn đặt, chính sách này sẽ chỉ định khoảng thời gian người dùng phải duy trì chế độ tạm vắng trước khi <ph name="PRODUCT_OS_NAME" /> hiện hộp thoại cảnh báo cho người dùng biết rằng hành động ở chế độ tạm vắng đó sắp được thực hiện. Khi bạn không đặt chính sách này, sẽ không có hộp thoại cảnh báo nào hiển thị. @@ -5148,7 +5152,7 @@ Nếu bạn đặt chính sách thành Tắt, thì <ph name="PRODUCT_NAME" /> s Lưu ý: <ph name="DEVICE_LOGIN_SCREEN_LARGE_CURSOR_ENABLED" /> (nếu đã được chỉ định) sẽ ghi đè chính sách này.</translation> <translation id="7632147323011514740">Các khoảng thời gian mà quá trình cập nhật ảnh chụp nhanh dữ liệu ARC có thể bắt đầu cho Phiên khách được quản lý</translation> <translation id="7632724434767231364">Tên thư viện GSSAPI</translation> -<translation id="7635106595080609261">Khi bạn đặt thành Bật hoặc không đặt chính sách này, Chrome có thể hiển thị hộp thoại chọn tệp và người dùng có thể mở hộp thoại này. +<translation id="7635106595080609261">Khi bạn đặt thành Bật hoặc không đặt chính sách này, Chrome có thể hiện hộp thoại chọn tệp và người dùng có thể mở hộp thoại này. Khi bạn đặt chính sách này thành Tắt, bất cứ khi nào người dùng thực hiện thao tác làm kích hoạt hộp thoại chọn tệp (chẳng hạn như nhập dấu trang, tải tệp lên, lưu đường liên kết, v.v), một thông báo sẽ xuất hiện. Người dùng được xem là đã nhấp vào nút Hủy trên hộp thoại chọn tệp.</translation> <translation id="7638300388094655454">Google Cast</translation> @@ -5188,7 +5192,7 @@ Nếu bạn đặt chính sách thành Tắt, thì <ph name="PRODUCT_NAME" /> s Khi bạn không đặt chính sách này, khoảng thời gian mặc định sẽ được sử dụng. Bạn phải chỉ định giá trị của chính sách bằng mili giây. Các giá trị được giới hạn ở mức nhỏ hơn hoặc bằng thời gian chờ tắt màn hình (nếu có đặt thời gian này) và thời gian chờ khi ở chế độ tạm vắng.</translation> -<translation id="7680437377926096177">Ngăn hiển thị hộp thoại đăng xuất khi cửa sổ cuối cùng đóng lại.</translation> +<translation id="7680437377926096177">Ngăn hiện hộp thoại đăng xuất khi cửa sổ cuối cùng đóng lại.</translation> <translation id="7683777542468165012">Làm mới chính sách động</translation> <translation id="7687943045976362719">Nếu bạn đặt chính sách này, <ph name="PRODUCT_FRAME_NAME" /> sẽ xử lý các loại nội dung được chỉ định. @@ -6062,7 +6066,7 @@ Bạn nên định cấu hình chính sách trên Windows qua GPO, mặc dù vi Đối với những cookie trên miền không khớp với các mẫu nêu ở đây hoặc đối với tất cả cookie, nếu bạn không đặt chính sách này, thì giá trị mặc định chung của chính sách <ph name="LEGACY_SAMESITE_COOKIE_BEHAVIOR_ENABLED_POLICY_NAME" /> (nếu bạn đã đặt chính sách này) hoặc trong cấu hình cá nhân của người dùng sẽ được sử dụng. Xin lưu ý rằng các mẫu bạn liệt kê ở đây được xử lý như miền, chứ không phải như URL. Vì vậy, bạn không nên chỉ định lược đồ hoặc cổng.</translation> -<translation id="8887709920496070892">Khoảng thời gian (tính bằng mili giây) kể từ khi không có hoạt động đầu vào của người dùng cho đến thời điểm hệ thống hiển thị hộp thoại cảnh báo</translation> +<translation id="8887709920496070892">Khoảng thời gian (tính bằng mili giây) kể từ khi không có hoạt động đầu vào của người dùng cho đến thời điểm hệ thống hiện hộp thoại cảnh báo</translation> <translation id="8890438048579188548">Ẩn cảnh báo về việc ngừng cung cấp <ph name="CLOUD_PRINT_NAME" /></translation> <translation id="8892286064305622118">Dung lượng ổ đĩa trống cần có cho <ph name="PLUGIN_VM_NAME" /></translation> <translation id="8892783613915541293">Số lần trì hoãn và các hành động cần thực hiện khi thiết bị ở trạng thái rảnh và chạy bằng nguồn điện AC</translation> diff --git a/components/policy/resources/policy_templates_zh-CN.xtb b/components/policy/resources/policy_templates_zh-CN.xtb index 9b3c1eb65ee6f2..06523bf5bf3ed8 100644 --- a/components/policy/resources/policy_templates_zh-CN.xtb +++ b/components/policy/resources/policy_templates_zh-CN.xtb @@ -3835,6 +3835,10 @@ 否则,本地 IP 地址将会隐藏,被 mDNS 主机名取代。 请注意,此政策会削弱对本地 IP 的保护(如果管理员需要这样做)。</translation> <translation id="614662973812186053">此政策亦用于控制对 Android 使用情况和诊断数据的收集。</translation> +<translation id="6154509171634387825">警告:我们将从 <ph name="PRODUCT_NAME" /> 的 95 版(将于 2021 年 10 月左右推出)中彻底移除 3DES。届时,此政策将不再有效。 + + 如果此政策设为 true,系统将在传输层安全协议 (TLS) 中启用 3DES 加密套件。如果此政策设为 false,系统将在 TLS 中停用 3DES 加密套件。如果此政策未设置,3DES 加密套件会默认处于停用状态。此政策可用于暂时保持与过时服务器的兼容性。这只是一种权宜之计,正确的做法是重新配置服务器。 + </translation> <translation id="6155350825868160236">允许用户选择是否使用 Google 网络服务来修正拼写错误</translation> <translation id="6155936611791017817">设置登录屏幕上大号光标的默认状态</translation> <translation id="6157537876488211233">代理绕过规则的逗号分隔列表</translation> diff --git a/components/policy/resources/policy_templates_zh-TW.xtb b/components/policy/resources/policy_templates_zh-TW.xtb index 605fcb6b3b856d..602c4e011534c4 100644 --- a/components/policy/resources/policy_templates_zh-TW.xtb +++ b/components/policy/resources/policy_templates_zh-TW.xtb @@ -3822,6 +3822,9 @@ 否則系統會透過 mDNS 主機名稱隱藏本機 IP 位址。 請注意,如果系統管理員必須使用此政策,此政策將降低系統對本機 IP 的保護程度。</translation> <translation id="614662973812186053">這項政策也可以控制 Android 使用資料和診斷資料的收集設定。</translation> +<translation id="6154509171634387825">警告:我們將從 <ph name="PRODUCT_NAME" /> 第 95 版中 (約在 2021 年 10 月推出) 完全移除 3DES,屆時這項政策也會停止運作。 + 如果將這項政策設為 True,系統會啟用傳輸層安全標準 (TLS) 中的 3DES 加密套件。如果設為 False,系統將停用這些加密套件。如果不設定這項政策,3DES 加密套件會預設為停用。這項政策可以暫時維持與過時伺服器的相容性。這種做法是權宜之計,正確的做法是重新設定伺服器。 + </translation> <translation id="6155350825868160236">允許使用者選擇是否要使用 Google 網路服務來解決拼字錯誤</translation> <translation id="6155936611791017817">設定大型游標在登入畫面的預設狀態</translation> <translation id="6157537876488211233">以逗號間隔的 Proxy 略過規則清單</translation> diff --git a/components/strings/components_strings_am.xtb b/components/strings/components_strings_am.xtb index f9ca4c2e8b2eb0..be6a28243d91db 100644 --- a/components/strings/components_strings_am.xtb +++ b/components/strings/components_strings_am.xtb @@ -727,6 +727,7 @@ <translation id="3631244953324577188">ባዮሜትሪክስ</translation> <translation id="3633738897356909127">የChrome አዝራርን ያዘምኑ፣ Chromeን ለማዘመን ከእርስዎ Chrome ቅንብሮች ሆነው አስገባን ይጫኑ</translation> <translation id="3634530185120165534">መሳቢያ 5</translation> +<translation id="3637662659967048211">ወደ Google መለያ አስቀምጥ</translation> <translation id="3640766068866876100">መረጃ ጠቋሚ-4x6-Ext</translation> <translation id="3642638418806704195">መተግበሪያ፦</translation> <translation id="3650584904733503804">ማረጋገጥ ተሳክቷል</translation> @@ -1401,6 +1402,7 @@ <translation id="6106989379647458772">በ<ph name="PAGE" /> ላይ ያለው ድረ-ገፅ ለጊዜው ተበላሽቶ ሊሆን ይችላል ወይም በቋሚነት ወደ አዲስ የድር አድራሻ ተንቀሳቅሶ ሊሆን ይችላል።</translation> <translation id="6107012941649240045">ለእዚህ ቀርቧል</translation> <translation id="610911394827799129">የእርስዎ Google መለያ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> ላይ ሌሎች የአሰሳ ታሪክ ዓይነቶች ሊኖረው ይችላል።</translation> +<translation id="6113594885686374546">የጉዞን ከቆመበት ቀጥል ቁልፍ፣ ጉዞዎን ከቆመበት ለመቀጠል አስገባን ይጫኑ እና በChrome ታሪክዎ ውስጥ አግባብነት ያለው እንቅስቃሴን ይመልከቱ</translation> <translation id="6116338172782435947">ወደ ቅንጥብ ሰሌዳው የተቀዱ ጽሑፍ እና ምስሎችን ይመልከቱ</translation> <translation id="6120179357481664955">የእርስዎን UPI መታወቂያ ያስታውሳሉ?</translation> <translation id="6123290840358279103">ምናባዊ ካርድ ይመልከቱ</translation> @@ -1476,6 +1478,7 @@ <translation id="6423385022588644828">ከአሁን በኋላ የንኪ መታወቂያን በመጠቀም የእርስዎን ካርዶች በበለጠ ፍጥነት ያረጋግጡ</translation> <translation id="6425092077175753609">ቁሳዊ</translation> <translation id="6427730057873428458">የበር እጥፋት</translation> +<translation id="6428146287756735566">በእርስዎ የChrome ታሪክ ውስጥ አግባብነት ያለው እንቅስቃሴን ለማየት ጉዞዎን ከቆመበት ይቀጥሉ</translation> <translation id="6428450836711225518">ስልክ ቁጥርዎን ያረጋግጡ</translation> <translation id="6433490469411711332">የዕውቂያ መረጃን ያርትዑ</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> ማገናኘት አሻፈረኝ ብሏል።</translation> @@ -1527,6 +1530,7 @@ <translation id="6643016212128521049">አጽዳ</translation> <translation id="6645291930348198241">ኩኪዎችን እና የጣቢያ ውሂብን ይድረሱ።</translation> <translation id="6646269444027925224">{COUNT,plural, =0{ምንም}=1{ከ1 ጣቢያ (ከእርስዎ የGoogle መለያ ዘግተው እንዲወጡ አይደረጉም)}one{ከ# ጣቢያዎች (ከእርስዎ የGoogle መለያ ዘግተው እንዲወጡ አይደረጉም)}other{ከ# ጣቢያዎች (ከእርስዎ የGoogle መለያ ዘግተው እንዲወጡ አይደረጉም)}}</translation> +<translation id="6647197322759179819">ጉዞን ከቆመበት ቀጥል</translation> <translation id="6648459603387803038">የእርስዎ አስተዳዳሪ በርቀት የአሳሽዎን ውቅረት መቀየር ይችላል። በዚህ መሣሪያ ላይ ያለ እንቅስቃሴ ከChrome ውጭም ሊስተዳደር ይችላል።</translation> <translation id="6648524591329069940">ባለጭረት ቅርጸ-ቁምፊ</translation> <translation id="6651270836885078973">በሚከተለው የሚተዳደር ነው፦</translation> @@ -2179,6 +2183,7 @@ <translation id="9114524666733003316">ካርድን በማረጋገጥ ላይ...</translation> <translation id="9114581008513152754">ይህ አሳሽ በኩባንያ ወይም ሌላ ድርጅት አይተዳደርም። በዚህ መሣሪያ ላይ ያለ እንቅስቃሴ ከChrome ውጭ ሊተዳደር ይችላል። <ph name="BEGIN_LINK" />የበለጠ ለመረዳት<ph name="END_LINK" /></translation> <translation id="9117930699067497412">አዲስ</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />፣ ትርን ጠቅ ያድርጉ ከዚያ ጉዞዎን ከቆመበት ለመቀጠል ያስገቡ እና በChrome ታሪክዎ ውስጥ አግባብነት ያለው እንቅስቃሴን ይመልከቱ</translation> <translation id="9119042192571987207">ተሰቅሏል</translation> <translation id="9128016270925453879">መመሪያዎች ተጭነዋል</translation> <translation id="9128870381267983090">ከአውታረ መረብ ጋር ይገናኙ</translation> diff --git a/components/strings/components_strings_ar.xtb b/components/strings/components_strings_ar.xtb index 85759b940735ea..5da0a0eb102601 100644 --- a/components/strings/components_strings_ar.xtb +++ b/components/strings/components_strings_ar.xtb @@ -734,6 +734,7 @@ <translation id="3631244953324577188">المقاييس الحيوية</translation> <translation id="3633738897356909127">زر "تحديث Chrome"، اضغط على مفتاح Enter لتحديث Chrome من إعداداته.</translation> <translation id="3634530185120165534">الدُرج 5</translation> +<translation id="3637662659967048211">حفظ المعلومات في حساب Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">التطبيق:</translation> <translation id="3650584904733503804">تم التحقق بنجاح</translation> @@ -1411,6 +1412,7 @@ <translation id="6106989379647458772">قد تكون صفحة الويب على <ph name="PAGE" /> غير متاحة مؤقتًا أو تم نقلها نهائيًا إلى عنوان ويب جديد.</translation> <translation id="6107012941649240045">الجهة صاحبة الإصدار</translation> <translation id="610911394827799129">قد يتضمّن حسابك على Google نماذج أخرى من سجلّ التصفّح على <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">زر استئناف عملية البحث، اضغط على Enter لاستئناف عملية البحث والاطّلاع على النشاط ذي الصلة في سجلّ Chrome.</translation> <translation id="6116338172782435947">الاطلاع على النصوص والصور التي تم نسخها إلى الحافظة</translation> <translation id="6120179357481664955">هل تتذكر معرّف واجهة الدفعات الموحّدة؟</translation> <translation id="6123290840358279103">عرض البطاقة الافتراضية</translation> @@ -1486,6 +1488,7 @@ <translation id="6423385022588644828">التأكد من بطاقاتك بشكلٍ أسرع باستخدام ميزة Touch ID من الآن فصاعدًا</translation> <translation id="6425092077175753609">متعدد الأبعاد</translation> <translation id="6427730057873428458">الطي على شكل بوابة</translation> +<translation id="6428146287756735566">استأنف عملية البحث للاطّلاع على النشاط ذي الصلة في سجلّ Chrome</translation> <translation id="6428450836711225518">إثبات ملكية رقم الهاتف</translation> <translation id="6433490469411711332">تعديل معلومات الاتصال</translation> <translation id="6433595998831338502">رفض <ph name="HOST_NAME" /> الاتصال.</translation> @@ -1537,6 +1540,7 @@ <translation id="6643016212128521049">محو</translation> <translation id="6645291930348198241">الوصول إلى بيانات الموقع الإلكتروني وملفات تعريف الارتباط</translation> <translation id="6646269444027925224">{COUNT,plural, =0{بدون}=1{من موقع إلكتروني واحد (لن يتم تسجيل خروجك من حسابك على Google)}two{من موقعي ويب (#) (لن يتم تسجيل خروجك من حسابك على Google)}few{من # مواقع إلكترونية (لن يتم تسجيل خروجك من حسابك على Google)}many{من # موقع إلكتروني (لن يتم تسجيل خروجك من حسابك على Google)}other{من # موقع إلكتروني (لن يتم تسجيل خروجك من حسابك على Google)}}</translation> +<translation id="6647197322759179819">استئناف عملية البحث</translation> <translation id="6648459603387803038">يمكن لمشرفك تغيير إعداد المتصفِّح عن بُعد. وقد تتم أيضًا إدارة النشاط على هذا الجهاز خارج Chrome.</translation> <translation id="6648524591329069940">خط Serif</translation> <translation id="6651270836885078973">تتم إدارة الجهاز من خلال:</translation> @@ -2189,6 +2193,7 @@ <translation id="9114524666733003316">جارٍ التحقق من البطاقة...</translation> <translation id="9114581008513152754">لا تتم إدارة هذا المتصفِّح من خلال شركة أو مؤسسة أخرى. وقد تتم إدارة النشاط على هذا الجهاز خارج Chrome. <ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" /></translation> <translation id="9117930699067497412">جديد</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />، اضغط على مفتاح التبويب (Tab)، ثم Enter لاستئناف عملية البحث والاطّلاع على النشاط ذي الصلة في سجلّ Chrome.</translation> <translation id="9119042192571987207">تم التحميل</translation> <translation id="9128016270925453879">تم تحميل السياسات.</translation> <translation id="9128870381267983090">الاتصال بالشبكة</translation> diff --git a/components/strings/components_strings_as.xtb b/components/strings/components_strings_as.xtb index ebdde15753fd7b..624efd743351a2 100644 --- a/components/strings/components_strings_as.xtb +++ b/components/strings/components_strings_as.xtb @@ -731,6 +731,7 @@ <translation id="3631244953324577188">বায়’মেট্ৰিক্স</translation> <translation id="3633738897356909127">Chrome আপডে’ট কৰক বুটাম, Chromeৰ ছেটিংসমূহৰ পৰা Chrome আপডে’ট কৰিবলৈ এণ্টাৰ টিপক</translation> <translation id="3634530185120165534">ট্ৰে’ ৫</translation> +<translation id="3637662659967048211">Google একাউণ্টত ছেভ কৰক</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">এপ্লিকেশ্বন:</translation> <translation id="3650584904733503804">মান্যতাকৰণ সফল</translation> @@ -1405,6 +1406,7 @@ <translation id="6106989379647458772"><ph name="PAGE" />ৰ ৱেবপৃষ্ঠাটো অস্থায়ীভাৱে ব্যৱহাৰযোগ্য হৈ নাথাকিব পাৰে বা ইয়াক কোনো নতুন ৱেব ঠিকনালৈ স্থায়ী ভাৱে নিয়া হ’ব পাৰে।</translation> <translation id="6107012941649240045">ইয়াত প্ৰদান কৰা হৈছে</translation> <translation id="610911394827799129">আপোনাৰ Google একাউণ্টৰ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />ত অন্য ব্ৰাউজিং ইতিহাস থাকিব পাৰে৷</translation> +<translation id="6113594885686374546">যাত্ৰা পুনৰ আৰম্ভ কৰক বুটাম, আপোনাৰ যাত্ৰা পুনৰ আৰম্ভ কৰিবলৈ এণ্টাৰ টিপক আৰু আপোনাৰ Chromeৰ ইতিহাসত প্ৰাসংগিক কাৰ্যকলাপ চাওক</translation> <translation id="6116338172782435947">ক্লিপব’ৰ্ডলৈ প্ৰতিলিপি কৰা পাঠ আৰু প্ৰতিচ্ছবি চাওক</translation> <translation id="6120179357481664955">আপোনাৰ UPI IDটো মনত আছেনে?</translation> <translation id="6123290840358279103">ভাৰ্চুৱেল কাৰ্ডখন চাওক</translation> @@ -1479,6 +1481,7 @@ <translation id="6423385022588644828">এতিয়াৰ পৰা স্পৰ্শ আইডি ব্যৱহাৰ কৰি আপোনাৰ কাৰ্ডসমূহ খৰতকীয়াকৈ নিশ্চিত কৰক</translation> <translation id="6425092077175753609">সামগ্ৰী</translation> <translation id="6427730057873428458">গে'ট ফ'ল্ড কৰক</translation> +<translation id="6428146287756735566">আপোনাৰ Chromeৰ ইতিহাসত প্ৰাসংগিক কাৰ্যকলাপ চাবলৈ যাত্ৰা পুনৰ আৰম্ভ কৰক</translation> <translation id="6428450836711225518">আপোনাৰ ফ’ন নম্বৰটো সত্যাপন কৰক</translation> <translation id="6433490469411711332">সম্পর্কৰ তথ্য সম্পাদনা কৰক</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" />এ সংযোগ কৰিবলৈ অস্বীকাৰ কৰিছে।</translation> @@ -1530,6 +1533,7 @@ <translation id="6643016212128521049">মচক</translation> <translation id="6645291930348198241">কুকীসমূহ আৰু ছাইটৰ ডেটা এক্সেছ কৰক।</translation> <translation id="6646269444027925224">{COUNT,plural, =0{এটাৰ পৰাও নহয়}=1{১টা ছাইটৰ পৰা (আপুনি নিজৰ Google Accountৰ পৰা ছাইন আউট হৈ নাযায়)}one{#টা ছাইটৰ পৰা (আপুনি নিজৰ Google Accountৰ পৰা ছাইন আউট হৈ নাযায়)}other{#টা ছাইটৰ পৰা (আপুনি নিজৰ Google Accountৰ পৰা ছাইন আউট হৈ নাযায়)}}</translation> +<translation id="6647197322759179819">যাত্ৰা পুনৰ আৰম্ভ কৰক</translation> <translation id="6648459603387803038">আপোনাৰ প্ৰশাসকে দূৰৰ পৰাই আপোনাৰ ব্ৰাউজাৰৰ ছেটআপ সলনি কৰিব পাৰে। এই ডিভাইচটোত কৰা কাৰ্যকলাপ Chromeৰ বাহিৰৰ পৰাও পৰিচালনা কৰা হ’ব পাৰে।</translation> <translation id="6648524591329069940">Serif ফ’ণ্ট</translation> <translation id="6651270836885078973">ইয়াৰ দ্বাৰা পৰিচালিত:</translation> @@ -2178,6 +2182,7 @@ <translation id="9114524666733003316">কার্ড নিশ্চিত কৰি থকা হৈছে...</translation> <translation id="9114581008513152754">এই ব্ৰাউজাৰটো কোনো কোম্পানী অথবা অন্য প্ৰতিষ্ঠানৰ দ্বাৰা পৰিচালিত। এই ডিভাইচটোৰ কাৰ্যকলাপ Chromeৰ বাহিৰত পৰিচালনা কৰা হৈ থাকিব পাৰে। <ph name="BEGIN_LINK" />অধিক জানক<ph name="END_LINK" /></translation> <translation id="9117930699067497412">সজীৱ</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, টেব টিপক তাৰ পাছত আপোনাৰ যাত্ৰা পুনৰ আৰম্ভ কৰিবলৈ এণ্টাৰ টিপক আৰু আপোনাৰ Chromeৰ ইতিহাসত প্ৰাসংগিক কাৰ্যকলাপ চাওক</translation> <translation id="9119042192571987207">আপল’ড কৰা হৈছে</translation> <translation id="9128016270925453879">নীতি ল’ড কৰা হৈছে</translation> <translation id="9128870381267983090">নেটৱৰ্কত সংযোগ কৰক</translation> diff --git a/components/strings/components_strings_az.xtb b/components/strings/components_strings_az.xtb index ba6d1b2fe53a55..447baeb30d0ec9 100644 --- a/components/strings/components_strings_az.xtb +++ b/components/strings/components_strings_az.xtb @@ -730,6 +730,7 @@ <translation id="3631244953324577188">Biometriklər</translation> <translation id="3633738897356909127">"Chrome'u güncəlləyin" düyməsi, Chrome ayarlarında Chrome'u güncəlləmək üçün Enter düyməsinə basın</translation> <translation id="3634530185120165534">Qab 5</translation> +<translation id="3637662659967048211">Google Hesabında saxlayın</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Tətbiq:</translation> <translation id="3650584904733503804">Yoxlama uğurludur</translation> @@ -1406,6 +1407,7 @@ <translation id="6106989379647458772"><ph name="PAGE" /> veb səhifəsi müvəqqəti işləməyə bilər və ya yeni veb ünvana köçürülmüş ola bilər.</translation> <translation id="6107012941649240045">Verildi:</translation> <translation id="610911394827799129"><ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> linkində Google Hesabına məxsus axtarış tarixçəsinin başqa formaları ola bilər</translation> +<translation id="6113594885686374546">"Baxışa davam edin" düyməsi, Enter düyməsinə basaraq baxışa davam edin və Chrome tarixçəsində əlaqəli fəaliyyəti görün</translation> <translation id="6116338172782435947">Buferə kopyalanan mətn və şəkillərə baxın</translation> <translation id="6120179357481664955">UPI ID'niz yadda saxlansın?</translation> <translation id="6123290840358279103">Virtual karta baxın</translation> @@ -1481,6 +1483,7 @@ <translation id="6423385022588644828">Bundan sonra Toxunuş İD'si istifadə edərək kartlarınızı daha sürətli təsdiqləyin</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Qapı şəklində qatlayın</translation> +<translation id="6428146287756735566">Chrome tarixçəsində əlaqəli fəaliyyəti görmək üçün baxışa davam edin</translation> <translation id="6428450836711225518">Telefon nömrənizi doğrulayın</translation> <translation id="6433490469411711332">Kontakt məlumatını redaktə edin</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> qoşulmaq istəmədi.</translation> @@ -1532,6 +1535,7 @@ <translation id="6643016212128521049">Silin</translation> <translation id="6645291930348198241">Kukilər və sayt datasına giriş.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Yoxdur}=1{1 saytdan (Google Hesabınızdan çıxmayacaqsınız)}other{ # saytdan (Google Hesabınızdan çıxmayacaqsınız)}}</translation> +<translation id="6647197322759179819">Baxışa davam edin</translation> <translation id="6648459603387803038">Administrator brauzer quraşdırmasını uzaqdan dəyişə bilər. Bu cihazdakı fəaliyyət Chrome'dan kənarda da idarə edilə bilər.</translation> <translation id="6648524591329069940">Serif Şrifti</translation> <translation id="6651270836885078973">İdarə edən:</translation> @@ -2183,6 +2187,7 @@ <translation id="9114524666733003316">Kart təsdiqlənir...</translation> <translation id="9114581008513152754">Bu brauzer şirkət və ya başqa təşkilat tərəfindən idarə edilmir. Bu cihazdakı fəaliyyət Chrome'dan kənarda idarə edilə bilər. <ph name="BEGIN_LINK" />Ətraflı məlumat<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Təzə</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, Tab düyməsi, sonra Enter düyməsinə basaraq baxışa davam edin və Chrome tarixçəsində əlaqəli fəaliyyəti görün</translation> <translation id="9119042192571987207">Yüklənib</translation> <translation id="9128016270925453879">Siyasətlər yüklənib</translation> <translation id="9128870381267983090">Şəbəkəyə qoşulun</translation> diff --git a/components/strings/components_strings_be.xtb b/components/strings/components_strings_be.xtb index 5bbf7d6ee1f6e4..08523bd2b63329 100644 --- a/components/strings/components_strings_be.xtb +++ b/components/strings/components_strings_be.xtb @@ -733,6 +733,7 @@ <translation id="3631244953324577188">Біяметрыя</translation> <translation id="3633738897356909127">Кнопка "Абнавіць Chrome". Каб абнавіць браўзер Chrome праз яго налады, націсніце Enter</translation> <translation id="3634530185120165534">Латок 5</translation> +<translation id="3637662659967048211">Захоўванне даных ва Уліковым запісе Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Праграма:</translation> <translation id="3650584904733503804">Праверка прайшла паспяхова</translation> @@ -1410,6 +1411,7 @@ <translation id="6106989379647458772">Магчыма, вэб-старонка па адрасе <ph name="PAGE" /> часова недаступная або была перамешчана на новы вэб-адрас.</translation> <translation id="6107012941649240045">Каму выдадзена</translation> <translation id="610911394827799129">На сайце <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> могуць быць іншыя формы запісу гісторыі прагляду сайтаў для вашага Уліковага запісу Google</translation> +<translation id="6113594885686374546">Кнопка "Працягнуць пошук". Каб пашукаць звязаныя дзеянні ў гісторыі праглядаў Chrome, націсніце Enter</translation> <translation id="6116338172782435947">Праглядаць тэкст і відарысы, скапіраваныя ў буфер абмену</translation> <translation id="6120179357481664955">Запомніць ідэнтыфікатар UPI?</translation> <translation id="6123290840358279103">Праглядзець віртуальную картку</translation> @@ -1485,6 +1487,7 @@ <translation id="6423385022588644828">Калі выкарыстоўваць Touch ID, пацвярджаць карткі можна будзе хутчэй</translation> <translation id="6425092077175753609">Матэрыял</translation> <translation id="6427730057873428458">Згіб "вароты"</translation> +<translation id="6428146287756735566">Пашукаць звязаныя дзеянні ў гісторыі праглядаў Chrome</translation> <translation id="6428450836711225518">Спраўдзіце свой нумар тэлефона</translation> <translation id="6433490469411711332">Змена кантактных звестак</translation> <translation id="6433595998831338502">Хост <ph name="HOST_NAME" /> адмовіўся ад падключэння.</translation> @@ -1536,6 +1539,7 @@ <translation id="6643016212128521049">Ачысціць</translation> <translation id="6645291930348198241">Атрымаць доступ да файлаў cookie і даных сайта.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Няма}=1{З 1 сайта (вы не выйдзеце з Уліковага запісу Google)}one{З # сайта (вы не выйдзеце з Уліковага запісу Google)}few{З # сайтаў (вы не выйдзеце з Уліковага запісу Google)}many{З # сайтаў (вы не выйдзеце з Уліковага запісу Google)}other{З # сайта (вы не выйдзеце з Уліковага запісу Google)}}</translation> +<translation id="6647197322759179819">Працягнуць пошук</translation> <translation id="6648459603387803038">Адміністратар можа аддалена змяняць налады браўзера. Сама прылада таксама можа знаходзіцца пад знешнім кіраваннем.</translation> <translation id="6648524591329069940">Шрыфт з засечкамі</translation> <translation id="6651270836885078973">Прыладай кіруе:</translation> @@ -2188,6 +2192,7 @@ <translation id="9114524666733003316">Пацвярджаюцца даныя карткі...</translation> <translation id="9114581008513152754">Гэты браўзер не знаходзіцца пад кіраваннем кампаніі або іншай арганізацыі. Аднак сама прылада можа знаходзіцца пад знешнім кіраваннем. <ph name="BEGIN_LINK" />Даведацца больш<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Свежы</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />. Каб пашукаць звязаныя дзеянні ў гісторыі праглядаў Chrome, націсніце Tab, затым Enter</translation> <translation id="9119042192571987207">Запампавана</translation> <translation id="9128016270925453879">Палітыкі загружаны</translation> <translation id="9128870381267983090">Падключыцеся да сеткі</translation> diff --git a/components/strings/components_strings_bg.xtb b/components/strings/components_strings_bg.xtb index 21c525dea5c9b5..191b01cb38262e 100644 --- a/components/strings/components_strings_bg.xtb +++ b/components/strings/components_strings_bg.xtb @@ -730,6 +730,7 @@ <translation id="3631244953324577188">Биометрика</translation> <translation id="3633738897356909127">Бутон „Актуализиране на Chrome“. Натиснете Enter, за да актуализирате Chrome от настройките</translation> <translation id="3634530185120165534">Тава 5</translation> +<translation id="3637662659967048211">Запазване в профила в Google</translation> <translation id="3640766068866876100">Index-4 x 6-Ext</translation> <translation id="3642638418806704195">Приложение:</translation> <translation id="3650584904733503804">Потвърждаването е успешно</translation> @@ -1407,6 +1408,7 @@ <translation id="6106989379647458772">Уеб страницата на адрес <ph name="PAGE" /> може временно да не е налице или да е била преместена на нов уеб адрес.</translation> <translation id="6107012941649240045">Издаден на</translation> <translation id="610911394827799129">В профила ви в Google може да има други видове история на сърфиране, съхранявани на адрес <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Бутон „Продължаване на пътешествието“. Натиснете Enter, за да продължите пътешествието си и да прегледате съответната активност в историята си в Chrome</translation> <translation id="6116338172782435947">Да преглежда текста и изображенията, копирани в буферната памет</translation> <translation id="6120179357481664955">Помните ли идентификационния си номер за UPI?</translation> <translation id="6123290840358279103">Преглед на виртуалната карта</translation> @@ -1482,6 +1484,7 @@ <translation id="6423385022588644828">Потвърждавайте картите си по-бързо, като от сега нататък използвате Touch ID</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Сгъване на двата края навътре</translation> +<translation id="6428146287756735566">Продължете пътешествието си, за да прегледате съответната активност в историята си в Chrome</translation> <translation id="6428450836711225518">Потвърдете телефонния си номер</translation> <translation id="6433490469411711332">Редактиране на информацията за връзка</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> отказа да установи връзка.</translation> @@ -1533,6 +1536,7 @@ <translation id="6643016212128521049">Изчистване</translation> <translation id="6645291930348198241">Осъществява достъп до „бисквитки“ и данни за сайтове.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Няма}=1{От 1 сайт (няма да излезете от профила си в Google)}other{От # сайта (няма да излезете от профила си в Google)}}</translation> +<translation id="6647197322759179819">Продължаване на пътешествието</translation> <translation id="6648459603387803038">Администраторът ви може отдалечено да променя настройките на браузъра. Възможно е активността на това устройство да се управлява и извън Chrome.</translation> <translation id="6648524591329069940">Серифен шрифт</translation> <translation id="6651270836885078973">Управлява се от:</translation> @@ -2184,6 +2188,7 @@ <translation id="9114524666733003316">Картата се потвърждава...</translation> <translation id="9114581008513152754">Този браузър не се управлява от дружество или друга организация. Възможно е активността на устройството да се управлява извън Chrome. <ph name="BEGIN_LINK" />Научете повече<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Свежо</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, натиснете Tab и след това Enter, за да продължите пътешествието си и да прегледате съответната активност в историята си в Chrome</translation> <translation id="9119042192571987207">Качено</translation> <translation id="9128016270925453879">Правилата са заредени</translation> <translation id="9128870381267983090">Свързване към мрежа</translation> diff --git a/components/strings/components_strings_bs.xtb b/components/strings/components_strings_bs.xtb index ec4273e52d0f8a..0c357ab203ccac 100644 --- a/components/strings/components_strings_bs.xtb +++ b/components/strings/components_strings_bs.xtb @@ -734,6 +734,7 @@ To će u suprotnom biti blokirano prema vašim postavkama privatnosti. Ovo će o <translation id="3631244953324577188">Biometrija</translation> <translation id="3633738897356909127">Dugme Ažuriraj Chrome, pritisnite Enter da ažurirate Chrome iz postavki Chromea</translation> <translation id="3634530185120165534">Ladica 5</translation> +<translation id="3637662659967048211">Sačuvajte na Google račun</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplikacija:</translation> <translation id="3650584904733503804">Potvrda valjanosti je uspjela</translation> @@ -1411,6 +1412,7 @@ To će u suprotnom biti blokirano prema vašim postavkama privatnosti. Ovo će o <translation id="6106989379647458772">Web stranica na <ph name="PAGE" /> je možda privremeno ugašena ili je trajno prebačena na novu web adresu.</translation> <translation id="6107012941649240045">Izdato za</translation> <translation id="610911394827799129">Google račun može imati druge oblike historije pregledanja na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Dugme Nastavi pregledati, pritisnite Enter da nastavite pregledati te da vidite relevantne aktivnosti u historiji Chromea</translation> <translation id="6116338172782435947">Pogledajte tekst i slike kopirane u međumemoriju</translation> <translation id="6120179357481664955">Zapamtiti vaš UPI ID?</translation> <translation id="6123290840358279103">Prikaži virtuelnu karticu</translation> @@ -1486,6 +1488,7 @@ To će u suprotnom biti blokirano prema vašim postavkama privatnosti. Ovo će o <translation id="6423385022588644828">Od sada brže potvrđujte kartice korištenjem funkcije Touch ID</translation> <translation id="6425092077175753609">Materijal</translation> <translation id="6427730057873428458">Presavijanje</translation> +<translation id="6428146287756735566">Nastavite pregledati da vidite relevantne aktivnosti u historiji Chromea</translation> <translation id="6428450836711225518">Potvrdite broj telefona</translation> <translation id="6433490469411711332">Uređivanje podataka za kontakt</translation> <translation id="6433595998831338502">Host računar <ph name="HOST_NAME" /> je odbio povezivanje.</translation> @@ -1537,6 +1540,7 @@ To će u suprotnom biti blokirano prema vašim postavkama privatnosti. Ovo će o <translation id="6643016212128521049">Obriši</translation> <translation id="6645291930348198241">Pristupiti kolačićima i podacima web lokacije.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Ništa}=1{S jedne web lokacije (nećete se odjaviti sa svog Google računa)}one{S # web lokacije (nećete se odjaviti sa svog Google računa)}few{S # web lokacije (nećete se odjaviti sa svog Google računa)}other{S # web lokacija (nećete se odjaviti sa svog Google računa)}}</translation> +<translation id="6647197322759179819">Nastavi pregledati</translation> <translation id="6648459603387803038">Vaš administrator može promijeniti postavke preglednika daljinskim putem. Aktivnostima na ovom uređaju se može upravljati i van Chromea.</translation> <translation id="6648524591329069940">Font Serif</translation> <translation id="6651270836885078973">Upravlja:</translation> @@ -2188,6 +2192,7 @@ Dodatni detalji: <translation id="9114524666733003316">Potvrđivanje kartice...</translation> <translation id="9114581008513152754">Ovim preglednikom ne upravlja kompanija ili neka druga organizacija. Aktivnostima na ovom uređaju se može upravljati van Chromea. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Svježe</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, a zatim Enter da nastavite pregledati te da vidite relevantne aktivnosti u historiji Chromea</translation> <translation id="9119042192571987207">Otpremljeno</translation> <translation id="9128016270925453879">Pravila su učitana</translation> <translation id="9128870381267983090">Spoji se na mrežu</translation> diff --git a/components/strings/components_strings_ca.xtb b/components/strings/components_strings_ca.xtb index 622da3f2b83428..4114ecc18c5ad9 100644 --- a/components/strings/components_strings_ca.xtb +++ b/components/strings/components_strings_ca.xtb @@ -728,6 +728,7 @@ En cas contrari, la configuració de privadesa el bloquejarà. Això permetrà q <translation id="3631244953324577188">Biometria</translation> <translation id="3633738897356909127">Botó Actualitza Chrome; prem Retorn per actualitzar Chrome des de la configuració de Chrome</translation> <translation id="3634530185120165534">Safata 5</translation> +<translation id="3637662659967048211">Desa al Compte de Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplicació:</translation> <translation id="3650584904733503804">Validació correcta</translation> @@ -1400,6 +1401,7 @@ En cas contrari, la configuració de privadesa el bloquejarà. Això permetrà q <translation id="6106989379647458772">És possible que la pàgina web <ph name="PAGE" /> estigui temporalment fora de servei o s'hagi traslladat permanentment a una adreça web nova.</translation> <translation id="6107012941649240045">Emès per a</translation> <translation id="610911394827799129">A <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> trobaràs altres maneres d'explorar l'historial de navegació del teu Compte de Google</translation> +<translation id="6113594885686374546">Botó Reprèn el camí: prem Retorn per reprendre el camí i veure activitat rellevant a l'historial de Chrome</translation> <translation id="6116338172782435947">Veure el text i les imatges copiats al porta-retalls</translation> <translation id="6120179357481664955">Recordes el teu identificador d'UPI?</translation> <translation id="6123290840358279103">Mostra la targeta virtual</translation> @@ -1475,6 +1477,7 @@ En cas contrari, la configuració de privadesa el bloquejarà. Això permetrà q <translation id="6423385022588644828">A partir d'ara, confirma les targetes més ràpidament amb Touch ID</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Plegat en finestra</translation> +<translation id="6428146287756735566">Reprèn el camí per veure activitat rellevant a l'historial de Chrome</translation> <translation id="6428450836711225518">Verifica el número de telèfon</translation> <translation id="6433490469411711332">Edita la informació de contacte</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> no ens ha permès establir la connexió.</translation> @@ -1526,6 +1529,7 @@ En cas contrari, la configuració de privadesa el bloquejarà. Això permetrà q <translation id="6643016212128521049">Esborra</translation> <translation id="6645291930348198241">Accedir a les galetes i a les dades del lloc web.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Cap}=1{D'1 lloc web (no se't tancarà la sessió del Compte de Google)}other{De # llocs web (no se't tancarà la sessió del Compte de Google)}}</translation> +<translation id="6647197322759179819">Reprèn el camí</translation> <translation id="6648459603387803038">L'administrador pot modificar la configuració del navegador de manera remota. És possible que l'activitat d'aquest dispositiu també es gestioni fora de Chrome.</translation> <translation id="6648524591329069940">Tipus de lletra Serif</translation> <translation id="6651270836885078973">Gestionades per:</translation> @@ -2177,6 +2181,7 @@ Detalls addicionals: <translation id="9114524666733003316">S'està confirmant la targeta...</translation> <translation id="9114581008513152754">Cap empresa ni cap altra organització no gestiona aquest navegador. És possible que l'activitat d'aquest dispositiu es gestioni fora de Chrome. <ph name="BEGIN_LINK" />Més informació<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Fresca</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />: prem Tab i després Retorn per reprendre el camí i veure activitat rellevant a l'historial de Chrome</translation> <translation id="9119042192571987207">Penjat</translation> <translation id="9128016270925453879">Les polítiques s'han carregat</translation> <translation id="9128870381267983090">Connecta't a la xarxa</translation> diff --git a/components/strings/components_strings_cs.xtb b/components/strings/components_strings_cs.xtb index a50ade6299721e..4d27896e4f6c2d 100644 --- a/components/strings/components_strings_cs.xtb +++ b/components/strings/components_strings_cs.xtb @@ -724,6 +724,7 @@ Jinak to vaše nastavení ochrany soukromí bude blokovat. Povolením umožníte <translation id="3631244953324577188">Biometrické systémy</translation> <translation id="3633738897356909127">Tlačítko Aktualizovat Chrome, stisknutím klávesy Enter aktualizujete Chrome v nastavení Chromu</translation> <translation id="3634530185120165534">Přihrádka 5</translation> +<translation id="3637662659967048211">Uložit do účtu Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplikace:</translation> <translation id="3650584904733503804">Ověření proběhlo úspěšně</translation> @@ -1395,6 +1396,7 @@ Kontaktujte administrátora systému.</translation> <translation id="6106989379647458772">Webová stránka <ph name="PAGE" /> může být dočasně nefunkční nebo mohla být trvale přesunuta na novou webovou adresu.</translation> <translation id="6107012941649240045">Vydán pro</translation> <translation id="610911394827799129">Na stránce <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> mohou být k dispozici další druhy historie prohlížení zaznamenané ve vašem účtu Google.</translation> +<translation id="6113594885686374546">Tlačítko obnovení cesty, stisknutím klávesy Enter obnovíte svou cestu a zobrazíte příslušnou aktivitu v historii Chromu</translation> <translation id="6116338172782435947">Přístup k textu a obrázkům zkopírovaným do schránky</translation> <translation id="6120179357481664955">Uložit vaše UPI ID?</translation> <translation id="6123290840358279103">Zobrazit virtuální kartu</translation> @@ -1469,6 +1471,7 @@ Kontaktujte administrátora systému.</translation> <translation id="6423385022588644828">Od teď karty potvrzujte rychleji pomocí technologie Touch ID</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Otevírací přeložení</translation> +<translation id="6428146287756735566">Obnovením cesty zobrazíte příslušnou aktivitu v historii Chromu</translation> <translation id="6428450836711225518">Ověření telefonního čísla</translation> <translation id="6433490469411711332">Upravit kontaktní údaje</translation> <translation id="6433595998831338502">Web <ph name="HOST_NAME" /> odmítl připojení.</translation> @@ -1520,6 +1523,7 @@ Kontaktujte administrátora systému.</translation> <translation id="6643016212128521049">Vymazat</translation> <translation id="6645291930348198241">Získat přístup k souborům cookie a datům webů.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Žádné}=1{Z 1 webu (nebudete odhlášeni z účtu Google)}few{Ze # webů (nebudete odhlášeni z účtu Google)}many{Z # webu (nebudete odhlášeni z účtu Google)}other{Z # webů (nebudete odhlášeni z účtu Google)}}</translation> +<translation id="6647197322759179819">Obnovit cestu</translation> <translation id="6648459603387803038">Administrátor může nastavení prohlížeče vzdáleně změnit. Aktivita na tomto zařízení může být spravována také mimo Chrome.</translation> <translation id="6648524591329069940">Patkové písmo</translation> <translation id="6651270836885078973">Správce:</translation> @@ -2171,6 +2175,7 @@ Další podrobnosti: <translation id="9114524666733003316">Ověřování karty...</translation> <translation id="9114581008513152754">Tento prohlížeč není spravován administrátorem ani jinou organizací. Aktivita na tomto zařízení může být spravována mimo Chrome. <ph name="BEGIN_LINK" />Další informace<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Svěží</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, stisknutím tabulátoru a poté klávesy Enter obnovíte svou cestu a zobrazíte příslušnou aktivitu v historii Chromu</translation> <translation id="9119042192571987207">Nahráno</translation> <translation id="9128016270925453879">Zásady jsou načteny</translation> <translation id="9128870381267983090">Připojit k síti</translation> diff --git a/components/strings/components_strings_da.xtb b/components/strings/components_strings_da.xtb index 5c69c827d50929..c67d7d7d12b73a 100644 --- a/components/strings/components_strings_da.xtb +++ b/components/strings/components_strings_da.xtb @@ -734,6 +734,7 @@ Ellers vil det blive blokeret af dine privatlivsindstillinger. Det giver det ind <translation id="3631244953324577188">Biometri</translation> <translation id="3633738897356909127">Knappen Opdater Chrome – tryk på Enter for at opdatere Chrome i dine Chrome-indstillinger</translation> <translation id="3634530185120165534">Bakke 5</translation> +<translation id="3637662659967048211">Gem på Google-konto</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Program:</translation> <translation id="3650584904733503804">Valideringen er fuldført</translation> @@ -1411,6 +1412,7 @@ Ellers vil det blive blokeret af dine privatlivsindstillinger. Det giver det ind <translation id="6106989379647458772">Websiden på <ph name="PAGE" /> kan være midlertidigt nede, eller også er den permanent flyttet til en ny webadresse.</translation> <translation id="6107012941649240045">Udstedt til</translation> <translation id="610911394827799129">Din Google-konto kan have andre former for browserhistorik på <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Knappen Genoptag søgning, tryk på Enter for at genoptage søgningen og se relevant aktivitet i din Chrome-historik</translation> <translation id="6116338172782435947">Se tekst og billeder, der er kopieret til udklipsholderen</translation> <translation id="6120179357481664955">Skal dit UPI-id huskes?</translation> <translation id="6123290840358279103">Se virtuelt kort</translation> @@ -1486,6 +1488,7 @@ Ellers vil det blive blokeret af dine privatlivsindstillinger. Det giver det ind <translation id="6423385022588644828">Bekræft dine kort hurtigere ved hjælp af Touch ID fra nu af</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Portfals</translation> +<translation id="6428146287756735566">Genoptag søgningen for at se relevant aktivitet i din Chrome-historik</translation> <translation id="6428450836711225518">Bekræft dit telefonnummer</translation> <translation id="6433490469411711332">Rediger kontaktoplysninger</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> nægtede at oprette forbindelse.</translation> @@ -1537,6 +1540,7 @@ Ellers vil det blive blokeret af dine privatlivsindstillinger. Det giver det ind <translation id="6643016212128521049">Ryd</translation> <translation id="6645291930348198241">Adgang til cookies og websitedata.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Ingen}=1{Fra 1 website (du logges ikke ud af din Google-konto)}one{Fra # website (du logges ikke ud af din Google-konto)}other{Fra # websites (du logges ikke ud af din Google-konto)}}</translation> +<translation id="6647197322759179819">Genoptag søgning</translation> <translation id="6648459603387803038">Din administrator kan ændre konfigurationen af din browser via fjernadgang. Aktivitet på denne enhed administreres muligvis også uden for Chrome.</translation> <translation id="6648524591329069940">Serif-skrifttype</translation> <translation id="6651270836885078973">Administreres af:</translation> @@ -2189,6 +2193,7 @@ Yderligere oplysninger: <translation id="9114524666733003316">Bekræfter kort...</translation> <translation id="9114581008513152754">Denne browser administreres ikke af en virksomhed eller en anden organisation. Aktivitet på denne enhed administreres muligvis uden for Chrome. <ph name="BEGIN_LINK" />Få flere oplysninger<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Frisk</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" /> – tryk på Tab-tasten og derefter Enter for at genoptage søgningen og se relevant aktivitet i din Chrome-historik</translation> <translation id="9119042192571987207">Uploadet</translation> <translation id="9128016270925453879">Politikkerne er indlæst</translation> <translation id="9128870381267983090">Opret forbindelse til netværk</translation> diff --git a/components/strings/components_strings_el.xtb b/components/strings/components_strings_el.xtb index a7393c8d36ed38..ad64d3d9b1d368 100644 --- a/components/strings/components_strings_el.xtb +++ b/components/strings/components_strings_el.xtb @@ -735,6 +735,7 @@ <translation id="3631244953324577188">Βιομετρικά</translation> <translation id="3633738897356909127">Κουμπί ενημέρωσης Chrome, πατήστε Enter για να ενημερώσετε το Chrome από τις ρυθμίσεις του Chrome.</translation> <translation id="3634530185120165534">Δίσκος 5</translation> +<translation id="3637662659967048211">Αποθήκευση στον Λογαριασμό Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Εφαρμογή:</translation> <translation id="3650584904733503804">Επιτυχής επικύρωση</translation> @@ -1415,6 +1416,7 @@ <translation id="6106989379647458772">Η ιστοσελίδα στη διεύθυνση <ph name="PAGE" /> μπορεί να βρίσκεται προσωρινά εκτός λειτουργίας ή ίσως έχει μεταφερθεί μόνιμα σε μια νέα διεύθυνση ιστού.</translation> <translation id="6107012941649240045">Εκδόθηκε σε</translation> <translation id="610911394827799129">Ο Λογαριασμός Google ενδέχεται να διαθέτει άλλες μορφές ιστορικού περιήγησης στη διεύθυνση <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Κουμπί Συνέχιση διαδρομής, πατήστε Enter για να συνεχίσετε τη διαδρομή σας και να δείτε σχετική δραστηριότητα στο Ιστορικό Chrome.</translation> <translation id="6116338172782435947">Δει κείμενο και εικόνες που αντιγράψατε στο πρόχειρο</translation> <translation id="6120179357481664955">Θυμάστε το αναγνωριστικό UPI;</translation> <translation id="6123290840358279103">Προβολή εικονικής κάρτας</translation> @@ -1490,6 +1492,7 @@ <translation id="6423385022588644828">Επιβεβαιώστε πιο γρήγορα τις κάρτες σας, χρησιμοποιώντας το Touch ID από εδώ και στο εξής</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Δίπλωση παράθυρο</translation> +<translation id="6428146287756735566">Συνέχιση διαδρομής για προβολή σχετική δραστηριότητας στο Ιστορικό Chrome</translation> <translation id="6428450836711225518">Επαλήθευση του αριθμού τηλεφώνου σας</translation> <translation id="6433490469411711332">Επεξεργασία στοιχείων επαφής</translation> <translation id="6433595998831338502">Ο κεντρικός υπολογιστής <ph name="HOST_NAME" /> απέρριψε τη σύνδεση.</translation> @@ -1541,6 +1544,7 @@ <translation id="6643016212128521049">Διαγραφή</translation> <translation id="6645291930348198241">Πρόσβαση σε cookie και δεδομένα ιστοτόπου.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Κανένας}=1{Από 1 ιστότοπο (δεν θα αποσυνδεθείτε από τον Λογαριασμό σας Google)}other{Από # ιστοτόπους (δεν θα αποσυνδεθείτε από τον Λογαριασμό σας Google)}}</translation> +<translation id="6647197322759179819">Συνέχιση διαδρομής</translation> <translation id="6648459603387803038">Ο διαχειριστής σας μπορεί να αλλάξει τη ρύθμιση του προγράμματος περιήγησής σας απομακρυσμένα. Η διαχείριση της δραστηριότητας σε αυτήν τη συσκευή μπορεί επίσης να πραγματοποιηθεί εκτός Chrome.</translation> <translation id="6648524591329069940">Γραμματοσειρά Serif</translation> <translation id="6651270836885078973">Η διαχείριση γίνεται από:</translation> @@ -2195,6 +2199,7 @@ <translation id="9114524666733003316">Επιβεβαίωση κάρτας…</translation> <translation id="9114581008513152754">Αυτός ο ιστότοπος δεν είναι διαχειριζόμενος από κάποια εταιρεία ή άλλον οργανισμό. Η διαχείριση της δραστηριότητας σε αυτήν τη συσκευή μπορεί να πραγματοποιηθεί εκτός Chrome. <ph name="BEGIN_LINK" />Μάθετε περισσότερα<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Φρέσκο</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, πατήστε Tab και, στη συνέχεια, Enter για να συνεχίσετε τη διαδρομή σας και να δείτε σχετική δραστηριότητα στο Ιστορικό Chrome.</translation> <translation id="9119042192571987207">Έγινε μεταφόρτωση</translation> <translation id="9128016270925453879">Οι πολιτικές φορτώθηκαν</translation> <translation id="9128870381267983090">Σύνδεση σε δίκτυο</translation> diff --git a/components/strings/components_strings_es-419.xtb b/components/strings/components_strings_es-419.xtb index 251b7cb183760a..c1d8cd96014075 100644 --- a/components/strings/components_strings_es-419.xtb +++ b/components/strings/components_strings_es-419.xtb @@ -729,6 +729,7 @@ De lo contrario, la configuración de privacidad bloqueará esta acción. Esto p <translation id="3631244953324577188">Biométricos</translation> <translation id="3633738897356909127">Botón Actualizar Chrome: presiona Intro para actualizar Chrome desde la configuración del navegador</translation> <translation id="3634530185120165534">Bandeja 5</translation> +<translation id="3637662659967048211">Guardar en la Cuenta de Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplicación:</translation> <translation id="3650584904733503804">Validación correcta</translation> @@ -1401,6 +1402,7 @@ De lo contrario, la configuración de privacidad bloqueará esta acción. Esto p <translation id="6106989379647458772">Es posible que la página web de <ph name="PAGE" /> no funcione temporalmente o se haya trasladado permanentemente a una dirección web nueva.</translation> <translation id="6107012941649240045">Emitido a</translation> <translation id="610911394827799129">Es posible que tu cuenta de Google tenga otros formularios del historial de navegación en <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Botón Reanudar búsqueda: presiona Intro para reanudar la búsqueda y ver actividad relevante en tu historial de Chrome</translation> <translation id="6116338172782435947">Ver el texto y las imágenes copiados en el portapapeles</translation> <translation id="6120179357481664955">¿Recuerdas tu ID de IUP?</translation> <translation id="6123290840358279103">Ver la tarjeta virtual</translation> @@ -1476,6 +1478,7 @@ De lo contrario, la configuración de privacidad bloqueará esta acción. Esto p <translation id="6423385022588644828">A partir de ahora, usa Touch ID para confirmar las tarjetas más rápido</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Plegado en ventana</translation> +<translation id="6428146287756735566">Reanuda la búsqueda para ver la actividad relevante en tu historial de Chrome.</translation> <translation id="6428450836711225518">Verifica tu número de teléfono</translation> <translation id="6433490469411711332">Editar la información de contacto</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> rechazó la conexión.</translation> @@ -1527,6 +1530,7 @@ De lo contrario, la configuración de privacidad bloqueará esta acción. Esto p <translation id="6643016212128521049">Borrar</translation> <translation id="6645291930348198241">Acceder a las cookies y los datos de sitios</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Ninguno}=1{De 1 sitio (no saldrás de tu cuenta de Google)}other{De # sitios (no saldrás de tu cuenta de Google)}}</translation> +<translation id="6647197322759179819">Reanudar búsqueda</translation> <translation id="6648459603387803038">El administrador puede cambiar la configuración de tu navegador de forma remota. Es posible que la actividad en este dispositivo también se administre fuera de Chrome.</translation> <translation id="6648524591329069940">Fuente Serif</translation> <translation id="6651270836885078973">Administrador:</translation> @@ -2179,6 +2183,7 @@ Detalles adicionales: <translation id="9114524666733003316">Confirmando tarjeta…</translation> <translation id="9114581008513152754">Este navegador no está administrado por una empresa ni por otra organización. Es posible que la actividad de este dispositivo se administre fuera de Chrome. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Fresh</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />: presiona Tab y, luego, Intro para reanudar la búsqueda y ver la actividad relevante en tu historial de Chrome</translation> <translation id="9119042192571987207">Subido</translation> <translation id="9128016270925453879">Se cargaron las políticas</translation> <translation id="9128870381267983090">Conectarse a una red</translation> diff --git a/components/strings/components_strings_es.xtb b/components/strings/components_strings_es.xtb index 43071152e9c40f..b2e23093c37179 100644 --- a/components/strings/components_strings_es.xtb +++ b/components/strings/components_strings_es.xtb @@ -734,6 +734,7 @@ De lo contrario, lo impedirá tu configuración de privacidad. Permitirá que el <translation id="3631244953324577188">Biometría</translation> <translation id="3633738897356909127">Botón Actualizar Chrome, pulsa Intro para actualizar Chrome desde la configuración de Chrome</translation> <translation id="3634530185120165534">Bandeja 5</translation> +<translation id="3637662659967048211">Guardar en tu cuenta de Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplicación:</translation> <translation id="3650584904733503804">Validación correcta</translation> @@ -1411,6 +1412,7 @@ De lo contrario, lo impedirá tu configuración de privacidad. Permitirá que el <translation id="6106989379647458772">La página web <ph name="PAGE" /> podría estar temporalmente fuera de servicio o bien podría haberse trasladado a una dirección web nueva permanentemente.</translation> <translation id="6107012941649240045">Enviado a</translation> <translation id="610911394827799129">Es posible que tu cuenta de Google tenga otros tipos de historial de navegación en la página <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Botón Reanudar recorrido, pulsa Intro para reanudar tu recorrido y ver la actividad relevante en tu historial de Chrome</translation> <translation id="6116338172782435947">Ver el texto y las imágenes que se hayan copiado en el portapapeles</translation> <translation id="6120179357481664955">¿Recuerdas tu ID de UPI?</translation> <translation id="6123290840358279103">Ver tarjeta virtual</translation> @@ -1486,6 +1488,7 @@ De lo contrario, lo impedirá tu configuración de privacidad. Permitirá que el <translation id="6423385022588644828">A partir de ahora, puedes confirmar tus tarjetas más rápido con Touch ID</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Plegado en ventana</translation> +<translation id="6428146287756735566">Reanuda el recorrido para ver la actividad relevante en tu historial de Chrome</translation> <translation id="6428450836711225518">Verifica tu número de teléfono</translation> <translation id="6433490469411711332">Editar información de contacto</translation> <translation id="6433595998831338502">La página <ph name="HOST_NAME" /> ha rechazado la conexión.</translation> @@ -1537,6 +1540,7 @@ De lo contrario, lo impedirá tu configuración de privacidad. Permitirá que el <translation id="6643016212128521049">Borrar</translation> <translation id="6645291930348198241">Acceder a cookies y datos de sitios.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Ninguno}=1{De 1 sitio web (no se cerrará la sesión en tu cuenta de Google)}other{De # sitios (no se cerrará la sesión en tu cuenta de Google)}}</translation> +<translation id="6647197322759179819">Reanudar recorrido</translation> <translation id="6648459603387803038">El administrador puede cambiar la configuración del navegador de forma remota. Es posible que la actividad de este dispositivo también se administre fuera de Chrome.</translation> <translation id="6648524591329069940">Fuente Serif</translation> <translation id="6651270836885078973">Gestionado por:</translation> @@ -2188,6 +2192,7 @@ Más información: <translation id="9114524666733003316">Confirmando tarjeta...</translation> <translation id="9114581008513152754">Este navegador no lo administra ninguna empresa ni organización. Es posible que se administre la actividad de este dispositivo fuera de Chrome. <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Novedosa</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />. Pulsa Pestaña y, después, Intro para reanudar tu recorrido y ver la actividad relevante en tu historial de Chrome</translation> <translation id="9119042192571987207">Subido</translation> <translation id="9128016270925453879">Se han cargado las políticas</translation> <translation id="9128870381267983090">Conéctate a la red</translation> diff --git a/components/strings/components_strings_et.xtb b/components/strings/components_strings_et.xtb index 8829e1e208544f..3eff36bc11be5f 100644 --- a/components/strings/components_strings_et.xtb +++ b/components/strings/components_strings_et.xtb @@ -733,6 +733,7 @@ Vastasel korral blokeeritakse see teie privaatsusseadetes. See võimaldab teie k <translation id="3631244953324577188">Biomeetria</translation> <translation id="3633738897356909127">Nupp Värskenda Chrome'i, vajutage Chrome'i seadetes Chrome'i värskendamiseks sisestusklahvi</translation> <translation id="3634530185120165534">Salv 5</translation> +<translation id="3637662659967048211">Salvesta Google'i kontole</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Rakendus:</translation> <translation id="3650584904733503804">Valideerimine õnnestus</translation> @@ -1410,6 +1411,7 @@ Vastasel korral blokeeritakse see teie privaatsusseadetes. See võimaldab teie k <translation id="6106989379647458772">Veebileht <ph name="PAGE" /> võib olla ajutiselt maas või see viidi jäädavalt üle uuele veebiaadressile.</translation> <translation id="6107012941649240045">Väljastatud subjektile:</translation> <translation id="610911394827799129">Aadressil <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> võib teie Google'i kontol olla muus vormis sirvimisajalugu</translation> +<translation id="6113594885686374546">Teekonna jätkamise nupp, vajutage sisestusklahvi, et teekonda jätkata ja oma Chrome'i ajaloos asjakohaseid tegevusi näha</translation> <translation id="6116338172782435947">näha lõikelauale kopeeritud teksti ja kujutisi</translation> <translation id="6120179357481664955">Kas jätta teie UPI ID meelde?</translation> <translation id="6123290840358279103">Kuva virtuaalkaart</translation> @@ -1485,6 +1487,7 @@ Vastasel korral blokeeritakse see teie privaatsusseadetes. See võimaldab teie k <translation id="6423385022588644828">Kinnitage oma kaardid kiiremini, kasutades edaspidi funktsiooni Touch ID</translation> <translation id="6425092077175753609">Materiaalne</translation> <translation id="6427730057873428458">Väravakujuliselt volditud</translation> +<translation id="6428146287756735566">Jätkake teekonda, et näha Chrome'i ajaloos asjakohaseid tegevusi</translation> <translation id="6428450836711225518">Kinnitage oma telefoninumber</translation> <translation id="6433490469411711332">Kontaktandmete muutmine</translation> <translation id="6433595998831338502">Host <ph name="HOST_NAME" /> keeldus ühendamast.</translation> @@ -1536,6 +1539,7 @@ Vastasel korral blokeeritakse see teie privaatsusseadetes. See võimaldab teie k <translation id="6643016212128521049">Tühjenda</translation> <translation id="6645291930348198241">Juurdepääs küpsisefailidele ja saidi andmetele.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Mitte ükski}=1{1 saidilt (teid ei logita Google'i kontolt välja)}other{# saidilt (teid ei logita Google'i kontolt välja)}}</translation> +<translation id="6647197322759179819">Jätka teekonda</translation> <translation id="6648459603387803038">Teie administraator saab brauseri seadistust kaugühenduse kaudu muuta. Selle seadme tegevusi võidakse hallata ka väljaspool Chrome'i.</translation> <translation id="6648524591329069940">Seriifidega font</translation> <translation id="6651270836885078973">Haldab:</translation> @@ -2187,6 +2191,7 @@ Lisateave: <translation id="9114524666733003316">Kaardi kinnitamine …</translation> <translation id="9114581008513152754">Seda brauserit ei halda ettevõte ega muu organisatsioon. Selle seadme tegevusi võidakse hallata ka väljaspool Chrome'i. <ph name="BEGIN_LINK" />Lisateave<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Värske</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, vajutage tabulaatorit ja siis sisestusklahvi, et teekonda jätkata ning oma Chrome'i ajaloos asjakohaseid tegevusi näha</translation> <translation id="9119042192571987207">Üles laaditud</translation> <translation id="9128016270925453879">Reeglid on laaditud</translation> <translation id="9128870381267983090">Ühendumine Internetiga</translation> diff --git a/components/strings/components_strings_eu.xtb b/components/strings/components_strings_eu.xtb index 780aa671aa6bb5..af0e697b77b248 100644 --- a/components/strings/components_strings_eu.xtb +++ b/components/strings/components_strings_eu.xtb @@ -724,6 +724,7 @@ Bestela, pribatutasun-ezarpenek blokeatu egingo dute baimen hori. Baimen honekin <translation id="3631244953324577188">Sistema biometrikoak</translation> <translation id="3633738897356909127">"Eguneratu Chrome" botoia: sakatu "Sartu" Chrome eguneratzeko Chrome-ren ezarpenetan</translation> <translation id="3634530185120165534">5. erretilua</translation> +<translation id="3637662659967048211">Gorde Google-ko kontuan</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplikazioa:</translation> <translation id="3650584904733503804">Behar bezala baliozkotu da</translation> @@ -1396,6 +1397,7 @@ Bestela, pribatutasun-ezarpenek blokeatu egingo dute baimen hori. Baimen honekin <translation id="6106989379647458772">Baliteke <ph name="PAGE" /> helbideko web-orria ez funtzionatzea edo beste web-helbide batera betiko aldatu izatea.</translation> <translation id="6107012941649240045">Nori jaulkia:</translation> <translation id="610911394827799129">Google-ko kontuko arakatze-historiaren bestelako datu batzuk gera litezke <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> webgunean.</translation> +<translation id="6113594885686374546">"Berrekin bidaiari" botoia, sakatu Sartu bidaiari berrekiteko eta Chrome-ko historiako jarduera egokiak ikusteko</translation> <translation id="6116338172782435947">Ikusi arbelean kopiatzen ditudan testuak eta irudiak</translation> <translation id="6120179357481664955">Gogoan al duzu UPIko IDa?</translation> <translation id="6123290840358279103">Ikusi txartel birtuala</translation> @@ -1470,6 +1472,7 @@ Bestela, pribatutasun-ezarpenek blokeatu egingo dute baimen hori. Baimen honekin <translation id="6423385022588644828">Aurrerantzean, berretsi txartelak bizkorrago Touch ID erabilita</translation> <translation id="6425092077175753609">Material diseinua</translation> <translation id="6427730057873428458">Leiho-erako tolestura</translation> +<translation id="6428146287756735566">Berrekin bidaiari Chrome-ko historiako jarduera egokiak ikusteko</translation> <translation id="6428450836711225518">Egiaztatu telefono-zenbakia</translation> <translation id="6433490469411711332">Editatu harremanetarako informazioa</translation> <translation id="6433595998831338502">Konexioa baztertu du <ph name="HOST_NAME" /> webguneak.</translation> @@ -1521,6 +1524,7 @@ Bestela, pribatutasun-ezarpenek blokeatu egingo dute baimen hori. Baimen honekin <translation id="6643016212128521049">Garbitu</translation> <translation id="6645291930348198241">Cookieak eta webguneko datuak atzitu.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Bat ere ez}=1{1 gune (ez da amaituko Google-ko kontuko saioa)}other{# gune (ez da amaituko Google-ko kontuko saioa)}}</translation> +<translation id="6647197322759179819">Berrekin bidaiari</translation> <translation id="6648459603387803038">Administratzaileak urrunetik alda dezake arakatzailearen konfigurazioa. Baliteke gailu honetako jarduerak Chrome-tik kanpo ere kudeatzea.</translation> <translation id="6648524591329069940">Serif letra</translation> <translation id="6651270836885078973">Kudeatzailea:</translation> @@ -2172,6 +2176,7 @@ Xehetasun gehiago: <translation id="9114524666733003316">Txartela berresten…</translation> <translation id="9114581008513152754">Arakatzailea ez du enpresa edo erakunde batek kudeatzen. Baliteke gailu honetako jarduerak Chrome-tik kanpo kudeatzea. <ph name="BEGIN_LINK" />Lortu informazio gehiago<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Freskoa</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, sakatu tabuladorea eta, ondoren, sakatu Sartu bidaiari berrekiteko eta Chrome-ko historiako jarduera egokiak ikusteko</translation> <translation id="9119042192571987207">Kargatuta</translation> <translation id="9128016270925453879">Kargatu dira gidalerroak</translation> <translation id="9128870381267983090">Konektatu sarera</translation> diff --git a/components/strings/components_strings_fa.xtb b/components/strings/components_strings_fa.xtb index d9b20f99064503..02f98ac356c012 100644 --- a/components/strings/components_strings_fa.xtb +++ b/components/strings/components_strings_fa.xtb @@ -732,6 +732,7 @@ <translation id="3631244953324577188">زیستسنجشی</translation> <translation id="3633738897356909127">دکمه «بهروزرسانی Chrome»، برای بهروزرسانی Chrome ازطریق تنظیمات Chrome، کلید Enter (ورود) را فشار دهید</translation> <translation id="3634530185120165534">سینی ۵</translation> +<translation id="3637662659967048211">ذخیره در «حساب Google»</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">برنامه:</translation> <translation id="3650584904733503804">ارزیابی موفق بود</translation> @@ -1409,6 +1410,7 @@ <translation id="6106989379647458772">شاید صفحه وب در <ph name="PAGE" /> موقتاً غیرفعال شده باشد یا شاید بهطور دائم به آدرس وب جدیدی منتقل شده باشد.</translation> <translation id="6107012941649240045">صادر شده برای</translation> <translation id="610911394827799129">ممکن است حساب Google شما اشکال دیگری از سابقه مرور در <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> داشته باشد</translation> +<translation id="6113594885686374546">دکمه «ازسرگیری کاوش»، کلید «ورود» را فشار دهید تا کاوش را ازسر بگیرید و فعالیتهای مرتبط را در سابقه Chrome ببینید</translation> <translation id="6116338172782435947">به نوشتار و تصاویر کپیشده در بریدهدان دسترسی پیدا کند</translation> <translation id="6120179357481664955">شناسه «رابط پرداختهای یکپارچه» (UPI) شما بهخاطر سپرده شود؟</translation> <translation id="6123290840358279103">مشاهده کارت مجازی</translation> @@ -1484,6 +1486,7 @@ <translation id="6423385022588644828">ازاینپس، برای بهتأیید رساندن سریعتر کارتها، از «شناسه لمسی» استفاده شود</translation> <translation id="6425092077175753609">سهبعدی</translation> <translation id="6427730057873428458">تاخوردگی دروازهای</translation> +<translation id="6428146287756735566">کاوش را ازسربگیرید تا فعالیتهای مرتبط را در سابقه Chrome ببینید</translation> <translation id="6428450836711225518">بهتأیید رساندن شماره تلفن</translation> <translation id="6433490469411711332">ویرایش اطلاعات تماس</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> از اتصال خودداری کرد.</translation> @@ -1535,6 +1538,7 @@ <translation id="6643016212128521049">پاک کردن</translation> <translation id="6645291930348198241">به کوکیها و دادههای سایت دسترسی داشته باشد.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{هیچکدام}=1{از ۱ سایت (از سیستم حساب Google خود خارج نخواهید شد)}one{از # سایت (از سیستم حساب Google خود خارج نخواهید شد)}other{از # سایت (از سیستم حساب Google خود خارج نخواهید شد)}}</translation> +<translation id="6647197322759179819">ازسرگیری کاوش</translation> <translation id="6648459603387803038">سرپرستتان میتواند تنظیم مرورگرتان را ازراهدور تغییر دهد. فعالیت انجامشده در این دستگاه میتواند از خارج از Chrome هم مدیریت شود.</translation> <translation id="6648524591329069940">قلم Serif</translation> <translation id="6651270836885078973">مدیریت توسط:</translation> @@ -2186,6 +2190,7 @@ <translation id="9114524666733003316">درحال تأیید کردن کارت…</translation> <translation id="9114581008513152754">این مرورگر را شرکت یا سازمان دیگری مدیریت نمیکند. فعالیت در این دستگاه ممکن است خارج از Chrome مدیریت شود. <ph name="BEGIN_LINK" />بیشتر بدانید<ph name="END_LINK" /></translation> <translation id="9117930699067497412">تازه</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />، کلید «جهش» و سپس «ورود» را فشار دهید تا کاوش را ازسر بگیرید و فعالیتهای مرتبط را در سابقه Chrome ببینید</translation> <translation id="9119042192571987207">بارگذاریشده</translation> <translation id="9128016270925453879">خطمشیها بار شد</translation> <translation id="9128870381267983090">اتصال به شبکه</translation> diff --git a/components/strings/components_strings_fi.xtb b/components/strings/components_strings_fi.xtb index 8353321ee3a3ae..467aacdb8127dc 100644 --- a/components/strings/components_strings_fi.xtb +++ b/components/strings/components_strings_fi.xtb @@ -735,6 +735,7 @@ Muussa tapauksessa tämä estetään tietosuoja-asetuksilla. Jos sallit tämän, <translation id="3631244953324577188">Biometriikka</translation> <translation id="3633738897356909127">Päivitä Chrome ‑painike, päivitä Chrome sen asetuksista painamalla Enter</translation> <translation id="3634530185120165534">Lokero 5</translation> +<translation id="3637662659967048211">Tallenna Google-tilille</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Sovellus:</translation> <translation id="3650584904733503804">Todennus onnistui</translation> @@ -1412,6 +1413,7 @@ Muussa tapauksessa tämä estetään tietosuoja-asetuksilla. Jos sallit tämän, <translation id="6106989379647458772">Verkkosivu <ph name="PAGE" /> saattaa olla väliaikaisesti poissa käytöstä tai se on siirretty pysyvästi uuteen osoitteeseen.</translation> <translation id="6107012941649240045">Myönnetty kohteelle</translation> <translation id="610911394827799129">Google-tililläsi voi olla muita selaushistoriatietoja osoitteessa <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Jatka toimintoa ‑painike, paina Enter, niin voit jatkaa toimintoa ja nähdä oleelliset tapahtumat Chrome-historiassasi</translation> <translation id="6116338172782435947">nähdä leikepöydälle kopioidun tekstin ja kuvat</translation> <translation id="6120179357481664955">Muistatko UPI-tunnuksesi?</translation> <translation id="6123290840358279103">Näytä virtuaalinen kortti</translation> @@ -1487,6 +1489,7 @@ Muussa tapauksessa tämä estetään tietosuoja-asetuksilla. Jos sallit tämän, <translation id="6423385022588644828">Vahvista kortit jatkossa nopeammin Touch ID:llä</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Lehtitaite</translation> +<translation id="6428146287756735566">Jatka toimintoa, niin näet oleelliset tapahtumat Chrome-historiassasi</translation> <translation id="6428450836711225518">Vahvista puhelinnumerosi</translation> <translation id="6433490469411711332">Muokkaa yhteystietoja</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> kieltäytyi muodostamasta yhteyttä.</translation> @@ -1538,6 +1541,7 @@ Muussa tapauksessa tämä estetään tietosuoja-asetuksilla. Jos sallit tämän, <translation id="6643016212128521049">Tyhjennä</translation> <translation id="6645291930348198241">päästä evästeisiin ja sivustodataan.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Ei mitään}=1{1 sivustolta (sinua ei kirjata ulos Google-tililtäsi)}other{# sivustolta (sinua ei kirjata ulos Google-tililtäsi)}}</translation> +<translation id="6647197322759179819">Jatka toimintoa</translation> <translation id="6648459603387803038">Järjestelmänvalvoja voi muuttaa selaimen määrityksiä etäyhteydellä. Toimintaa tällä laitteella saatetaan ylläpitää myös Chromen ulkopuolelta.</translation> <translation id="6648524591329069940">Serif-fontti</translation> <translation id="6651270836885078973">Ylläpitäjä:</translation> @@ -2190,6 +2194,7 @@ Lisätietoja: <translation id="9114524666733003316">Vahvistetaan korttia…</translation> <translation id="9114581008513152754">Yritys tai muu organisaatio ei ylläpidä selainta. Laitteen toimintaa saatetaan ylläpitää Chromen ulkopuolelta. <ph name="BEGIN_LINK" />Lue lisää<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Tuore</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, paina sarkainta ja Enter, niin voit jatkaa toimintoa ja nähdä oleelliset tapahtumat Chrome-historiassasi</translation> <translation id="9119042192571987207">Lähetetty</translation> <translation id="9128016270925453879">Käytännöt on ladattu</translation> <translation id="9128870381267983090">Yhdistä verkkoon</translation> diff --git a/components/strings/components_strings_fr-CA.xtb b/components/strings/components_strings_fr-CA.xtb index 3f5585e1277ba1..32c79d288af2b7 100644 --- a/components/strings/components_strings_fr-CA.xtb +++ b/components/strings/components_strings_fr-CA.xtb @@ -728,6 +728,7 @@ <translation id="3631244953324577188">Données biométriques</translation> <translation id="3633738897356909127">Bouton Mise à jour de Chrome, appuyez sur la touche Entrée pour mettre à jour Chrome dans les paramètres de Chrome</translation> <translation id="3634530185120165534">Bac 5</translation> +<translation id="3637662659967048211">Enregistrer dans le compte Google</translation> <translation id="3640766068866876100">Fiche, 4 po x 6 po, ext</translation> <translation id="3642638418806704195">Application :</translation> <translation id="3650584904733503804">Validation réussie</translation> @@ -1400,6 +1401,7 @@ <translation id="6106989379647458772">Il se peut que la page Web à l'adresse <ph name="PAGE" /> soit temporairement inaccessible ou qu'elle ait été déplacée de façon permanente à une autre adresse Web.</translation> <translation id="6107012941649240045">Délivré à</translation> <translation id="610911394827799129">D'autres formes d'historique de navigation peuvent exister sur votre compte Google à l'adresse <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Bouton de reprise de la recherche, appuyez sur Entrée pour reprendre votre recherche et voir l'activité pertinente dans votre historique de Chrome</translation> <translation id="6116338172782435947">Voir le texte et les images copiés dans le presse-papiers</translation> <translation id="6120179357481664955">Se souvenir de votre identifiant UPI?</translation> <translation id="6123290840358279103">Afficher la carte virtuelle</translation> @@ -1475,6 +1477,7 @@ <translation id="6423385022588644828">Vérifiez vos cartes plus rapidement en vous servant de Touch ID à partir de maintenant</translation> <translation id="6425092077175753609">Matériel</translation> <translation id="6427730057873428458">Pli fenêtre</translation> +<translation id="6428146287756735566">Reprenez votre recherche pour voir l'activité pertinente dans votre historique de Chrome</translation> <translation id="6428450836711225518">Vérifier votre numéro de téléphone</translation> <translation id="6433490469411711332">Modifier les coordonnées</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> a refusé la connexion.</translation> @@ -1526,6 +1529,7 @@ <translation id="6643016212128521049">Effacer</translation> <translation id="6645291930348198241">Accéder aux témoins et aux données relatives aux sites.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Aucun}=1{De 1 site (vous ne serez pas déconnecté de votre compte Google)}one{De # site (vous ne serez pas déconnecté de votre compte Google)}other{De # sites (vous ne serez pas déconnecté de votre compte Google)}}</translation> +<translation id="6647197322759179819">Reprendre la recherche</translation> <translation id="6648459603387803038">Votre administrateur peut modifier la configuration de votre navigateur à distance. L'activité sur cet appareil peut aussi être gérée à l'extérieur de Chrome.</translation> <translation id="6648524591329069940">Police avec empattement</translation> <translation id="6651270836885078973">Géré par :</translation> @@ -2177,6 +2181,7 @@ Détails supplémentaires : <translation id="9114524666733003316">Confirmation de la carte en cours…</translation> <translation id="9114581008513152754">Ce navigateur n'est pas géré par une entreprise ou une organisation. L'activité sur cet appareil peut être gérée à l'extérieur de Chrome. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Frais</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, appuyez sur la touche Tabulation, puis sur la touche Entrée pour reprendre votre recherche et voir l'activité pertinente dans votre historique de Chrome</translation> <translation id="9119042192571987207">Téléversé</translation> <translation id="9128016270925453879">Les politiques ont été chargées</translation> <translation id="9128870381267983090">Connexion au réseau</translation> diff --git a/components/strings/components_strings_fr.xtb b/components/strings/components_strings_fr.xtb index 47a2c3fb89a6b2..28969c73a9d289 100644 --- a/components/strings/components_strings_fr.xtb +++ b/components/strings/components_strings_fr.xtb @@ -732,6 +732,7 @@ Par défaut, ce type d'accès est bloqué par vos paramètres de confidentialit <translation id="3631244953324577188">Biométrie</translation> <translation id="3633738897356909127">Bouton "Mise à jour de Chrome" : appuyer sur Entrée pour mettre à jour Chrome depuis les paramètres du navigateur</translation> <translation id="3634530185120165534">Bac 5</translation> +<translation id="3637662659967048211">Enregistrer dans le compte Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Application :</translation> <translation id="3650584904733503804">Validation réussie.</translation> @@ -1409,6 +1410,7 @@ Par défaut, ce type d'accès est bloqué par vos paramètres de confidentialit <translation id="6106989379647458772">Il est possible que la page Web située à l'adresse <ph name="PAGE" /> soit temporairement inaccessible ou qu'elle ait été déplacée de façon permanente à une nouvelle adresse Web.</translation> <translation id="6107012941649240045">Émis pour</translation> <translation id="610911394827799129">Votre compte Google conserve peut-être d'autres contenus d'historique de navigation sur la page <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Bouton "Reprendre les recherches", appuyez sur Entrée pour reprendre vos recherches et voir les activités pertinentes dans votre historique Chrome</translation> <translation id="6116338172782435947">Voir le texte et les images copiés dans le presse-papiers</translation> <translation id="6120179357481664955">Souhaitez-vous mémoriser votre ID UPI ?</translation> <translation id="6123290840358279103">Afficher la carte virtuelle</translation> @@ -1484,6 +1486,7 @@ Par défaut, ce type d'accès est bloqué par vos paramètres de confidentialit <translation id="6423385022588644828">Confirmez désormais vos cartes plus rapidement avec Touch ID</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Pli en volets</translation> +<translation id="6428146287756735566">Reprenez vos recherches pour voir les activités pertinentes dans votre historique Chrome</translation> <translation id="6428450836711225518">Validez votre numéro de téléphone</translation> <translation id="6433490469411711332">Modifier les coordonnées</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> n'autorise pas la connexion.</translation> @@ -1535,6 +1538,7 @@ Par défaut, ce type d'accès est bloqué par vos paramètres de confidentialit <translation id="6643016212128521049">Effacer</translation> <translation id="6645291930348198241">Accéder aux cookies et aux données de site.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Aucun}=1{De 1 site (vous ne serez pas déconnecté de votre compte Google)}one{De # site (vous ne serez pas déconnecté de votre compte Google)}other{De # sites (vous ne serez pas déconnecté de votre compte Google)}}</translation> +<translation id="6647197322759179819">Reprendre les recherches</translation> <translation id="6648459603387803038">Votre administrateur peut modifier à distance la configuration de votre navigateur. Il se peut que l'activité sur cet appareil soit gérée en dehors de Chrome.</translation> <translation id="6648524591329069940">Police Serif</translation> <translation id="6651270836885078973">Gérées par :</translation> @@ -2186,6 +2190,7 @@ Informations supplémentaires : <translation id="9114524666733003316">Validation de la carte…</translation> <translation id="9114581008513152754">Ce navigateur n'est géré par aucune entreprise ni aucune autre organisation. Il se peut que l'activité sur cet appareil soit gérée en dehors de Chrome. <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Frais</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, appuyez sur la touche Tabulation, puis sur Entrée pour reprendre vos recherches et voir les activités pertinentes dans votre historique Chrome</translation> <translation id="9119042192571987207">Importation terminée</translation> <translation id="9128016270925453879">Les règles sont chargées</translation> <translation id="9128870381267983090">Connectez-vous au réseau</translation> diff --git a/components/strings/components_strings_gl.xtb b/components/strings/components_strings_gl.xtb index d689d82fcfe441..e3076a6c3a768f 100644 --- a/components/strings/components_strings_gl.xtb +++ b/components/strings/components_strings_gl.xtb @@ -731,6 +731,7 @@ En caso contrario, a configuración de privacidade impedirao. Se o permites, o c <translation id="3631244953324577188">Autenticación biométrica</translation> <translation id="3633738897356909127">Botón Actualizar Chrome. Preme Intro para actualizar Chrome desde a configuración do navegador</translation> <translation id="3634530185120165534">Bandexa 5</translation> +<translation id="3637662659967048211">Gardar na Conta de Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplicación:</translation> <translation id="3650584904733503804">Validación realizada correctamente</translation> @@ -1408,6 +1409,7 @@ En caso contrario, a configuración de privacidade impedirao. Se o permites, o c <translation id="6106989379647458772">É posible que a páxina web de <ph name="PAGE" /> estea temporalmente inactiva ou que se trasladase definitivamente a un enderezo web novo.</translation> <translation id="6107012941649240045">Emitido para</translation> <translation id="610911394827799129">É posible que a túa conta de Google teña outras formas do historial de navegación en <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Botón Retomar percorrido; para retomar o percorrido e ver a actividade relevante do teu historial de Chrome, preme Introducir</translation> <translation id="6116338172782435947">Ver o texto e as imaxes que se copian no portapapeis</translation> <translation id="6120179357481664955">Queres lembrar o teu código da UPI?</translation> <translation id="6123290840358279103">Ver tarxeta virtual</translation> @@ -1483,6 +1485,7 @@ En caso contrario, a configuración de privacidade impedirao. Se o permites, o c <translation id="6423385022588644828">A partir de agora, confirma as tarxetas máis rápido con Touch ID</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Dobrez en ventá</translation> +<translation id="6428146287756735566">Retoma o percorrido para ver a actividade relevante do teu historial de Chrome</translation> <translation id="6428450836711225518">Verificar o teu número de teléfono</translation> <translation id="6433490469411711332">Editar información de contacto</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> rexeitou a conexión.</translation> @@ -1534,6 +1537,7 @@ En caso contrario, a configuración de privacidade impedirao. Se o permites, o c <translation id="6643016212128521049">Borrar</translation> <translation id="6645291930348198241">Acceder ás cookies e aos datos dos sitios.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Ningún}=1{De 1 sitio (non se pechará sesión na túa conta de Google)}other{De # sitios (non se pechará sesión na túa conta de Google)}}</translation> +<translation id="6647197322759179819">Retomar percorrido</translation> <translation id="6648459603387803038">O teu administrador pode cambiar a configuración do navegador de forma remota. A actividade deste dispositivo tamén se pode xestionar fóra de Chrome.</translation> <translation id="6648524591329069940">Tipo de letra con serifas</translation> <translation id="6651270836885078973">Xestionadas por:</translation> @@ -2185,6 +2189,7 @@ Detalles adicionais: <translation id="9114524666733003316">Confirmando tarxeta…</translation> <translation id="9114581008513152754">Ningunha compañía ou organización xestiona este navegador. A actividade deste dispositivo pódese xestionar fóra de Chrome. <ph name="BEGIN_LINK" />Máis información<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Novo</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />; para retomar o percorrido e ver a actividade relevante do teu historial de Chrome, preme Tabulador e, despois, Introducir</translation> <translation id="9119042192571987207">Cargouse</translation> <translation id="9128016270925453879">Cargáronse as políticas</translation> <translation id="9128870381267983090">Conectarse á rede</translation> diff --git a/components/strings/components_strings_hi.xtb b/components/strings/components_strings_hi.xtb index 2dbda10686acb5..a0261ac48629a6 100644 --- a/components/strings/components_strings_hi.xtb +++ b/components/strings/components_strings_hi.xtb @@ -732,6 +732,7 @@ <translation id="3631244953324577188">बायोमेट्रिक्स</translation> <translation id="3633738897356909127">'Chrome अपडेट करें' बटन, अपनी Chrome सेटिंग से Chrome अपडेट करने के लिए Enter दबाएं</translation> <translation id="3634530185120165534">ट्रे 5</translation> +<translation id="3637662659967048211">Google खाते में सेव करें</translation> <translation id="3640766068866876100">इंडेक्स-4x6-एक्स्ट्रा</translation> <translation id="3642638418806704195">ऐप्लिकेशन:</translation> <translation id="3650584904733503804">मान्यकरण सफल</translation> @@ -1409,6 +1410,7 @@ <translation id="6106989379647458772">हो सकता है कि <ph name="PAGE" /> पर मौजूद वेबपेज अस्थायी रूप से काम नहीं कर रहा हो या उसे स्थायी रूप से किसी नए वेब पते पर ले जाया गया हो.</translation> <translation id="6107012941649240045">इसको जारी</translation> <translation id="610911394827799129">आपके Google खाते में <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> पर दूसरी तरह के ब्राउज़िंग इतिहास हो सकते हैं</translation> +<translation id="6113594885686374546">ढूंढना जारी रखने के लिए बटन, ढूंढना जारी रखने के लिए Enter दबाएं. इससे आपको 'Chrome इतिहास' में मिलती-जुलती गतिविधि दिखेगी</translation> <translation id="6116338172782435947">क्लिपबोर्ड पर कॉपी किए गए लेख और इमेज देखें</translation> <translation id="6120179357481664955">क्या आप चाहते हैं कि हम आपका UPI आईडी रखें?</translation> <translation id="6123290840358279103">वर्चुअल कार्ड देखें</translation> @@ -1484,6 +1486,7 @@ <translation id="6423385022588644828">अब Touch ID का इस्तेमाल करके अपने कार्ड की जल्दी पुष्टि करें</translation> <translation id="6425092077175753609">मटीरियल</translation> <translation id="6427730057873428458">गेट फ़ोल्ड</translation> +<translation id="6428146287756735566">अपने 'Chrome इतिहास' में मिलती-जुलती गतिविधि देखने के लिए ढूंढना जारी रखें</translation> <translation id="6428450836711225518">अपने फ़ोन नंबर की पुष्टि करें</translation> <translation id="6433490469411711332">संपर्क जानकारी में बदलाव करें</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> ने कनेक्ट करने से मना कर दिया है.</translation> @@ -1535,6 +1538,7 @@ <translation id="6643016212128521049">साफ़ करें</translation> <translation id="6645291930348198241">कुकी और साइट के डेटा को ऐक्सेस करना चाहती है.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{कोई नहीं}=1{1 साइट से (आप अपने Google खाते से साइन आउट नहीं होंगे)}one{# साइटों से (आप अपने Google खाते से साइन आउट नहीं होंगे)}other{# साइटों से (आप अपने Google खाते से साइन आउट नहीं होंगे)}}</translation> +<translation id="6647197322759179819">ढूंढना जारी रखें</translation> <translation id="6648459603387803038">आपका एडमिन किसी दूसरे डिवाइस से आपके ब्राउज़र का सेट अप बदल सकता है. इस डिवाइस की गतिविधि को Chrome से बाहर भी प्रबंधित किया जा सकता है.</translation> <translation id="6648524591329069940">Serif फ़ॉन्ट</translation> <translation id="6651270836885078973">इसे यह मैनेज करता है:</translation> @@ -2187,6 +2191,7 @@ <translation id="9114524666733003316">कार्ड की पुष्टि की जा रही है...</translation> <translation id="9114581008513152754">यह ब्राउज़र कोई कंपनी या दूसरा संगठन प्रबंधित नहीं करता. इस डिवाइस की गतिविधि Chrome से बाहर प्रबंधित की जा सकती है. <ph name="BEGIN_LINK" />ज़्यादा जानें<ph name="END_LINK" /></translation> <translation id="9117930699067497412">ताज़ा</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, ढूंढना जारी रखने के लिए Tab दबाएं और फिर Enter दबाएं. इससे आपको 'Chrome इतिहास' में मिलती-जुलती गतिविधि दिखेगी</translation> <translation id="9119042192571987207">अपलोड किया गया</translation> <translation id="9128016270925453879">नीतियां लोड हो गई हैं</translation> <translation id="9128870381267983090">नेटवर्क से कनेक्ट करें</translation> diff --git a/components/strings/components_strings_hr.xtb b/components/strings/components_strings_hr.xtb index 0a6cf61a2314be..5879efa929cd0c 100644 --- a/components/strings/components_strings_hr.xtb +++ b/components/strings/components_strings_hr.xtb @@ -733,6 +733,7 @@ To će u suprotnom biti onemogućeno na temelju vaših postavki privatnosti. To <translation id="3631244953324577188">Biometrijski podaci</translation> <translation id="3633738897356909127">Gumb Ažuriranje Chromea, pritisnite Enter da biste ažurirali Chrome u postavkama Chromea</translation> <translation id="3634530185120165534">Ladica 5</translation> +<translation id="3637662659967048211">Spremanje na Google račun</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplikacija:</translation> <translation id="3650584904733503804">Valjanost je uspješna</translation> @@ -1411,6 +1412,7 @@ To će u suprotnom biti onemogućeno na temelju vaših postavki privatnosti. To <translation id="6106989379647458772">Web-stranica na <ph name="PAGE" /> možda privremeno nije dostupna ili je trajno premještena na novu web-adresu.</translation> <translation id="6107012941649240045">Izdano za</translation> <translation id="610911394827799129">Na vašem Google računu možda postoje drugi oblici povijesti pregledavanja na stranici <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Gumb Nastavi putovanje, pritisnite Enter da biste nastavili putovanje i vidjeli relevantne aktivnosti u svojoj povijesti na Chromeu</translation> <translation id="6116338172782435947">vidjeti tekst i slike koje kopirate u međuspremnik</translation> <translation id="6120179357481664955">Upamtiti vaš UPI ID?</translation> <translation id="6123290840358279103">Prikaži virtualnu karticu</translation> @@ -1486,6 +1488,7 @@ To će u suprotnom biti onemogućeno na temelju vaših postavki privatnosti. To <translation id="6423385022588644828">Odsad brže potvrdite svoje kartice upotrebom značajke Touch ID.</translation> <translation id="6425092077175753609">Materijal</translation> <translation id="6427730057873428458">Presavijanje u obliku prozora</translation> +<translation id="6428146287756735566">Nastavite putovanje da biste vidjeli relevantne aktivnosti u svojoj povijesti na Chromeu</translation> <translation id="6428450836711225518">Potvrdite svoj telefonski broj</translation> <translation id="6433490469411711332">Uređivanje podataka za kontakt</translation> <translation id="6433595998831338502">Host <ph name="HOST_NAME" /> odbio je povezivanje.</translation> @@ -1537,6 +1540,7 @@ To će u suprotnom biti onemogućeno na temelju vaših postavki privatnosti. To <translation id="6643016212128521049">Izbriši</translation> <translation id="6645291930348198241">pristupiti kolačićima i podacima web-lokacije.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Nijedna}=1{S jedne web-lokacije (nećete se odjaviti s Google računa)}one{S # web-lokacije (nećete se odjaviti s Google računa)}few{S # web-lokacije (nećete se odjaviti s Google računa)}other{S # web-lokacija (nećete se odjaviti s Google računa)}}</translation> +<translation id="6647197322759179819">Nastavi putovanje</translation> <translation id="6648459603387803038">Vaš administrator može daljinski promijeniti postavke preglednika. Aktivnostima na ovom uređaju može se upravljati i izvan Chromea.</translation> <translation id="6648524591329069940">Font Serif</translation> <translation id="6651270836885078973">Upravlja:</translation> @@ -2190,6 +2194,7 @@ i netočne vjerodajnice. To može značiti da se neki napadač pokušava predsta <translation id="9114524666733003316">Potvrđivanje kartice...</translation> <translation id="9114581008513152754">Preglednikom ne upravlja tvrtka ili neka druga organizacija. Aktivnostima na ovom uređaju možda se upravlja izvan Chromea. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Novo</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, a zatim Enter da biste nastavili putovanje i vidjeli relevantne aktivnosti u svojoj povijesti na Chromeu</translation> <translation id="9119042192571987207">Preneseno</translation> <translation id="9128016270925453879">Pravila se učitavaju</translation> <translation id="9128870381267983090">Povezivanje s mrežom</translation> diff --git a/components/strings/components_strings_hu.xtb b/components/strings/components_strings_hu.xtb index 97f335d95fcf1e..70d569fd936acb 100644 --- a/components/strings/components_strings_hu.xtb +++ b/components/strings/components_strings_hu.xtb @@ -730,6 +730,7 @@ Ezt egyéb esetben letiltják az Ön adatvédelmi beállításai. Az engedélyez <translation id="3631244953324577188">Biometria</translation> <translation id="3633738897356909127">Chrome frissítése gomb, nyomja le az Enter billentyűt a Chrome-nak a Chrome beállításaiban való frissítéséhez</translation> <translation id="3634530185120165534">5. tálca</translation> +<translation id="3637662659967048211">Mentés Google-fiókba</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Alkalmazás:</translation> <translation id="3650584904733503804">Sikeres érvényesítés</translation> @@ -1407,6 +1408,7 @@ Ezt egyéb esetben letiltják az Ön adatvédelmi beállításai. Az engedélyez <translation id="6106989379647458772">Előfordulhat, hogy a(z) <ph name="PAGE" /> webhelyen található oldal ideiglenesen nem érhető el, vagy véglegesen új címre költözött.</translation> <translation id="6107012941649240045">Tulajdonos</translation> <translation id="610911394827799129">Előfordulhat, hogy a böngészési előzmények más formái még megtalálhatók Google-fiókjában a <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> webhelyen</translation> +<translation id="6113594885686374546">Keresés folytatása gomb, nyomja le az Enter billentyűt, ha folytatni szeretné a keresést, és meg szeretné tekinteni a releváns tevékenységet Chrome-előzményei között</translation> <translation id="6116338172782435947">Megtekinteni a vágólapra másolt szövegeket és képeket</translation> <translation id="6120179357481664955">Emlékszik UPI-azonosítójára?</translation> <translation id="6123290840358279103">Virtuális kártya megtekintése</translation> @@ -1482,6 +1484,7 @@ Ezt egyéb esetben letiltják az Ön adatvédelmi beállításai. Az engedélyez <translation id="6423385022588644828">Mostantól gyorsabban igazolhatja kártyáit a Touch ID használatával</translation> <translation id="6425092077175753609">Anyag</translation> <translation id="6427730057873428458">Kihajtható</translation> +<translation id="6428146287756735566">Keresés folytatása a Chrome-előzmények között található releváns tevékenységek megtekintéséhez</translation> <translation id="6428450836711225518">Telefonszám ellenőrzése</translation> <translation id="6433490469411711332">Kapcsolattartási adatok szerkesztése</translation> <translation id="6433595998831338502">A(z) <ph name="HOST_NAME" /> visszautasította a csatlakozást.</translation> @@ -1533,6 +1536,7 @@ Ezt egyéb esetben letiltják az Ön adatvédelmi beállításai. Az engedélyez <translation id="6643016212128521049">Törlés</translation> <translation id="6645291930348198241">Hozzáférés a cookie-khoz és a webhelyadatokhoz.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Nincs}=1{1 webhelyről (a böngésző nem jelentkezteti ki Google-fiókjából)}other{# webhelyről (a böngésző nem jelentkezteti ki Google-fiókjából)}}</translation> +<translation id="6647197322759179819">Keresés folytatása</translation> <translation id="6648459603387803038">A rendszergazda távolról módosítani tudja a böngészőbeállításokat. Az is lehetséges, hogy az eszközön végzett tevékenységeket a Chrome-on kívülről felügyelik.</translation> <translation id="6648524591329069940">Serif betűtípus</translation> <translation id="6651270836885078973">Kezelő:</translation> @@ -2185,6 +2189,7 @@ További részletek: <translation id="9114524666733003316">Kártya ellenőrzése…</translation> <translation id="9114581008513152754">Ezt a böngészőt nem kezeli cég vagy más szervezet. Lehetséges, hogy az eszközön végzett tevékenységeket a Chrome-on kívülről felügyelik. <ph name="BEGIN_LINK" />További információ<ph name="END_LINK" />.</translation> <translation id="9117930699067497412">Friss</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, nyomja le a Tab, majd az Enter billentyűt, ha folytatni szeretné a keresést, és meg szeretné tekinteni a releváns tevékenységet Chrome-előzményei között</translation> <translation id="9119042192571987207">Feltöltve</translation> <translation id="9128016270925453879">Házirendek betöltve</translation> <translation id="9128870381267983090">Csatlakozás hálózathoz</translation> diff --git a/components/strings/components_strings_hy.xtb b/components/strings/components_strings_hy.xtb index 2a09d50a372865..9dda317ba98fce 100644 --- a/components/strings/components_strings_hy.xtb +++ b/components/strings/components_strings_hy.xtb @@ -734,6 +734,7 @@ <translation id="3631244953324577188">Կենսաչափական համակարգեր</translation> <translation id="3633738897356909127">«Թարմացնել Chrome-ը» կոճակ։ Սեղմեք Enter՝ Chrome-ը թարմացելու համար։</translation> <translation id="3634530185120165534">Դարակ 5</translation> +<translation id="3637662659967048211">Պահեք Google հաշվում</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Ծրագիրը՝</translation> <translation id="3650584904733503804">Վավերացումը հաջողվեց</translation> @@ -1411,6 +1412,7 @@ <translation id="6106989379647458772">Հնարավոր է, որ <ph name="PAGE" /> կայքէջը ժամանակավորապես անհասանելի է կամ մշտապես տեղափոխվել է նոր հասցե:</translation> <translation id="6107012941649240045">Տրված`</translation> <translation id="610911394827799129">Ձեր Google հաշվում կարող են լինել այցելությունների պատմության այլ ձևեր ևս: Դրանք կարող եք գտնել <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> էջում:</translation> +<translation id="6113594885686374546">«Շարունակել որոնումը» կոճակ։ Chrome-ի պատմության մեջ նման հարցումները դիտելու համար սեղմեք Enter։</translation> <translation id="6116338172782435947">Տեսնել սեղմատախտակին պատճենված տեքստը և պատկերները</translation> <translation id="6120179357481664955">Հիշո՞ւմ եք ձեր UPI ID-ն</translation> <translation id="6123290840358279103">Դիտել վիրտուալ քարտը</translation> @@ -1486,6 +1488,7 @@ <translation id="6423385022588644828">Այսուհետ ավելի արագ հաստատեք ձեր քարտերը Touch ID-ի միջոցով</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Երկփեղկ ծալում</translation> +<translation id="6428146287756735566">Դիտել նման հարցումներ Chrome-ի պատմության մեջ</translation> <translation id="6428450836711225518">Հաստատեք ձեր հեռախոսահամարը</translation> <translation id="6433490469411711332">Փոփոխեք կոնտակտային տվյալները</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" />-ը մերժեց կապակցումը:</translation> @@ -1537,6 +1540,7 @@ <translation id="6643016212128521049">Մաքրել</translation> <translation id="6645291930348198241">Օգտագործել քուքիներն ու կայքի տվյալները։</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Ոչինչ չկա}=1{1 կայքից (դուք դուրս չեք գա ձեր Google հաշվից)}one{# կայքից (դուք դուրս չեք գա ձեր Google հաշվից)}other{# կայքից (դուք դուրս չեք գա ձեր Google հաշվից)}}</translation> +<translation id="6647197322759179819">Շարունակել որոնումը</translation> <translation id="6648459603387803038">Ձեր ադմինիստրատորը կարող է հեռակա փոխել ձեր դիտարկիչի կարգավորումները։ Սարքում արվող գործողությունները նույնպես կարող են կառավարվել Chrome-ից դուրս։</translation> <translation id="6648524591329069940">Serif տառատեսակ</translation> <translation id="6651270836885078973">Կառավարիչ՝</translation> @@ -2188,6 +2192,7 @@ <translation id="9114524666733003316">Քարտի հաստատում...</translation> <translation id="9114581008513152754">Ձեր դիտարկիչը չի կառավարվում որևէ ընկերության կամ կազմակերպության կողմից։ Սարքում արվող գործողությունները կարող են կառավարվել Chrome-ից դուրս։ <ph name="BEGIN_LINK" />Իմանալ ավելին<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Թարմ</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />։ Chrome-ի պատմության մեջ նման հարցումները դիտելու համար սեղմեք Tab, ապա՝ Enter։</translation> <translation id="9119042192571987207">Վերբեռնված է</translation> <translation id="9128016270925453879">Կանոնները բեռնվել են</translation> <translation id="9128870381267983090">Կապակցեք ցանցին</translation> diff --git a/components/strings/components_strings_id.xtb b/components/strings/components_strings_id.xtb index 8ac6e2bb12f454..b1d62d17ed90b7 100644 --- a/components/strings/components_strings_id.xtb +++ b/components/strings/components_strings_id.xtb @@ -729,6 +729,7 @@ Jika tidak, ini akan diblokir oleh setelan privasi Anda. Ini akan memungkinkan k <translation id="3631244953324577188">Biometrik</translation> <translation id="3633738897356909127">Tombol Update Chrome, tekan Enter untuk mengupdate Chrome dari setelan Chrome</translation> <translation id="3634530185120165534">Baki 5</translation> +<translation id="3637662659967048211">Simpan ke Akun Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplikasi:</translation> <translation id="3650584904733503804">Validasi berhasil</translation> @@ -1401,6 +1402,7 @@ Jika tidak, ini akan diblokir oleh setelan privasi Anda. Ini akan memungkinkan k <translation id="6106989379647458772">Halaman web di <ph name="PAGE" /> mungkin tidak aktif untuk sementara atau dipindahkan secara permanen ke alamat web baru.</translation> <translation id="6107012941649240045">Diterbitkan Untuk</translation> <translation id="610911394827799129">Akun Google Anda mungkin memiliki bentuk histori penjelajahan lainnya di <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Tombol Lanjutkan penelusuran, tekan Enter untuk melanjutkan penelusuran dan melihat aktivitas yang relevan di histori Chrome Anda</translation> <translation id="6116338172782435947">Melihat teks dan gambar yang disalin ke papan klip</translation> <translation id="6120179357481664955">Ingat ID UPI Anda?</translation> <translation id="6123290840358279103">Lihat kartu virtual</translation> @@ -1476,6 +1478,7 @@ Jika tidak, ini akan diblokir oleh setelan privasi Anda. Ini akan memungkinkan k <translation id="6423385022588644828">Mulai sekarang, konfirmasikan kartu Anda lebih cepat menggunakan Touch ID</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Gate fold</translation> +<translation id="6428146287756735566">Lanjutkan penelusuran untuk melihat aktivitas yang relevan di histori Chrome Anda</translation> <translation id="6428450836711225518">Verifikasi nomor telepon Anda</translation> <translation id="6433490469411711332">Edit info kontak</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> menolak untuk tersambung.</translation> @@ -1527,6 +1530,7 @@ Jika tidak, ini akan diblokir oleh setelan privasi Anda. Ini akan memungkinkan k <translation id="6643016212128521049">Hapus</translation> <translation id="6645291930348198241">Mengakses cookie dan data situs.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Tidak ada}=1{Dari 1 situs (Anda tidak akan logout dari Akun Google)}other{Dari # situs (Anda tidak akan logout dari Akun Google)}}</translation> +<translation id="6647197322759179819">Lanjutkan penelusuran</translation> <translation id="6648459603387803038">Administrator dapat mengubah penyiapan browser Anda dari jarak jauh. Aktivitas di perangkat ini juga dapat dikelola di luar Chrome.</translation> <translation id="6648524591329069940">Font Serif</translation> <translation id="6651270836885078973">Dikelola oleh:</translation> @@ -2174,6 +2178,7 @@ Jika tidak, ini akan diblokir oleh setelan privasi Anda. Ini akan memungkinkan k <translation id="9114524666733003316">Mengonfirmasi kartu...</translation> <translation id="9114581008513152754">Browser ini tidak dikelola oleh perusahaan atau organisasi lain. Aktivitas di perangkat ini mungkin dikelola di luar Chrome. <ph name="BEGIN_LINK" />Pelajari lebih lanjut<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Baru</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, tekan Tab, lalu Enter untuk melanjutkan penelusuran dan melihat aktivitas yang relevan di histori Chrome Anda</translation> <translation id="9119042192571987207">Diupload</translation> <translation id="9128016270925453879">Kebijakan dimuat</translation> <translation id="9128870381267983090">Sambungkan ke jaringan</translation> diff --git a/components/strings/components_strings_is.xtb b/components/strings/components_strings_is.xtb index d7e6ad54effa8f..a79b8231f974a4 100644 --- a/components/strings/components_strings_is.xtb +++ b/components/strings/components_strings_is.xtb @@ -735,6 +735,7 @@ og röng skilríki til baka. Þetta getur gerst þegar tölvuþrjótur reynir a <translation id="3631244953324577188">Lífkenni</translation> <translation id="3633738897356909127">Hnappurinn Uppfæra Chrome, ýttu á Enter til að uppfæra Chrome úr stillingum Chrome</translation> <translation id="3634530185120165534">Bakki 5</translation> +<translation id="3637662659967048211">Vista á Google reikningi</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Forrit:</translation> <translation id="3650584904733503804">Sannvottun heppnaðist</translation> @@ -1412,6 +1413,7 @@ og röng skilríki til baka. Þetta getur gerst þegar tölvuþrjótur reynir a <translation id="6106989379647458772">Vefsíðan á <ph name="PAGE" /> gæti legið niðri tímabundið eða hafa verið færð á nýtt veffang fyrir fullt og allt.</translation> <translation id="6107012941649240045">Úthlutað til</translation> <translation id="610911394827799129">Google reikningurinn þinn kann að vera með annars konar vefskoðunarferil á <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Hnappur til að halda ferðinni áfram, ýttu á Enter til að halda ferðinni áfram og sjá viðkomandi virkni í Chrome ferlinum</translation> <translation id="6116338172782435947">Sjá texta og myndir sem þú afritar á klippiborðið</translation> <translation id="6120179357481664955">Muna eftir UPI-auðkenni?</translation> <translation id="6123290840358279103">Skoða sýndarkort</translation> @@ -1487,6 +1489,7 @@ og röng skilríki til baka. Þetta getur gerst þegar tölvuþrjótur reynir a <translation id="6423385022588644828">Staðfestu kortin þín hraðar með því að nota Touch ID héðan í frá</translation> <translation id="6425092077175753609">Nýja útlitshönnunin</translation> <translation id="6427730057873428458">Bæklingabrot</translation> +<translation id="6428146287756735566">Haltu ferðinni áfram til að sjá viðkomandi virkni í Chrome ferlinum</translation> <translation id="6428450836711225518">Staðfestu símanúmerið þitt</translation> <translation id="6433490469411711332">Breyta samskiptaupplýsingum</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> neitaði að koma á tengingu.</translation> @@ -1538,6 +1541,7 @@ og röng skilríki til baka. Þetta getur gerst þegar tölvuþrjótur reynir a <translation id="6643016212128521049">Hreinsa</translation> <translation id="6645291930348198241">Fá aðgang að fótsporum og gögnum vefsvæða.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Ekkert}=1{Frá einu vefsvæði (þú verður ekki skráð(ur) út af Google reikningnum þínum)}one{Frá # vefsvæði (þú verður ekki skráð(ur) út af Google reikningnum þínum)}other{Frá # vefsvæðum (þú verður ekki skráð(ur) út af Google reikningnum þínum)}}</translation> +<translation id="6647197322759179819">Halda ferðinni áfram</translation> <translation id="6648459603387803038">Kerfisstjórinn þinn getur breytt uppsetningu vafrans með fjartengingu. Virkni þinni í þessu tæki er einnig hægt að stjórna utan Chrome.</translation> <translation id="6648524591329069940">Serif-letur</translation> <translation id="6651270836885078973">Stjórnað af:</translation> @@ -2189,6 +2193,7 @@ og röng skilríki til baka. Þetta getur gerst þegar tölvuþrjótur reynir a <translation id="9114524666733003316">Staðfestir kort...</translation> <translation id="9114581008513152754">Þessi vafri er ekki í umsjón fyrirtækis eða annarrar stofnunar. Hægt er að hafa umsjón með aðgerðum í þessu tæki utan Chrome. <ph name="BEGIN_LINK" />Frekari upplýsingar<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Ferskt</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, ýttu á dálkalykilinn og svo á Enter til að halda ferðinni áfram og sjá viðkomandi virkni í Chrome ferlinum</translation> <translation id="9119042192571987207">Sent</translation> <translation id="9128016270925453879">Reglum var hlaðið</translation> <translation id="9128870381267983090">Tengjast neti</translation> diff --git a/components/strings/components_strings_it.xtb b/components/strings/components_strings_it.xtb index adc9c7855d43fe..c9cf5d73f3a3a3 100644 --- a/components/strings/components_strings_it.xtb +++ b/components/strings/components_strings_it.xtb @@ -731,6 +731,7 @@ In caso contrario l'uso sarà bloccato dalle impostazioni sulla privacy. I conte <translation id="3631244953324577188">Dati biometrici</translation> <translation id="3633738897356909127">Pulsante Aggiorna Chrome, premi Invio per aggiornare Chrome dalle relative impostazioni</translation> <translation id="3634530185120165534">Vassoio 5</translation> +<translation id="3637662659967048211">Salva nell'Account Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Applicazione:</translation> <translation id="3650584904733503804">Convalida riuscita</translation> @@ -1408,6 +1409,7 @@ In caso contrario l'uso sarà bloccato dalle impostazioni sulla privacy. I conte <translation id="6106989379647458772">La pagina web all'indirizzo <ph name="PAGE" /> potrebbe non essere momentaneamente disponibile o potrebbe essere stata trasferita definitivamente a un nuovo indirizzo web.</translation> <translation id="6107012941649240045">Rilasciato a</translation> <translation id="610911394827799129">Il tuo Account Google potrebbe avere altre forme di cronologia di navigazione all'indirizzo <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Pulsante Riprendi il percorso, premi Invio per riprendere il percorso e visualizzare le attività pertinenti nella tua cronologia di Chrome</translation> <translation id="6116338172782435947">Leggere testi e immagini copiati negli appunti</translation> <translation id="6120179357481664955">Ricordi il tuo ID UPI?</translation> <translation id="6123290840358279103">Visualizza carta virtuale</translation> @@ -1482,6 +1484,7 @@ In caso contrario l'uso sarà bloccato dalle impostazioni sulla privacy. I conte <translation id="6423385022588644828">Verifica più velocemente le tue carte usando Touch ID d'ora in poi</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Piegatura a finestra</translation> +<translation id="6428146287756735566">Riprendi il percorso per visualizzare le attività pertinenti nella tua cronologia di Chrome</translation> <translation id="6428450836711225518">Verifica il numero di telefono</translation> <translation id="6433490469411711332">Modifica informazioni di contatto</translation> <translation id="6433595998831338502">Connessione negata da <ph name="HOST_NAME" />.</translation> @@ -1533,6 +1536,7 @@ In caso contrario l'uso sarà bloccato dalle impostazioni sulla privacy. I conte <translation id="6643016212128521049">Cancella</translation> <translation id="6645291930348198241">Accedere a cookie e dati del sito.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Nessuno}=1{Da 1 sito (non verrai disconnesso dal tuo Account Google)}other{Da # siti (non verrai disconnesso dal tuo Account Google)}}</translation> +<translation id="6647197322759179819">Riprendi il percorso</translation> <translation id="6648459603387803038">L'amministratore può modificare da remoto la configurazione del browser. L'attività svolta su questo dispositivo potrebbe essere gestita anche al di fuori di Chrome.</translation> <translation id="6648524591329069940">Carattere serif</translation> <translation id="6651270836885078973">Gestiti da:</translation> @@ -2184,6 +2188,7 @@ Ulteriori dettagli: <translation id="9114524666733003316">Conferma della carta...</translation> <translation id="9114581008513152754">Questo browser non è gestito da un'azienda o da un'altra organizzazione. L'attività svolta su questo dispositivo potrebbe essere gestita al di fuori di Chrome. <ph name="BEGIN_LINK" />Ulteriori informazioni<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Vivace</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, premi Tab poi Invio per riprendere il percorso e visualizzare le attività pertinenti nella tua cronologia di Chrome</translation> <translation id="9119042192571987207">Caricato</translation> <translation id="9128016270925453879">I criteri sono stati caricati</translation> <translation id="9128870381267983090">Collegati alla rete</translation> diff --git a/components/strings/components_strings_iw.xtb b/components/strings/components_strings_iw.xtb index f98f308e139cb0..4da5a2d38fd5c5 100644 --- a/components/strings/components_strings_iw.xtb +++ b/components/strings/components_strings_iw.xtb @@ -734,6 +734,7 @@ <translation id="3631244953324577188">מידע ביומטרי</translation> <translation id="3633738897356909127">הלחצן 'עדכון Chrome', יש להקיש על Enter כדי לעדכן את דפדפן Chrome בהגדרות Chrome</translation> <translation id="3634530185120165534">מגש 5</translation> +<translation id="3637662659967048211">שמירה בחשבון Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">אפליקציה:</translation> <translation id="3650584904733503804">האימות בוצע בהצלחה</translation> @@ -1414,6 +1415,7 @@ Del</translation> <translation id="6106989379647458772">ייתכן שדף האינטרנט בכתובת <ph name="PAGE" /> אינו פעיל זמנית, או שהוא הועבר לכתובת אינטרנט קבועה אחרת.</translation> <translation id="6107012941649240045">מונפק ל</translation> <translation id="610911394827799129">ייתכן שיהיה אפשר לגשת לסוגים אחרים של היסטוריית גלישה בחשבון Google בכתובת <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">הלחצן 'המשך התהליך', יש להקיש על Enter להמשך התהליך ולהצגת פעילות רלוונטית בהיסטוריה ב-Chrome</translation> <translation id="6116338172782435947">גישה אל טקסט ותמונות שהועתקו ללוח</translation> <translation id="6120179357481664955">מזהה UPI שלך זכור לך?</translation> <translation id="6123290840358279103">לצפייה בכרטיס הווירטואלי</translation> @@ -1489,6 +1491,7 @@ Del</translation> <translation id="6423385022588644828">כדי לאשר את הכרטיסים שלך מהר יותר, אפשר להשתמש ב-Touch ID מעכשיו והלאה</translation> <translation id="6425092077175753609">עיצוב חדשני תלת-ממדי</translation> <translation id="6427730057873428458">כנף בקיפול</translation> +<translation id="6428146287756735566">המשך התהליך מאפשר הצגת פעילות רלוונטית בהיסטוריה שלך ב-Chrome</translation> <translation id="6428450836711225518">אימות מספר הטלפון שלך</translation> <translation id="6433490469411711332">עריכת הפרטים ליצירת קשר</translation> <translation id="6433595998831338502">לא ניתן היה להתחבר אל <ph name="HOST_NAME" />.</translation> @@ -1540,6 +1543,7 @@ Del</translation> <translation id="6643016212128521049">ניקוי</translation> <translation id="6645291930348198241">לקבל גישה לקובצי Cookie ולנתוני אתרים.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{ללא}=1{מאתר אחד (לא תבוצע יציאה מחשבון Google שלך.)}two{מ-# אתרים (לא תבוצע יציאה מחשבון Google שלך.)}many{מ-# אתרים (לא תבוצע יציאה מחשבון Google שלך.)}other{מ-# אתרים (לא תבוצע יציאה מחשבון Google שלך.)}}</translation> +<translation id="6647197322759179819">המשך התהליך</translation> <translation id="6648459603387803038">מנהל המערכת יכול לשנות את הגדרת הדפדפן שלך מרחוק. בנוסף, ניתן לנהל את הפעילות במכשיר הזה מחוץ ל-Chrome.</translation> <translation id="6648524591329069940">גופן Serif</translation> <translation id="6651270836885078973">בניהול של:</translation> @@ -2191,6 +2195,7 @@ Del</translation> <translation id="9114524666733003316">אישור הכרטיס מתבצע...</translation> <translation id="9114581008513152754">הדפדפן הזה לא מנוהל על ידי חברה או ארגון אחר. ייתכן שהפעילות במכשיר הזה מנוהלת מחוץ ל-Chrome. <ph name="BEGIN_LINK" />מידע נוסף<ph name="END_LINK" /></translation> <translation id="9117930699067497412">מרענן</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, יש להקיש על Tab ואז על Enter להמשך התהליך ולהצגת פעילות רלוונטית בהיסטוריה ב-Chrome</translation> <translation id="9119042192571987207">הועלה</translation> <translation id="9128016270925453879">המדיניות נטענה</translation> <translation id="9128870381267983090">התחברות לרשת</translation> diff --git a/components/strings/components_strings_ja.xtb b/components/strings/components_strings_ja.xtb index 2c2d8073dc33d2..1820b261eb23f7 100644 --- a/components/strings/components_strings_ja.xtb +++ b/components/strings/components_strings_ja.xtb @@ -1713,7 +1713,7 @@ <translation id="7378594059915113390">メディアの操作</translation> <translation id="7378627244592794276">いいえ</translation> <translation id="7378810950367401542">/</translation> -<translation id="7386364858855961704">該当なし</translation> +<translation id="7386364858855961704">対象外です</translation> <translation id="7390545607259442187">カードの確認</translation> <translation id="7392089738299859607">住所を更新</translation> <translation id="7399802613464275309">安全確認</translation> diff --git a/components/strings/components_strings_ka.xtb b/components/strings/components_strings_ka.xtb index df3659754a457e..f0c527b2fd7936 100644 --- a/components/strings/components_strings_ka.xtb +++ b/components/strings/components_strings_ka.xtb @@ -728,6 +728,7 @@ <translation id="3631244953324577188">ბიომეტრიული მონაცემები</translation> <translation id="3633738897356909127">Chrome-ის განახლების ღილაკი, Chrome-ის პარამეტრებიდან Chrome-ის გასაახლებლად დააჭირეთ კლავიშს Enter</translation> <translation id="3634530185120165534">ლანგარი 5</translation> +<translation id="3637662659967048211">შეინახეთ Google ანგარიშში</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">აპლიკაცია:</translation> <translation id="3650584904733503804">წარმატებული შემოწმება</translation> @@ -1400,6 +1401,7 @@ <translation id="6106989379647458772"><ph name="PAGE" />-ზე არსებული ვებგვერდი შეიძლება იყოს დროებით გათიშული ან სამუდამოდ ახალ ვებ მისამართზე გადასული.</translation> <translation id="6107012941649240045">გაცემულია</translation> <translation id="610911394827799129">თქვენს Google ანგარიშში შეიძლება ინახებოდეს სხვა ტიპის დათვალიერების ისტორიაც, რომელიც ხელმისაწვდომია მისამართზე: <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">პროცესის გაგრძელების ღილაკი, პროცესის გასაგრძელებლად და თქვენს Chrome-ის ისტორიაში შესაბამისი აქტივობის სანახავად დააჭირეთ კლავიშს Tab, შემდეგ კი — Enter-ს</translation> <translation id="6116338172782435947">გაცვლის ბუფერში კოპირებული ტექსტისა და სურათების ნახვა</translation> <translation id="6120179357481664955">გსურთ თქვენი UPI ID-ს დამახსოვრება?</translation> <translation id="6123290840358279103">ვირტუალური ბარათის ჩვენება</translation> @@ -1475,6 +1477,7 @@ <translation id="6423385022588644828">დაადასტურეთ ბარათები უფრო სწრაფად ამიერიდან Touch ID-ს გამოყენების მეშვეობით</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">დაკეცვა ჭიშკრის ფორმით</translation> +<translation id="6428146287756735566">გააგრძელეთ პროცესი, თქვენს Chrome-ის ისტორიაში შესაბამისი აქტივობა რომ იხილოთ</translation> <translation id="6428450836711225518">დაადასტურეთ თქვენი ტელეფონის ნომერი</translation> <translation id="6433490469411711332">საკონტაქტო ინფორმაციის რედაქტირება</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" />-მა უარყო დაკავშირება.</translation> @@ -1526,6 +1529,7 @@ <translation id="6643016212128521049">გასუფთავება</translation> <translation id="6645291930348198241">ქუქი-ჩანაწერებსა და საიტის მონაცემებზე წვდომა.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{არცერთი}=1{1 საიტიდან (თქვენ არ გამოხვალთ Google ანგარიშიდან)}other{# საიტიდან (თქვენ არ გამოხვალთ Google ანგარიშიდან)}}</translation> +<translation id="6647197322759179819">პროცესის გაგრძელება</translation> <translation id="6648459603387803038">თქვენს ადმინისტრატორს დისტანციურად შეუძლია ბრაუზერში დაყენებული პარამეტრების შეცვლა. ამ მოწყობილობაზე აქტივობა შეიძლება იმართებოდეს Chrome-ს მიღმაც.</translation> <translation id="6648524591329069940">Serif შრიფტი</translation> <translation id="6651270836885078973">მმართველი:</translation> @@ -2177,6 +2181,7 @@ <translation id="9114524666733003316">მიმდინარეობს ბარათის დადასტურება...</translation> <translation id="9114581008513152754">ამ ბრაუზერს არ მართავს კომპანია თუ სხვა ორგანიზაცია. ამ მოწყობილობაზე აქტივობა შეიძლება იმართებოდეს Chrome-ს მიღმა. <ph name="BEGIN_LINK" />შეიტყვეთ მეტი<ph name="END_LINK" /></translation> <translation id="9117930699067497412">ნორჩი</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, პროცესის გასაგრძელებლად და თქვენს Chrome-ის ისტორიაში შესაბამისი აქტივობის სანახავად დააჭირეთ კლავიშს Tab, შემდეგ კი — Enter-ს</translation> <translation id="9119042192571987207">ატვირთულია</translation> <translation id="9128016270925453879">წესები ჩაიტვირთა</translation> <translation id="9128870381267983090">ქსელთან დაკავშირება</translation> diff --git a/components/strings/components_strings_kk.xtb b/components/strings/components_strings_kk.xtb index d7080b00806ef9..484ef527379853 100644 --- a/components/strings/components_strings_kk.xtb +++ b/components/strings/components_strings_kk.xtb @@ -733,6 +733,7 @@ <translation id="3631244953324577188">Биометрика</translation> <translation id="3633738897356909127">"Chrome-ды жаңарту" түймесі, Chrome параметрлерінен Chrome-ды жаңарту үшін Enter пернесін басыңыз.</translation> <translation id="3634530185120165534">5-науа</translation> +<translation id="3637662659967048211">Google есептік жазбасына сақтау</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Қолданба:</translation> <translation id="3650584904733503804">Тексеру сәтті аяқталды</translation> @@ -1410,6 +1411,7 @@ <translation id="6106989379647458772"><ph name="PAGE" /> мекенжайындағы веб-бет уақытша өшірілген немесе біржола жаңа мекенжайға көшірілген болуы мүмкін.</translation> <translation id="6107012941649240045">Кімге берілді</translation> <translation id="610911394827799129"><ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> бетінде Google есептік жазбасымен шолу тарихының басқа да үлгілері болуы мүмкін.</translation> +<translation id="6113594885686374546">Іздеуді жалғастыру түймесі. Іздеуді жалғастырып, Chrome тарихынан сәйкес сұрауларды көру үшін Enter пернесін басыңыз.</translation> <translation id="6116338172782435947">Буферге көшірілетін мәтіндер мен кескіндерді көру</translation> <translation id="6120179357481664955">UPI идентификаторы сақталсын ба?</translation> <translation id="6123290840358279103">Виртуалды картаны көру</translation> @@ -1485,6 +1487,7 @@ <translation id="6423385022588644828">Қазірден бастап Touch ID арқылы карталараңызды жылдам растаңыз</translation> <translation id="6425092077175753609">Материал</translation> <translation id="6427730057873428458">Қақпа тәрізді бүктеу</translation> +<translation id="6428146287756735566">Chrome тарихынан сәйкес сұрауларды көру үшін іздеуді жалғастыру</translation> <translation id="6428450836711225518">Телефон нөміріңізді растаңыз</translation> <translation id="6433490469411711332">Байланыс ақпаратын өңдеу</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> байланыстан бас тартты.</translation> @@ -1536,6 +1539,7 @@ <translation id="6643016212128521049">Тазалау</translation> <translation id="6645291930348198241">Cookie файлдарын және сайт деректерін пайдалану.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Жоқ}=1{1 сайттан (Google есептік жазбаңыздан шықпайсыз)}other{# сайттан (Google есептік жазбаңыздан шықпайсыз)}}</translation> +<translation id="6647197322759179819">Іздеуді жалғастыру</translation> <translation id="6648459603387803038">Браузер параметрін әкімші қашықтан өзгерте алады. Сонымен қатар құрылғыдағы әрекеттерді Chrome браузерінен тыс басқаруға болады.</translation> <translation id="6648524591329069940">Serif қарпі</translation> <translation id="6651270836885078973">Басқарушы:</translation> @@ -2187,6 +2191,7 @@ <translation id="9114524666733003316">Карта расталуда...</translation> <translation id="9114581008513152754">Бұл браузер компания немесе басқа ұйым арқылы басқарылмайды. Құрылғыдағы әрекет Chrome браузерінен тыс басқарылуы мүмкін. <ph name="BEGIN_LINK" />Толығырақ<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Жаңа</translation> +<translation id="9118692854637641831">"<ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />". Іздеуді жалғастырып, Chrome тарихынан сәйкес сұрауларды көру үшін Tab, сосын Enter пернесін басыңыз.</translation> <translation id="9119042192571987207">Жүктеп салынды</translation> <translation id="9128016270925453879">Саясаттар жүктелді.</translation> <translation id="9128870381267983090">Желіге қосылу</translation> diff --git a/components/strings/components_strings_km.xtb b/components/strings/components_strings_km.xtb index ee00468687c61e..6f1a4c2c08c8d0 100644 --- a/components/strings/components_strings_km.xtb +++ b/components/strings/components_strings_km.xtb @@ -737,6 +737,7 @@ <translation id="3631244953324577188">ជីវមាត្រ</translation> <translation id="3633738897356909127">ប៊ូតុង "ដំឡើងកំណែ Chrome" ចុច "Enter" ដើម្បីដំឡើងកំណែ Chrome ពីការកំណត់ Chrome របស់អ្នក</translation> <translation id="3634530185120165534">ទម្រទី 5</translation> +<translation id="3637662659967048211">រក្សាទុកនៅក្នុងគណនី Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">កម្មវិធី៖</translation> <translation id="3650584904733503804">ការពិនិត្យសុពលភាពបានជោគជ័យ</translation> @@ -1415,6 +1416,7 @@ <translation id="6106989379647458772">គេហទំព័រនៅ <ph name="PAGE" /> អាចមិនដំណើរការបណ្តោះអាសន្ន ឬវាអាចត្រូវបានផ្លាស់ទីទៅអាសយដ្ឋានគេហទំព័រថ្មី។</translation> <translation id="6107012941649240045">បោះផ្សាយជូន</translation> <translation id="610911394827799129">គណនី Google របស់អ្នកអាចមានទម្រង់ប្រវត្តិរុករកផ្សេងទៀតនៅក្នុង <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> ។</translation> +<translation id="6113594885686374546">ប៊ូតុងបន្តការស្វែងរក រួចចុច Enter ដើម្បីបន្តការស្វែងរករបស់អ្នក និងមើលសកម្មភាពដែលពាក់ព័ន្ធនៅក្នុងប្រវត្តិ Chrome របស់អ្នក</translation> <translation id="6116338172782435947">មើលអត្ថបទ និងរូបភាពដែលបានចម្លងទៅអង្គចងចាំ</translation> <translation id="6120179357481664955">ចងចាំលេខសម្គាល់ UPI របស់អ្នកដែរទេ?</translation> <translation id="6123290840358279103">មើលកាតនិម្មិត</translation> @@ -1490,6 +1492,7 @@ <translation id="6423385022588644828">បញ្ជាក់បណ្ណរបស់អ្នករហ័សជាងមុនដោយប្រើ Touch ID ចាប់ពីពេលនេះតទៅ</translation> <translation id="6425092077175753609">សម្ភារៈ</translation> <translation id="6427730057873428458">បត់ជាផ្ទាំងៗមានសណ្ឋានជាទ្វារ</translation> +<translation id="6428146287756735566">បន្តការស្វែងរកដើម្បីមើលសកម្មភាពដែលពាក់ព័ន្ធនៅក្នុងប្រវត្តិ Chrome របស់អ្នក</translation> <translation id="6428450836711225518">ផ្ទៀងផ្ទាត់លេខទូរសព្ទរបស់អ្នក</translation> <translation id="6433490469411711332">កែសម្រួលព័ត៌មានទំនាក់ទំនង</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> បានបដិសេធក្នុងការតភ្ជាប់</translation> @@ -1541,6 +1544,7 @@ <translation id="6643016212128521049">ជម្រះ</translation> <translation id="6645291930348198241">ចូលប្រើទិន្នន័យគេហទំព័រ និងខូគី។</translation> <translation id="6646269444027925224">{COUNT,plural, =0{គ្មាន}=1{ពីទំព័រ 1 (អ្នកនឹងមិនចាកចេញពីគណនី Google របស់អ្នកទេ)}other{ពីទំព័រ # (អ្នកនឹងមិនចាកចេញពីគណនី Google របស់អ្នកទេ)}}</translation> +<translation id="6647197322759179819">បន្តការស្វែងរក</translation> <translation id="6648459603387803038">អ្នកគ្រប់គ្រងរបស់អ្នកអាចប្ដូរការរៀបចំកម្មវិធីរុករកតាមអ៊ីនធឺណិតរបស់អ្នកពីចម្ងាយបាន។ សកម្មភាពនៅលើឧបករណ៍នេះក៏អាចត្រូវបានគ្រប់គ្រងនៅក្រៅ Chrome ផងដែរ។</translation> <translation id="6648524591329069940">ពុម្ពអក្សរ Serif</translation> <translation id="6651270836885078973">ស្ថិតក្រោមការគ្រប់គ្រងរបស់៖</translation> @@ -2193,6 +2197,7 @@ <translation id="9114524666733003316">កំពុងបញ្ជាក់បណ្ណឥណទាន...</translation> <translation id="9114581008513152754">កម្មវិធីរុករកតាមអ៊ីនធឺណិតនេះមិនស្ថិតក្រោមការគ្រប់គ្រងរបស់ក្រុមហ៊ុន ឬស្ថាប័នផ្សេងទេ។ សកម្មភាពនៅលើឧបករណ៍នេះអាចនឹងត្រូវបានគ្រប់គ្រងក្រៅពី Chrome។ <ph name="BEGIN_LINK" />ស្វែងយល់បន្ថែម<ph name="END_LINK" /></translation> <translation id="9117930699067497412">ស្រស់ស្រាយ</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, ចុច Tab រួចចុច Enter ដើម្បីបន្តការស្វែងរករបស់អ្នក និងមើលសកម្មភាពដែលពាក់ព័ន្ធនៅក្នុងប្រវត្តិ Chrome របស់អ្នក</translation> <translation id="9119042192571987207">បានបង្ហោះ</translation> <translation id="9128016270925453879">គោលការណ៍ត្រូវបានផ្ទុក</translation> <translation id="9128870381267983090">ភ្ជាប់ទៅបណ្តាញ</translation> diff --git a/components/strings/components_strings_kn.xtb b/components/strings/components_strings_kn.xtb index cb722d80c23f5d..c3f2fc4c58d5ff 100644 --- a/components/strings/components_strings_kn.xtb +++ b/components/strings/components_strings_kn.xtb @@ -727,6 +727,7 @@ <translation id="3631244953324577188">ಬಯೋಮೆಟ್ರಿಕ್ಸ್</translation> <translation id="3633738897356909127">Chrome ಬಟನ್ ಅಪ್ಡೇಟ್ ಮಾಡಿ, ನಿಮ್ಮ Chrome ಸೆಟ್ಟಿಂಗ್ಗಳಿಂದ Chrome ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲು Enter ಒತ್ತಿರಿ</translation> <translation id="3634530185120165534">ಟ್ರೇ 5</translation> +<translation id="3637662659967048211">Google ಖಾತೆಗೆ ಉಳಿಸಿ</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">ಅಪ್ಲಿಕೇಶನ್:</translation> <translation id="3650584904733503804">ಊರ್ಜಿತಗೊಳಿಸುವಿಕೆಯು ಯಶಸ್ವಿಯಾಗಿದೆ</translation> @@ -1399,6 +1400,7 @@ <translation id="6106989379647458772"><ph name="PAGE" /> ನಲ್ಲಿರುವ ವೆಬ್ಪುಟ ತಾತ್ಕಾಲಿಕವಾಗಿ ಕೆಲಸ ಮಾಡುತ್ತಿಲ್ಲ ಅಥವಾ ಅದನ್ನು ಶಾಶ್ವತವಾಗಿ ಹೊಸ ವೆಬ್ ವಿಳಾಸಕ್ಕೆ ಸರಿಸಲಾಗಿದೆ.</translation> <translation id="6107012941649240045">ಇವರಿಗೆ ನೀಡಲಾಗಿದೆ</translation> <translation id="610911394827799129">ನಿಮ್ಮ Google ಖಾತೆಯು <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> ನಲ್ಲಿ ಇತರ ವಿಧಗಳ ಬ್ರೌಸಿಂಗ್ ಇತಿಹಾಸವನ್ನು ಹೊಂದಿರಬಹುದು</translation> +<translation id="6113594885686374546">ನಿಮ್ಮ ಪ್ರಯಾಣವನ್ನು ಪುನರಾರಂಭಿಸಲು ಮತ್ತು ನಿಮ್ಮ Chrome ಇತಿಹಾಸದಲ್ಲಿ ಸಂಬಂಧಿತ ಚಟುವಟಿಕೆಯನ್ನು ನೋಡಲು, ಪ್ರಯಾಣದ ಬಟನ್ ಪುನರಾರಂಭಿಸಿ, Enter ಒತ್ತಿ</translation> <translation id="6116338172782435947">ಕ್ಲಿಪ್ಬೋರ್ಡ್ಗೆ ನಕಲಿಸಿರುವ ಪಠ್ಯ ಮತ್ತು ಚಿತ್ರಗಳನ್ನು ನೋಡಿ</translation> <translation id="6120179357481664955">ನಿಮ್ಮ UPI ಐಡಿ ನೆನಪಿದೆಯೇ?</translation> <translation id="6123290840358279103">ವರ್ಚುವಲ್ ಕಾರ್ಡ್ ವೀಕ್ಷಿಸಿ</translation> @@ -1473,6 +1475,7 @@ <translation id="6423385022588644828">ಇನ್ನು ಮುಂದೆ, ಟಚ್ ID ಬಳಸುವ ಮೂಲಕ ನಿಮ್ಮ ಕಾರ್ಡ್ಗಳನ್ನು ವೇಗವಾಗಿ ದೃಢೀಕರಿಸಿ</translation> <translation id="6425092077175753609">ವಸ್ತು</translation> <translation id="6427730057873428458">ಗೇಟ್ ಮಾದರಿಯಲ್ಲಿ ಮಡಿಸಿ</translation> +<translation id="6428146287756735566">ನಿಮ್ಮ Chrome ಇತಿಹಾಸದಲ್ಲಿ ಸಂಬಂಧಿತ ಚಟುವಟಿಕೆಯನ್ನು ನೋಡಲು ಪ್ರಯಾಣವನ್ನು ಪುನರಾರಂಭಿಸಿ</translation> <translation id="6428450836711225518">ನಿಮ್ಮ ದೂರವಾಣಿ ಸಂಖ್ಯೆಯನ್ನು ದೃಢೀಕರಿಸಿ</translation> <translation id="6433490469411711332">ಸಂಪರ್ಕ ಮಾಹಿತಿ ಎಡಿಟ್ ಮಾಡಿ</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> ಸಂಪರ್ಕಗೊಳ್ಳಲು ನಿರಾಕರಿಸಿದೆ.</translation> @@ -1524,6 +1527,7 @@ <translation id="6643016212128521049">ತೆರವುಗೊಳಿಸಿ</translation> <translation id="6645291930348198241">ಕುಕೀಗಳು ಮತ್ತು ಸೈಟ್ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{ಯಾವುದೂ ಇಲ್ಲ}=1{1 ಸೈಟ್ನಿಂದ (ನಿಮ್ಮ Google ಖಾತೆಯಿಂದ ನಿಮ್ಮನ್ನು ಸೈನ್ ಔಟ್ ಮಾಡುವುದಿಲ್ಲ)}one{# ಸೈಟ್ಗಳಿಂದ (ನಿಮ್ಮ Google ಖಾತೆಯಿಂದ ನಿಮ್ಮನ್ನು ಸೈನ್ ಔಟ್ ಮಾಡುವುದಿಲ್ಲ)}other{# ಸೈಟ್ಗಳಿಂದ (ನಿಮ್ಮ Google ಖಾತೆಯಿಂದ ನಿಮ್ಮನ್ನು ಸೈನ್ ಔಟ್ ಮಾಡುವುದಿಲ್ಲ)}}</translation> +<translation id="6647197322759179819">ಪ್ರಯಾಣವನ್ನು ಪುನರಾರಂಭಿಸಿ</translation> <translation id="6648459603387803038">ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಮ್ಮ ಬ್ರೌಸರ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ದೂರದಿಂದಲೇ ಬದಲಾಯಿಸಬಹುದು. ಈ ಸಾಧನದಲ್ಲಿನ ಚಟುವಟಿಕೆಯನ್ನು Chrome ನ ಹೊರಗೆ ಸಹ ನಿರ್ವಹಿಸಬಹುದು.</translation> <translation id="6648524591329069940">Serif ಫಾಂಟ್</translation> <translation id="6651270836885078973">ಈ ಮೂಲಕ ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ:</translation> @@ -2175,6 +2179,7 @@ <translation id="9114524666733003316">ಕಾರ್ಡ್ ದೃಢೀಕರಿಸಲಾಗುತ್ತಿದೆ...</translation> <translation id="9114581008513152754">ಈ ಬ್ರೌಸರ್ ಅನ್ನು ಕಂಪನಿ ಅಥವಾ ಇತರ ಸಂಸ್ಥೆಯು ನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ. ಈ ಸಾಧನದಲ್ಲಿನ ಚಟುವಟಿಕೆಯನ್ನು Chrome ನಿಂದ ಹೊರಗೆ ನಿರ್ವಹಿಸಬಹುದು. <ph name="BEGIN_LINK" />ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ<ph name="END_LINK" /></translation> <translation id="9117930699067497412">ಹೊಸದು</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, ನಿಮ್ಮ ಪ್ರಯಾಣವನ್ನು ಪುನರಾರಂಭಿಸಲು ಮತ್ತು ನಿಮ್ಮ Chrome ಇತಿಹಾಸದಲ್ಲಿ ಸಂಬಂಧಿತ ಚಟುವಟಿಕೆಯನ್ನು ನೋಡಲು, Tab ಒತ್ತಿ, ನಂತರ Enter ಒತ್ತಿ</translation> <translation id="9119042192571987207">ಅಪ್ಲೋಡ್ ಮಾಡಲಾಗಿದೆ</translation> <translation id="9128016270925453879">ನೀತಿಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗಿದೆ</translation> <translation id="9128870381267983090">ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಿಸು</translation> diff --git a/components/strings/components_strings_ko.xtb b/components/strings/components_strings_ko.xtb index e61a9860157c4d..c529c175b08abb 100644 --- a/components/strings/components_strings_ko.xtb +++ b/components/strings/components_strings_ko.xtb @@ -728,6 +728,7 @@ <translation id="3631244953324577188">생체 인식</translation> <translation id="3633738897356909127">Chrome 업데이트 버튼, Chrome 설정에서 Chrome을 업데이트하려면 Enter 누르기</translation> <translation id="3634530185120165534">트레이 5</translation> +<translation id="3637662659967048211">Google 계정에 저장</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">애플리케이션:</translation> <translation id="3650584904733503804">유효성 검사 성공</translation> @@ -1400,6 +1401,7 @@ <translation id="6106989379647458772"><ph name="PAGE" />의 웹페이지가 일시적으로 다운되었거나 새 웹 주소로 완전히 이동했을 수 있습니다.</translation> <translation id="6107012941649240045">발급 대상</translation> <translation id="610911394827799129">Google 계정의 내 활동(<ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />)에는 인터넷 방문 기록이 다른 형식으로 남아 있을 수도 있습니다</translation> +<translation id="6113594885686374546">검색 계속하기 버튼, 검색을 계속하고 Chrome 방문 기록에서 관련 활동을 보려면 Enter를 누르세요.</translation> <translation id="6116338172782435947">클립보드에 복사된 텍스트 및 이미지를 확인합니다.</translation> <translation id="6120179357481664955">UPI ID를 저장하시겠습니까?</translation> <translation id="6123290840358279103">가상 카드 보기</translation> @@ -1475,6 +1477,7 @@ <translation id="6423385022588644828">지금부터 Touch ID를 사용하여 빠르게 카드를 확인합니다.</translation> <translation id="6425092077175753609">머티리얼</translation> <translation id="6427730057873428458">게이트 폴드</translation> +<translation id="6428146287756735566">Chrome 방문 기록에서 관련 활동을 보려면 검색을 계속하세요.</translation> <translation id="6428450836711225518">전화번호 인증</translation> <translation id="6433490469411711332">연락처 정보 수정</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" />에서 연결을 거부했습니다.</translation> @@ -1526,6 +1529,7 @@ <translation id="6643016212128521049">삭제</translation> <translation id="6645291930348198241">쿠키 및 사이트 데이터에 액세스합니다.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{없음}=1{사이트 1개(Google 계정에서 로그아웃되지 않음)}other{사이트 #개(Google 계정에서 로그아웃되지 않음)}}</translation> +<translation id="6647197322759179819">검색 계속하기</translation> <translation id="6648459603387803038">관리자가 원격으로 브라우저 설정을 변경할 수 있습니다. 이 기기의 활동은 Chrome 외부에서도 관리할 수 있습니다.</translation> <translation id="6648524591329069940">Serif 체</translation> <translation id="6651270836885078973">관리자:</translation> @@ -2176,6 +2180,7 @@ <translation id="9114524666733003316">카드 확인 중...</translation> <translation id="9114581008513152754">이 브라우저는 회사 또는 다른 조직에서 관리하지 않습니다. 이 기기의 활동은 Chrome 외부에서도 관리할 수 있습니다. <ph name="BEGIN_LINK" />자세히 알아보기<ph name="END_LINK" /></translation> <translation id="9117930699067497412">생기</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, 검색을 계속하고 Chrome 방문 기록에서 관련 활동을 보려면 Tab과 Enter를 차례로 누르세요</translation> <translation id="9119042192571987207">업로드됨</translation> <translation id="9128016270925453879">정책 로드됨</translation> <translation id="9128870381267983090">네트워크에 연결</translation> diff --git a/components/strings/components_strings_ky.xtb b/components/strings/components_strings_ky.xtb index a559e8f5383562..48a6f5118734b7 100644 --- a/components/strings/components_strings_ky.xtb +++ b/components/strings/components_strings_ky.xtb @@ -733,6 +733,7 @@ <translation id="3631244953324577188">Биометрика</translation> <translation id="3633738897356909127">Chrome'ду жаңыртуу баскычы. Chrome жөндөөлөрүңүздөн Chrome'ду жаңыртуу үчүн, Enter баскычын басыңыз</translation> <translation id="3634530185120165534">5-түпкүч</translation> +<translation id="3637662659967048211">Google аккаунтка сактоо</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Колдонмо:</translation> <translation id="3650584904733503804">Жарактуулугу ийгиликтүү текшерилди</translation> @@ -1410,6 +1411,7 @@ <translation id="6106989379647458772"><ph name="PAGE" /> дарегиндеги веб-баракча убактылуу иштебейт же жаңы веб дарекке биротоло көчүрүлгөн окшойт.</translation> <translation id="6107012941649240045">Кимге берилген</translation> <translation id="610911394827799129">Google аккаунтуңуздун серептөө таржымалынын башка түрлөрү <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> дарегинде болушу мүмкүн.</translation> +<translation id="6113594885686374546">Саякатты улантуу баскычы, саякатыңызды улантып, Chrome´до көрүлгөн вебсайттарыңыздын арасынан ылайыктууларын көрүү үчүн, Enter баскычын басыңыз</translation> <translation id="6116338172782435947">Алмашуу буферине көчүрүлгөн текстти жана сүрөттөрдү көрүү</translation> <translation id="6120179357481664955">UPI идентификаторуңуз сакталсынбы?</translation> <translation id="6123290840358279103">Виртуалдык картаны көрүү</translation> @@ -1485,6 +1487,7 @@ <translation id="6423385022588644828">Мындан ары Touch ID функциясын колдонуп карталарды тезирээк ырастаңыз</translation> <translation id="6425092077175753609">Материал</translation> <translation id="6427730057873428458">Эки жолу чаптоо</translation> +<translation id="6428146287756735566">Chrome´до көрүлгөн вебсайттарыңыздын арасынан ылайыктууларын көрүү үчүн саякатты улантыңыз</translation> <translation id="6428450836711225518">Телефон номериңизди ырастаңыз</translation> <translation id="6433490469411711332">Байланыш маалыматын түзөтүү</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> сайты туташуудан баш тартты.</translation> @@ -1536,6 +1539,7 @@ <translation id="6643016212128521049">Тазалоо</translation> <translation id="6645291930348198241">Cookie файлдарына жана сайттын маалыматына кирүү мүмкүнчүлүгүн алуу.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Бирөө да жок}=1{1 сайттан (Google аккаунтуңуздан чыгарылбайсыз)}other{# сайттан (Google аккаунтуңуздан чыгарылбайсыз)}}</translation> +<translation id="6647197322759179819">Саякатты улантуу</translation> <translation id="6648459603387803038">Администраторуңуз серепчини алыстан жөндөй алат. Бул түзмөктө аткарылган аракеттер Chrome'дон тышкары да башкарылышы мүмкүн.</translation> <translation id="6648524591329069940">Serif ариби</translation> <translation id="6651270836885078973">Төмөнкү тарабынан башкарылат:</translation> @@ -2187,6 +2191,7 @@ <translation id="9114524666733003316">Карта текшерилүүдө…</translation> <translation id="9114581008513152754">Бул серепчи компанияңыз же башка уюм тарабынан башкарылбайт. Бул түзмөктө аткарылган аракеттер Chrome'дон тышкары башкарылышы мүмкүн. <ph name="BEGIN_LINK" />Кеңири маалымат<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Жаңы</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, саякатыңызды улантып, Chrome´до көрүлгөн вебсайттарыңыздын арасынан ылайыктууларын көрүү үчүн, Tab, андан соң Enter баскычын басыңыз</translation> <translation id="9119042192571987207">Жүктөлүп берилди</translation> <translation id="9128016270925453879">Саясаттар жүктөлдү</translation> <translation id="9128870381267983090">Тармакка туташуу</translation> diff --git a/components/strings/components_strings_lo.xtb b/components/strings/components_strings_lo.xtb index 244f947ed8b397..bdc667ba884c81 100644 --- a/components/strings/components_strings_lo.xtb +++ b/components/strings/components_strings_lo.xtb @@ -734,6 +734,7 @@ <translation id="3631244953324577188">ຂໍ້ມູນຊີວະມິຕິ</translation> <translation id="3633738897356909127">ປຸ່ມອັບເດດ Chrome, ກົດ Enter ເພື່ອອັບເດດ Chrome ຈາກການຕັ້ງຄ່າ Chrome ຂອງທ່ານ</translation> <translation id="3634530185120165534">ຖາດ 5</translation> +<translation id="3637662659967048211">ບັນທຶກໄປໃສ່ບັນຊີ Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">ແອັບພລິເຄຊັນ:</translation> <translation id="3650584904733503804">ການຮັບຮອງສໍາເລັດ</translation> @@ -1411,6 +1412,7 @@ <translation id="6106989379647458772">ໜ້າເວັບຢູ່ທີ່ <ph name="PAGE" /> ອາດຈະໃຊ້ງານບໍ່ໄດ້ຊົ່ວຄາວ ຫຼື ມັນອາດຈະຍ້າຍໄປຫາທີ່ຢູ່ເວັບໃໝ່ຖາວອນແລ້ວ.</translation> <translation id="6107012941649240045">ອອກໃຫ້ກັບ</translation> <translation id="610911394827799129">ບັນຊີ Google ຂອງທ່ານອາດຈະມີປະຫວັດການທ່ອງເວັບຮູບແບບອື່ນຢູ່ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">ປຸ່ມສືບຕໍ່ສຳຫຼວດ, ກົດ Enter ເພື່ອສືບຕໍ່ການສຳຫຼວດຂອງທ່ານ ແລະ ເບິ່ງການເຄື່ອນໄຫວທີ່ກ່ຽວຂ້ອງໃນປະຫວັດ Chrome ຂອງທ່ານ</translation> <translation id="6116338172782435947">ເຫັນຂໍ້ຄວາມ ແລະ ຮູບພາບທີ່ສຳເນົາໄວ້ໃນຄລິບບອດ</translation> <translation id="6120179357481664955">ຈື່ UPI ID ຂອງທ່ານໄວ້ບໍ?</translation> <translation id="6123290840358279103">ເບິ່ງບັດສະເໝືອນ</translation> @@ -1486,6 +1488,7 @@ <translation id="6423385022588644828">ຢືນຢັນບັດຂອງທ່ານໄດ້ໄວຂຶ້ນໂດຍໃຊ້ Touch ID ຈາກນີ້ໄປ</translation> <translation id="6425092077175753609">ເນື້ອໃນ</translation> <translation id="6427730057873428458">ພັບທົບ</translation> +<translation id="6428146287756735566">ສືບຕໍ່ສຳຫຼວດເພື່ອເບິ່ງການເຄື່ອນໄຫວທີ່ກ່ຽວຂ້ອງໃນປະຫວັດ Chrome ຂອງທ່ານ</translation> <translation id="6428450836711225518">ຢັ້ງຢືນເບີໂທລະສັບຂອງທ່ານ</translation> <translation id="6433490469411711332">ແກ້ໄຂຂໍ້ມູນລາຍຊື່ຜູ້ຕິດຕໍ່</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> ໄດ້ປະຕິເສດການເຊື່ອມຕໍ່.</translation> @@ -1537,6 +1540,7 @@ <translation id="6643016212128521049">ລຶບ</translation> <translation id="6645291930348198241">ເຂົ້າເຖິງຄຸກກີ້ ແລະ ຂໍ້ມູນເວັບໄຊ.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{ບໍ່ມີ}=1{ຈາກ 1 ເວັບໄຊ (ທ່ານຈະບໍ່ຖືກນຳອອກຈາກລະບົບບັນຊີ Google ຂອງທ່ານ)}other{ຈາກ # ເວັບໄຊ (ທ່ານຈະບໍ່ຖືກນຳອອກຈາກລະບົບບັນຊີ Google ຂອງທ່ານ)}}</translation> +<translation id="6647197322759179819">ສືບຕໍ່ສຳຫຼວດ</translation> <translation id="6648459603387803038">ຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານສາມາດປ່ຽນການຕັ້ງຄ່າໂປຣແກຣມທ່ອງເວັບຂອງທ່ານຈາກທາງໄກໄດ້. ການເຄື່ອນໄຫວໃນອຸປະກອນນີ້ອາດຈະຖືກຈັດການຢູ່ນອກ Chrome ໄດ້ເຊັ່ນກັນ.</translation> <translation id="6648524591329069940">ຟອນ Serif</translation> <translation id="6651270836885078973">ຈັດການໂດຍ:</translation> @@ -2188,6 +2192,7 @@ <translation id="9114524666733003316">ກຳລັງຢືນຢັນບັດ...</translation> <translation id="9114581008513152754">ໂປຣແກຣມທ່ອງເວັບນີ້ບໍ່ໄດ້ຖືກຈັດການໂດຍບໍລິສັດ ຫຼື ອົງການຈັດຕັ້ງອື່ນ. ການເຄື່ອນໄຫວໃນອຸປະກອນນີ້ອາດຈະຖືກຈັດການຢູ່ນອກ Chrome ໄດ້. <ph name="BEGIN_LINK" />ສຶກສາເພີ່ມເຕີມ<ph name="END_LINK" /></translation> <translation id="9117930699067497412">ສົດໃໝ່</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, ກົດ Tab, ຈາກນັ້ນກົດ Enter ເພື່ອສືບຕໍ່ການສຳຫຼວດຂອງທ່ານ ແລະ ເບິ່ງການເຄື່ອນໄຫວທີ່ກ່ຽວຂ້ອງໃນປະຫວັດ Chrome ຂອງທ່ານ</translation> <translation id="9119042192571987207">ອັບໂຫລດແລ້ວ</translation> <translation id="9128016270925453879">ໂຫຼດນະໂຍບາຍແລ້ວ</translation> <translation id="9128870381267983090">ເຊື່ອມຕໍ່ກັບເຄືອຂ່າຍ</translation> diff --git a/components/strings/components_strings_lt.xtb b/components/strings/components_strings_lt.xtb index 74bd2e243b8ca3..797e37e1ef0e3c 100644 --- a/components/strings/components_strings_lt.xtb +++ b/components/strings/components_strings_lt.xtb @@ -735,6 +735,7 @@ Kitu atveju tai bus užblokuota pagal jūsų privatumo nustatymus. Taip turinys, <translation id="3631244953324577188">Biometrinės sistemos</translation> <translation id="3633738897356909127">Mygtukas „Atnaujinti „Chrome“, paspauskite „Enter“, kad „Chrome“ nustatymuose būtų atnaujinta naršyklė „Chrome“</translation> <translation id="3634530185120165534">5 dėklas</translation> +<translation id="3637662659967048211">Išsaugojimas „Google“ paskyroje</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Programa:</translation> <translation id="3650584904733503804">Tikrinimas sėkmingas</translation> @@ -1412,6 +1413,7 @@ Kitu atveju tai bus užblokuota pagal jūsų privatumo nustatymus. Taip turinys, <translation id="6106989379647458772">Gali būti, kad tinklalapis adresu <ph name="PAGE" /> laikinai neveikia arba yra visam laikui perkeltas nauju žiniatinklio adresu.</translation> <translation id="6107012941649240045">Išduotas</translation> <translation id="610911394827799129">„Google“ paskyroje gali būti kito tipo naršymo istorijos, kuri pasiekiama adresu <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Mygtukas „Tęsti veiksmus“, paspauskite „Enter“, kad tęstumėte veiksmus ir galėtumėte matyti atitinkamą veiklą „Chrome“ istorijoje</translation> <translation id="6116338172782435947">Peržiūrėti tekstą ir vaizdus, nukopijuotus į iškarpinę</translation> <translation id="6120179357481664955">Prisiminti UPI ID?</translation> <translation id="6123290840358279103">Žr. virtualią kortelę</translation> @@ -1487,6 +1489,7 @@ Kitu atveju tai bus užblokuota pagal jūsų privatumo nustatymus. Taip turinys, <translation id="6423385022588644828">Nuo šiol patvirtinkite korteles greičiau su „Touch ID“</translation> <translation id="6425092077175753609">Trimačiai objektai</translation> <translation id="6427730057873428458">Du atvartai</translation> +<translation id="6428146287756735566">Tęskite veiksmus, kad galėtumėte matyti atitinkamą veiklą „Chrome“ istorijoje</translation> <translation id="6428450836711225518">Patvirtinkite savo telefono numerį</translation> <translation id="6433490469411711332">Kontaktinės informacijos redagavimas</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> atsisakė prisijungti.</translation> @@ -1538,6 +1541,7 @@ Kitu atveju tai bus užblokuota pagal jūsų privatumo nustatymus. Taip turinys, <translation id="6643016212128521049">Išvalyti</translation> <translation id="6645291930348198241">Pasiekti slapukus ir svetainės duomenis.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Nėra}=1{Iš 1 svetainės (nebūsite atjungti nuo „Google“ paskyros)}one{Iš # svetainės (nebūsite atjungti nuo „Google“ paskyros)}few{Iš # svetainių (nebūsite atjungti nuo „Google“ paskyros)}many{Iš # svetainės (nebūsite atjungti nuo „Google“ paskyros)}other{Iš # svetainių (nebūsite atjungti nuo „Google“ paskyros)}}</translation> +<translation id="6647197322759179819">Tęsti veiksmus</translation> <translation id="6648459603387803038">Administratorius gali nuotoliniu būdu keisti naršyklės sąranką. Veiklą šiame įrenginyje taip pat galima tvarkyti ne naršyklėje „Chrome“.</translation> <translation id="6648524591329069940">Šriftas „Serif“</translation> <translation id="6651270836885078973">Valdo:</translation> @@ -2190,6 +2194,7 @@ Papildoma išsami informacija: <translation id="9114524666733003316">Kortelė patvirtinama...</translation> <translation id="9114581008513152754">Šios naršyklės netvarko įmonė ar kita organizacija. Veiklą šiame įrenginyje galima tvarkyti ne naršyklėje „Chrome“. <ph name="BEGIN_LINK" />Sužinokite daugiau<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Šviežia</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, paspauskite tabuliavimo klavišą, tada – „Enter“, kad tęstumėte veiksmus ir galėtumėte matyti atitinkamą veiklą „Chrome“ istorijoje</translation> <translation id="9119042192571987207">Įkelta</translation> <translation id="9128016270925453879">Politika įkelta</translation> <translation id="9128870381267983090">Prisijungti prie tinklo</translation> diff --git a/components/strings/components_strings_lv.xtb b/components/strings/components_strings_lv.xtb index 9813bd7ffb593f..bf1c4741f310a9 100644 --- a/components/strings/components_strings_lv.xtb +++ b/components/strings/components_strings_lv.xtb @@ -731,6 +731,7 @@ Pretējā gadījumā šī iespēja būtu liegta saskaņā ar jūsu konfidenciali <translation id="3631244953324577188">Biometrija</translation> <translation id="3633738897356909127">Poga “Atjaunināt Chrome”. Lai Chrome iestatījumos atjauninātu pārlūkprogrammu Chrome, nospiediet ievadīšanas taustiņu.</translation> <translation id="3634530185120165534">5. paplāte</translation> +<translation id="3637662659967048211">Saglabāšana Google kontā</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Lietojumprogramma:</translation> <translation id="3650584904733503804">Validācija bija veiksmīga.</translation> @@ -1408,6 +1409,7 @@ Pretējā gadījumā šī iespēja būtu liegta saskaņā ar jūsu konfidenciali <translation id="6106989379647458772">Tīmekļa lapa <ph name="PAGE" /> var būt īslaicīgi nepieejama, vai tā var būt pārvietota uz jaunu tīmekļa adresi.</translation> <translation id="6107012941649240045">Izsniegts</translation> <translation id="610911394827799129">Jūsu Google kontam var būt citu veidu pārlūkošanas vēstures dati vietnē <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Poga “Atsākt meklēšanu”: nospiediet ievadīšanas taustiņu, lai atsāktu meklēšanu un skatītu atbilstošās darbības savā Chrome vēsturē.</translation> <translation id="6116338172782435947">Skatīt starpliktuvē kopēto tekstu un attēlus</translation> <translation id="6120179357481664955">Vai iegaumēt jūsu UPI ID?</translation> <translation id="6123290840358279103">Skatīt virtuālo karti</translation> @@ -1483,6 +1485,7 @@ Pretējā gadījumā šī iespēja būtu liegta saskaņā ar jūsu konfidenciali <translation id="6423385022588644828">Turpmāk, izmantojot Touch ID, apstipriniet kartes ātrāk</translation> <translation id="6425092077175753609">Materiāls</translation> <translation id="6427730057873428458">Abpusējs locījums</translation> +<translation id="6428146287756735566">Atsāciet meklēšanu, lai skatītu atbilstošās darbības savā Chrome vēsturē.</translation> <translation id="6428450836711225518">Verificējiet savu tālruņa numuru</translation> <translation id="6433490469411711332">Kontaktinformācijas rediģēšana</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> noraidīja savienojuma izveidi.</translation> @@ -1534,6 +1537,7 @@ Pretējā gadījumā šī iespēja būtu liegta saskaņā ar jūsu konfidenciali <translation id="6643016212128521049">Notīrīt</translation> <translation id="6645291930348198241">Piekļūt sīkfailiem un vietnes datiem</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Nav}=1{No 1 vietnes (jūs netiksiet izrakstīts no sava Google konta)}zero{No # vietnēm (jūs netiksiet izrakstīts no sava Google konta)}one{No # vietnes (jūs netiksiet izrakstīts no sava Google konta)}other{No # vietnēm (jūs netiksiet izrakstīts no sava Google konta)}}</translation> +<translation id="6647197322759179819">Atsākt meklēšanu</translation> <translation id="6648459603387803038">Jūsu administrators var attālināti mainīt jūsu pārlūka iestatījumus. Darbību šajā ierīcē var pārvaldīt arī ārpus Chrome.</translation> <translation id="6648524591329069940">Serif fonts</translation> <translation id="6651270836885078973">Pārvalda:</translation> @@ -2186,6 +2190,7 @@ Papildu informācija: <translation id="9114524666733003316">Notiek kartes apstiprināšana...</translation> <translation id="9114581008513152754">Šo pārlūku nepārvalda uzņēmums vai cita organizācija. Darbību šajā ierīcē var pārvaldīt ārpus pārlūka Chrome. <ph name="BEGIN_LINK" />Uzzināt vairāk<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Dzīvīga</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />: nospiediet tabulēšanas taustiņu un pēc tam — ievadīšanas taustiņu, lai atsāktu meklēšanu un skatītu atbilstošās darbības savā Chrome vēsturē.</translation> <translation id="9119042192571987207">Augšupielādēts</translation> <translation id="9128016270925453879">Politikas ir ielādētas</translation> <translation id="9128870381267983090">Izveidot savienojumu ar tīklu</translation> diff --git a/components/strings/components_strings_mk.xtb b/components/strings/components_strings_mk.xtb index 3db769f3159db2..98739764ca7188 100644 --- a/components/strings/components_strings_mk.xtb +++ b/components/strings/components_strings_mk.xtb @@ -734,6 +734,7 @@ <translation id="3631244953324577188">Биометрика</translation> <translation id="3633738897356909127">Копче „Ажурирај го Chrome“, притиснете Enter за да го ажурирате Chrome од поставките за Chrome</translation> <translation id="3634530185120165534">Фиока 5</translation> +<translation id="3637662659967048211">Зачувајте во сметката на Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Апликација:</translation> <translation id="3650584904733503804">Потврдувањето е успешно</translation> @@ -1411,6 +1412,7 @@ <translation id="6106989379647458772">Веб-страницата на <ph name="PAGE" /> можеби привремено не работи или можеби трајно е преместена на нова веб-адреса.</translation> <translation id="6107012941649240045">Издадено на</translation> <translation id="610911394827799129">Вашата сметка на Google можеби има други видови историја на прелистување на <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Копче за продолжување со патувањето, притиснете Enter за да продолжите со патувањето и да ја прегледате релевантната активност во вашата „Историја на Chrome“</translation> <translation id="6116338172782435947">гледа текст и слики копирани на привремената меморија</translation> <translation id="6120179357481664955">Да се запомни ID за UPI?</translation> <translation id="6123290840358279103">Прикажи ја виртуелната картичка</translation> @@ -1486,6 +1488,7 @@ <translation id="6423385022588644828">Отсега, потврдувајте ги картичките побрзо со Touch ID</translation> <translation id="6425092077175753609">Материјален</translation> <translation id="6427730057873428458">Превиткување како брошура</translation> +<translation id="6428146287756735566">Продолжете со патување за да ја прегледате релевантната активност во вашата „Историја на Chrome“</translation> <translation id="6428450836711225518">Потврдете го телефонскиот број</translation> <translation id="6433490469411711332">Уредете ги информациите за контакт</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> одби да се поврзе.</translation> @@ -1537,6 +1540,7 @@ <translation id="6643016212128521049">Исчисти</translation> <translation id="6645291930348198241">да пристапува до колачиња и податоци за сајтот.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Ниту еден}=1{Од 1 сајт (нема да ве одјавиме од сметката на Google)}one{Од # сајт (нема да ве одјавиме од сметката на Google)}other{Од # сајтови (нема да ве одјавиме од сметката на Google)}}</translation> +<translation id="6647197322759179819">Продолжете со патување</translation> <translation id="6648459603387803038">Администраторот може далечински да го менува поставувањето на прелистувачот. Со активноста на уредов може да се управува и надвор од Chrome.</translation> <translation id="6648524591329069940">Фонт Serif</translation> <translation id="6651270836885078973">Управувано од:</translation> @@ -2188,6 +2192,7 @@ <translation id="9114524666733003316">Се потврдува картичката…</translation> <translation id="9114581008513152754">Прелистувачов не е управуван од компанија или друга организација. Активноста на уредов можеби се управува надвор од Chrome. <ph name="BEGIN_LINK" />Дознајте повеќе<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Свеж</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, притиснете Tab, а потоа Enter за да продолжите со патувањето и да ја прегледате релевантната активност во вашата „Историја на Chrome“</translation> <translation id="9119042192571987207">Прикачен</translation> <translation id="9128016270925453879">Правилата се вчитани</translation> <translation id="9128870381267983090">Поврзете се на мрежа</translation> diff --git a/components/strings/components_strings_mr.xtb b/components/strings/components_strings_mr.xtb index 6c86d6ad88b54d..0da98d689a4682 100644 --- a/components/strings/components_strings_mr.xtb +++ b/components/strings/components_strings_mr.xtb @@ -733,6 +733,7 @@ <translation id="3631244953324577188">बायोमेट्रिक</translation> <translation id="3633738897356909127">Chrome अपडेट करा बटण, तुमच्या Chrome सेटिंग्जमधून Chrome अपडेट करण्यासाठी एंटर दाबा</translation> <translation id="3634530185120165534">ट्रे ५</translation> +<translation id="3637662659967048211">Google खाते मध्ये सेव्ह करा</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">ॲप्लिकेशन:</translation> <translation id="3650584904733503804">प्रमाणीकरण यशस्वी</translation> @@ -1410,6 +1411,7 @@ <translation id="6106989379647458772"><ph name="PAGE" /> वरील वेबपेज कदाचित तात्पुरते बंद आहे किंवा ते कदाचित कायमचे नवीन वेब पत्त्यावर हलवले आहे.</translation> <translation id="6107012941649240045">यांना जारी केलेले</translation> <translation id="610911394827799129">तुमच्या Google खात्यामध्ये <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> वर ब्राउझिंग इतिहासाची अन्य स्वरूपे असू शकतात.</translation> +<translation id="6113594885686374546">शोध पुन्हा सुरू करा बटण, तुमच्या Chrome इतिहासामध्ये संबंधित अॅक्टिव्हिटी पाहण्यासाठी आणि शोध पुन्हा सुरू करण्यासाठी एंटर दाबा</translation> <translation id="6116338172782435947">क्लिपबोर्डवर कॉपी केलेला मजकूर आणि इमेज पहा</translation> <translation id="6120179357481664955">तुमचा UPI आयडी लक्षात ठेवायचा आहे का?</translation> <translation id="6123290840358279103">व्हर्च्युअल कार्ड पहा</translation> @@ -1486,6 +1488,7 @@ <translation id="6423385022588644828">यापुढे टच आयडी वापरून तुमच्या कार्डांची जलद खात्री करा</translation> <translation id="6425092077175753609">आशय</translation> <translation id="6427730057873428458">गेट फोल्ड</translation> +<translation id="6428146287756735566">तुमच्या Chrome इतिहासामध्ये संबंधित अॅक्टिव्हिटी पाहण्यासाठी शोध पुन्हा सुरू करा</translation> <translation id="6428450836711225518">तुमच्या फोन नंबरची पडताळणी करा</translation> <translation id="6433490469411711332">संपर्क माहिती संपादित करा</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> नी कनेक्ट करण्यास नकार दिला.</translation> @@ -1537,6 +1540,7 @@ <translation id="6643016212128521049">साफ करा</translation> <translation id="6645291930348198241">कुकी आणि साइट डेटा अॅक्सेस करा.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{काहीही नाही}=1{एका साइटवरून (तुम्हाला तुमच्या Google खात्यातून साइन आउट केले जाणार नाही)}other{# साइटवरून (तुम्हाला तुमच्या Google खात्यातून साइन आउट केले जाणार नाही)}}</translation> +<translation id="6647197322759179819">शोध पुन्हा सुरू करा</translation> <translation id="6648459603387803038">तुमचा अॅडमिनिस्ट्रेटर तुमच्या ब्राउझरचा सेटअप रिमोट पद्धतीने बदलू शकतो. या डिव्हाइसवरील अॅक्टिव्हिटी कदाचित Chrome च्या बाहेर व्यवस्थापित केलेली असू शकते.</translation> <translation id="6648524591329069940">Serif Font</translation> <translation id="6651270836885078973">यांनी व्यवस्थापित केलेले:</translation> @@ -2188,6 +2192,7 @@ <translation id="9114524666733003316">कार्डची निश्चिती करत आहे...</translation> <translation id="9114581008513152754">हा ब्राउझर कंपनी किंवा इतर संस्थेद्वारे व्यवस्थापित केला जात नाही. या डिव्हाइसवरील अॅक्टिव्हिटी Chrome च्या बाहेर व्यवस्थापित केलेली असू शकते. <ph name="BEGIN_LINK" />अधिक जाणून घ्या<ph name="END_LINK" /></translation> <translation id="9117930699067497412">नवीन</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, तुमच्या Chrome इतिहासामध्ये संबंधित अॅक्टिव्हिटी पाहण्यासाठी आणि शोध पुन्हा सुरू करण्यासाठी टॅब आणि त्यानंतर एंटर दाबा</translation> <translation id="9119042192571987207">अपलोड केला</translation> <translation id="9128016270925453879">धोरणे लोड केलेली आहेत</translation> <translation id="9128870381267983090">नेटवर्कशी कनेक्ट करा</translation> diff --git a/components/strings/components_strings_ms.xtb b/components/strings/components_strings_ms.xtb index 9439a9ba84a9e6..cd60195f130bca 100644 --- a/components/strings/components_strings_ms.xtb +++ b/components/strings/components_strings_ms.xtb @@ -735,6 +735,7 @@ Jika tidak, ini akan disekat oleh tetapan privasi anda. Kebenaran ini akan membo <translation id="3631244953324577188">Biometrik</translation> <translation id="3633738897356909127">Butang Kemas Kini Chrome, tekan Enter untuk mengemas kini Chrome daripada tetapan Chrome anda</translation> <translation id="3634530185120165534">Dulang 5</translation> +<translation id="3637662659967048211">Simpan pada Akaun Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplikasi:</translation> <translation id="3650584904733503804">Pengesahan berjaya</translation> @@ -1412,6 +1413,7 @@ Jika tidak, ini akan disekat oleh tetapan privasi anda. Kebenaran ini akan membo <translation id="6106989379647458772">Halaman web di <ph name="PAGE" /> mungkin tergendala sebentar atau mungkin telah dipindahkan secara kekal ke alamat web baharu.</translation> <translation id="6107012941649240045">Dikeluarkan Kepada</translation> <translation id="610911394827799129">Akaun Google anda mungkin mempunyai bentuk sejarah penyemakan imbas yang lain di <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Butang sambung semula perjalanan, tekan Enter untuk menyambung semula perjalanan dan melihat aktiviti yang berkaitan dalam sejarah Chrome anda</translation> <translation id="6116338172782435947">Lihat teks dan imej yang disalin ke papan keratan</translation> <translation id="6120179357481664955">Ingat ID UPI anda?</translation> <translation id="6123290840358279103">Lihat kad maya</translation> @@ -1487,6 +1489,7 @@ Jika tidak, ini akan disekat oleh tetapan privasi anda. Kebenaran ini akan membo <translation id="6423385022588644828">Sahkan kad anda dengan lebih cepat dengan menggunakan Touch ID mulai sekarang</translation> <translation id="6425092077175753609">Bahan</translation> <translation id="6427730057873428458">Lipatan pintu</translation> +<translation id="6428146287756735566">Sambung semula perjalanan untuk melihat aktiviti yang berkaitan dalam sejarah Chrome anda</translation> <translation id="6428450836711225518">Sahkan nombor telefon anda</translation> <translation id="6433490469411711332">Edit maklumat hubungan</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> enggan menyambung.</translation> @@ -1538,6 +1541,7 @@ Jika tidak, ini akan disekat oleh tetapan privasi anda. Kebenaran ini akan membo <translation id="6643016212128521049">Kosongkan</translation> <translation id="6645291930348198241">Akses kuki dan data tapak.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Tiada}=1{Daripada 1 tapak (anda tidak akan dilog keluar daripada Akaun Google anda)}other{Daripada # tapak (anda tidak akan dilog keluar daripada Akaun Google anda)}}</translation> +<translation id="6647197322759179819">Sambung semula perjalanan</translation> <translation id="6648459603387803038">Pentadbir anda boleh menukar persediaan penyemak imbas anda dari jauh. Aktiviti pada peranti ini mungkin turut diurus di luar Chrome.</translation> <translation id="6648524591329069940">Fon Serif</translation> <translation id="6651270836885078973">Diurus oleh:</translation> @@ -2190,6 +2194,7 @@ Butiran tambahan: <translation id="9114524666733003316">Mengesahkan kad...</translation> <translation id="9114581008513152754">Penyemak imbas ini tidak diurus oleh syarikat atau organisasi lain. Aktiviti pada peranti ini mungkin diurus di luar Chrome. <ph name="BEGIN_LINK" />Ketahui lebih lanjut<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Baharu</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, tekan Tab kemudian Enter untuk menyambung semula perjalanan dan melihat aktiviti yang berkaitan dalam sejarah Chrome anda</translation> <translation id="9119042192571987207">Dimuat naik</translation> <translation id="9128016270925453879">Dasar dimuatkan</translation> <translation id="9128870381267983090">Sambung ke rangkaian</translation> diff --git a/components/strings/components_strings_my.xtb b/components/strings/components_strings_my.xtb index f6af9a62e7b571..71092e418a225e 100644 --- a/components/strings/components_strings_my.xtb +++ b/components/strings/components_strings_my.xtb @@ -733,6 +733,7 @@ <translation id="3631244953324577188">ဇီဝမက်ထရစ် အချက်အလက်များ</translation> <translation id="3633738897356909127">Chrome အပ်ဒိတ်လုပ်ရန်ခလုတ်၊ သင့် Chrome ဆက်တင်များမှတစ်ဆင့် Chrome ကို အပ်ဒိတ်လုပ်ရန် Enter နှိပ်ပါ</translation> <translation id="3634530185120165534">ဗန်း ၅</translation> +<translation id="3637662659967048211">Google Account တွင် သိမ်းပါ</translation> <translation id="3640766068866876100">အညွှန်း-၄x၆-နောက်ဆက်တွဲ</translation> <translation id="3642638418806704195">အပလီကေးရှင်း-</translation> <translation id="3650584904733503804">အောင်မြင်စွာ အတည်ပြုပြီး</translation> @@ -1411,6 +1412,7 @@ <translation id="6106989379647458772"><ph name="PAGE" /> ပေါ်က ဝဘ်စာမျက်နှာမှာ ယာယီ ဒေါင်းနေတာ ဖြစ်နိုင်သည် သို့မဟုတ် ၎င်းသည် ဝဘ် လိပ်စာ သစ်ဆီသို့ ထာဝရ ရွှေ့ပြောင်းသွားတာ ဖြစ်နိုင်သည်။</translation> <translation id="6107012941649240045">...အား ထုတ်ပေးခဲ့သည်</translation> <translation id="610911394827799129">သင်၏ Google အကောင့်က ဖွင့်ကြည့်ထားသော မှတ်တမ်းသည် <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> တွင် အခြားပုံစံများဖြင့် ရှိနေနိုင်ပါသည်</translation> +<translation id="6113594885686374546">ခရီးစဉ်ကို ဆက်လုပ်ရန် ခလုတ်။ သင်၏ခရီးစဉ်ကို ဆက်လုပ်ရန်နှင့် သင်၏ Chrome မှတ်တမ်းရှိ သက်ဆိုင်ရာလုပ်ဆောင်ချက်ကို ကြည့်ရန် Enter နှိပ်ပါ</translation> <translation id="6116338172782435947">ကလစ်ဘုတ်သို့ မိတ္တူကူးထားသည့် စာသားနှင့် ပုံများအား ကြည့်ရန်</translation> <translation id="6120179357481664955">သင့် UPI ID ကို မှတ်မိပါသလား။</translation> <translation id="6123290840358279103">ပကတိအသွင်ကတ် ကြည့်ရန်</translation> @@ -1485,6 +1487,7 @@ <translation id="6423385022588644828">ယခုမှစ၍ Touch ID ကို အသုံးပြု၍ သင့်ကတ်များကို ပိုမိုမြန်ဆန်စွာ အတည်ပြုလိုက်ပါ</translation> <translation id="6425092077175753609">ရုပ်ဝတ္ထုပစ္စည်း</translation> <translation id="6427730057873428458">ဝင်းတံခါးပုံ ခေါက်ရန်</translation> +<translation id="6428146287756735566">သင်၏ Chrome မှတ်တမ်းရှိ သက်ဆိုင်ရာလုပ်ဆောင်ချက်ကို ကြည့်ရန် ခရီးစဉ်ကို ဆက်လုပ်ပါ</translation> <translation id="6428450836711225518">သင်၏ဖုန်းနံပါတ်ကို အတည်ပြုပါ</translation> <translation id="6433490469411711332">အဆက်အသွယ်အချက်အလက်ကို တည်းဖြတ်ပါ</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> သည်ချိတ်ဆက်ရန် ငြင်းပယ်ခဲ့သည်။</translation> @@ -1536,6 +1539,7 @@ <translation id="6643016212128521049">ရှင်းရန်</translation> <translation id="6645291930348198241">ကွတ်ကီးနှင့် ဝဘ်ဆိုက်ဒေတာများ သုံးခြင်း။</translation> <translation id="6646269444027925224">{COUNT,plural, =0{တစ်ခုမျှမရှိပါ}=1{ဝဘ်ဆိုက် ၁ ခုမှ (သင်၏ Google အကောင့်မှနေ၍ ထွက်သွားမည်မဟုတ်ပါ)}other{ဝဘ်ဆိုက် # ခုမှ (သင်၏ Google အကောင့်မှနေ၍ ထွက်သွားမည်မဟုတ်ပါ)}}</translation> +<translation id="6647197322759179819">ခရီးစဉ်ကို ဆက်လုပ်ရန်</translation> <translation id="6648459603387803038">သင့်စီမံခန့်ခွဲသူက သင်၏ဘရောင်ဇာ စနစ်ထည့်သွင်းမှုကို အဝေးမှ ပြောင်းလဲနိုင်ပါသည်။ ဤစက်ပေါ်ရှိ လုပ်ဆောင်ချက်များကိုလည်း Chrome ပြင်ပမှ စီမံခန့်ခွဲထားခြင်း ဖြစ်နိုင်သည်။</translation> <translation id="6648524591329069940">Serif ဖောင့်</translation> <translation id="6651270836885078973">စီမံခန့်ခွဲသူ-</translation> @@ -2188,6 +2192,7 @@ <translation id="9114524666733003316">ကတ် အတည်ပြုနေသည်...</translation> <translation id="9114581008513152754">ဤဘရောင်ဇာကို ကုမ္ပဏီ သို့မဟုတ် အခြားအဖွဲ့အစည်းက စီမံခန့်ခွဲမထားပါ။ ဤစက်ပေါ်ရှိ လုပ်ဆောင်ချက်ကို Chrome ပြင်ပမှ စီမံခန့်ခွဲထားခြင်း ဖြစ်နိုင်သည်။ <ph name="BEGIN_LINK" />ပိုမိုလေ့လာရန်<ph name="END_LINK" /></translation> <translation id="9117930699067497412">လန်းလန်းဆန်းဆန်း</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />။ တဘ်နှိပ်ပါ။ ထို့နောက် သင်၏ခရီးစဉ်ကို ဆက်လုပ်ရန်နှင့် သင်၏ Chrome မှတ်တမ်းရှိ သက်ဆိုင်ရာလုပ်ဆောင်ချက်ကို ကြည့်ရန် Enter နှိပ်ပါ</translation> <translation id="9119042192571987207">အပ်လုဒ်လုပ်ပြီးပြီ</translation> <translation id="9128016270925453879">မူဝါဒများကို ဖွင့်လိုက်သည်</translation> <translation id="9128870381267983090">ကွန်ယက်သို့ ချိတ်ဆက်ပါ</translation> diff --git a/components/strings/components_strings_nl.xtb b/components/strings/components_strings_nl.xtb index ad1393d974c0a5..2398ac2ebd2c3a 100644 --- a/components/strings/components_strings_nl.xtb +++ b/components/strings/components_strings_nl.xtb @@ -722,6 +722,7 @@ Anders wordt dit geblokkeerd door je privacyinstellingen. Hierdoor werkt de cont <translation id="3631244953324577188">Biometrische systemen</translation> <translation id="3633738897356909127">Knop 'Chrome updaten'. Druk op Enter om Chrome te updaten via de instellingen van Chrome.</translation> <translation id="3634530185120165534">Lade 5</translation> +<translation id="3637662659967048211">Opslaan in Google-account</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">App:</translation> <translation id="3650584904733503804">Validatie geslaagd</translation> @@ -1397,6 +1398,7 @@ Anders wordt dit geblokkeerd door je privacyinstellingen. Hierdoor werkt de cont <translation id="6106989379647458772">De webpagina op <ph name="PAGE" /> is mogelijk tijdelijk niet beschikbaar of is permanent verplaatst naar een nieuw webadres.</translation> <translation id="6107012941649240045">Verleend aan</translation> <translation id="610911394827799129">Er kunnen andere vormen van browsegeschiedenis zijn opgeslagen voor je Google-account op <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Knop Reis hervatten. Druk op Enter om je reis te hervatten en relevante activiteit in je Chrome-geschiedenis te bekijken.</translation> <translation id="6116338172782435947">Tekst en afbeeldingen bekijken die naar het klembord zijn gekopieerd</translation> <translation id="6120179357481664955">Weet je je UPI-ID nog?</translation> <translation id="6123290840358279103">Virtuele kaart bekijken</translation> @@ -1471,6 +1473,7 @@ Anders wordt dit geblokkeerd door je privacyinstellingen. Hierdoor werkt de cont <translation id="6423385022588644828">Bevestig je kaarten sneller door vanaf nu Touch ID te gebruiken</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Luikvouw</translation> +<translation id="6428146287756735566">Reis hervatten om relevante activiteit in je Chrome-geschiedenis te bekijken</translation> <translation id="6428450836711225518">Je telefoonnummer verifiëren</translation> <translation id="6433490469411711332">Contactgegevens bewerken</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> heeft de verbinding geweigerd.</translation> @@ -1522,6 +1525,7 @@ Anders wordt dit geblokkeerd door je privacyinstellingen. Hierdoor werkt de cont <translation id="6643016212128521049">Wissen</translation> <translation id="6645291930348198241">Toegang krijgen tot cookies en sitegegevens.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Geen}=1{Van 1 site (je wordt niet uitgelogd bij je Google-account)}other{Van # sites (je wordt niet uitgelogd bij je Google-account)}}</translation> +<translation id="6647197322759179819">Reis hervatten</translation> <translation id="6648459603387803038">Je beheerder kan je browserinstellingen op afstand wijzigen. Activiteit op dit apparaat kan ook buiten Chrome worden beheerd.</translation> <translation id="6648524591329069940">Serif-lettertype</translation> <translation id="6651270836885078973">Beheerd door:</translation> @@ -2171,6 +2175,7 @@ Aanvullende informatie: <translation id="9114524666733003316">Creditcard bevestigen...</translation> <translation id="9114581008513152754">Deze browser wordt niet beheerd door een bedrijf of andere organisatie. Activiteit op dit apparaat kan buiten Chrome worden beheerd. <ph name="BEGIN_LINK" />Meer informatie<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Nieuw</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />. Druk op Tab en daarna op Enter om je reis te hervatten en relevante activiteit in je Chrome-geschiedenis te bekijken.</translation> <translation id="9119042192571987207">Geüpload</translation> <translation id="9128016270925453879">Beleid is geladen</translation> <translation id="9128870381267983090">Verbinding maken met netwerk</translation> diff --git a/components/strings/components_strings_no.xtb b/components/strings/components_strings_no.xtb index 9f01abb29a7db6..c6ebab26e2ef0b 100644 --- a/components/strings/components_strings_no.xtb +++ b/components/strings/components_strings_no.xtb @@ -734,6 +734,7 @@ brukere av denne nettleseren.</translation> <translation id="3631244953324577188">Biometri</translation> <translation id="3633738897356909127">Knappen «Oppdater Chrome» – trykk på Enter for å oppdatere Chrome fra Chrome-innstillingene</translation> <translation id="3634530185120165534">Skuff 5</translation> +<translation id="3637662659967048211">Lagre i Google-kontoen</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Program:</translation> <translation id="3650584904733503804">Valideringen var vellykket</translation> @@ -1411,6 +1412,7 @@ brukere av denne nettleseren.</translation> <translation id="6106989379647458772">Det kan hende at nettsiden på <ph name="PAGE" /> er midlertidig nede eller flyttet permanent til en ny nettadresse.</translation> <translation id="6107012941649240045">Utstedt til</translation> <translation id="610911394827799129">Det kan hende Google-kontoen din har andre typer nettleserlogger på <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Fortsett ferden-knappen – trykk på Enter for å fortsette ferden og se relevant aktivitet i Chrome-loggen</translation> <translation id="6116338172782435947">Se tekst og bilder som er kopiert til utklippstavlen</translation> <translation id="6120179357481664955">Husker du UPI-ID-en din?</translation> <translation id="6123290840358279103">Se virtuelt kort</translation> @@ -1486,6 +1488,7 @@ brukere av denne nettleseren.</translation> <translation id="6423385022588644828">Bekreft kortene dine raskere ved å bruke Touch ID fra nå av</translation> <translation id="6425092077175753609">Materiale</translation> <translation id="6427730057873428458">Vindusfals</translation> +<translation id="6428146287756735566">Fortsett ferden for å se relevant aktivitet i Chrome-loggen</translation> <translation id="6428450836711225518">Bekreft telefonnummeret ditt</translation> <translation id="6433490469411711332">Endre kontaktinformasjonen</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> avviste tilkoblingsforsøket.</translation> @@ -1537,6 +1540,7 @@ brukere av denne nettleseren.</translation> <translation id="6643016212128521049">Tøm</translation> <translation id="6645291930348198241">få tilgang til informasjonskapsler og nettstedsdata</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Ingen}=1{Fra 1 nettsted (du blir ikke logget av Google-kontoen din)}other{Fra # nettsteder (du blir ikke logget av Google-kontoen din)}}</translation> +<translation id="6647197322759179819">Fortsett ferden</translation> <translation id="6648459603387803038">Administratoren kan endre nettleseroppsettet eksternt. Aktiviteten på denne enheten kan også administreres utenfor Chrome.</translation> <translation id="6648524591329069940">Med seriffer</translation> <translation id="6651270836885078973">Administreres av:</translation> @@ -2187,6 +2191,7 @@ Mer informasjon: <translation id="9114524666733003316">Bekrefter kortet …</translation> <translation id="9114581008513152754">Denne nettleseren administreres ikke av et selskap eller en annen organisasjon. Aktiviteten på denne enheten kan bli administrert utenfor Chrome. <ph name="BEGIN_LINK" />Finn ut mer<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Frisk</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" /> – trykk på Tab og deretter på Enter for å fortsette ferden og se relevant aktivitet i Chrome-loggen</translation> <translation id="9119042192571987207">Opplastet</translation> <translation id="9128016270925453879">Regler er lastet inn</translation> <translation id="9128870381267983090">Koble til nettverk</translation> diff --git a/components/strings/components_strings_pl.xtb b/components/strings/components_strings_pl.xtb index 4cec46b3345840..1d5c6cff68ff86 100644 --- a/components/strings/components_strings_pl.xtb +++ b/components/strings/components_strings_pl.xtb @@ -730,6 +730,7 @@ Jeśli się nie zgodzisz, zostaną one zablokowane ze względu na Twoje ustawien <translation id="3631244953324577188">Biometria</translation> <translation id="3633738897356909127">Przycisk aktualizacji Chrome. Naciśnij Enter, by zaktualizować przeglądarkę Chrome z poziomu jej ustawień.</translation> <translation id="3634530185120165534">Taca 5</translation> +<translation id="3637662659967048211">Zapisz na koncie Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplikacja:</translation> <translation id="3650584904733503804">Weryfikacja powiodła się</translation> @@ -1402,6 +1403,7 @@ Jeśli się nie zgodzisz, zostaną one zablokowane ze względu na Twoje ustawien <translation id="6106989379647458772">Strona <ph name="PAGE" /> może być chwilowo niedostępna lub została przeniesiona pod nowy adres.</translation> <translation id="6107012941649240045">Wystawiony dla</translation> <translation id="610911394827799129">Inne rodzaje historii przeglądania mogą być nadal dostępne na Twoim koncie Google na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Przycisk Wznów podróż; aby wznowić podróż i zobaczyć odpowiednią aktywność w historii Chrome, naciśnij Enter</translation> <translation id="6116338172782435947">Mieć dostęp do tekstu i obrazów skopiowanych do schowka</translation> <translation id="6120179357481664955">Zapamiętać Twój identyfikator UPI?</translation> <translation id="6123290840358279103">Zobacz kartę wirtualną</translation> @@ -1477,6 +1479,7 @@ Jeśli się nie zgodzisz, zostaną one zablokowane ze względu na Twoje ustawien <translation id="6423385022588644828">Potwierdzaj karty szybciej przy użyciu Touch ID</translation> <translation id="6425092077175753609">Styl Material</translation> <translation id="6427730057873428458">Składanie od góry i od dołu do środka</translation> +<translation id="6428146287756735566">Wznów podróż, aby zobaczyć odpowiednią aktywność w historii Chrome</translation> <translation id="6428450836711225518">Weryfikowanie numeru telefonu</translation> <translation id="6433490469411711332">Edytuj dane kontaktowe</translation> <translation id="6433595998831338502">Serwer <ph name="HOST_NAME" /> odrzucił połączenie.</translation> @@ -1528,6 +1531,7 @@ Jeśli się nie zgodzisz, zostaną one zablokowane ze względu na Twoje ustawien <translation id="6643016212128521049">Wyczyść</translation> <translation id="6645291930348198241">Dostęp do plików cookie i danych witryn.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Brak}=1{Z 1 witryny (nie spowoduje to wylogowania z konta Google)}few{Z # witryn (nie spowoduje to wylogowania z konta Google)}many{Z # witryn (nie spowoduje to wylogowania z konta Google)}other{Z # witryny (nie spowoduje to wylogowania z konta Google)}}</translation> +<translation id="6647197322759179819">Wznów podróż</translation> <translation id="6648459603387803038">Administrator może zdalnie zmienić konfigurację przeglądarki. Aktywność na tym urządzeniu może być zarządzana również poza Chrome.</translation> <translation id="6648524591329069940">Czcionka szeryfowa</translation> <translation id="6651270836885078973">Zarządzane przez:</translation> @@ -2179,6 +2183,7 @@ Dodatkowe informacje: <translation id="9114524666733003316">Sprawdzam kartę…</translation> <translation id="9114581008513152754">Ta przeglądarka nie jest zarządzana przez firmę ani inną organizację. Aktywność na tym urządzeniu może być zarządzana poza Chrome. <ph name="BEGIN_LINK" />Więcej informacji<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Świeży</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />; aby wznowić podróż i zobaczyć odpowiednią aktywność w historii Chrome, naciśnij Tab, a potem Enter</translation> <translation id="9119042192571987207">Przesłano</translation> <translation id="9128016270925453879">Zasady zostały załadowane</translation> <translation id="9128870381267983090">Połącz z siecią</translation> diff --git a/components/strings/components_strings_pt-BR.xtb b/components/strings/components_strings_pt-BR.xtb index 972be96345522a..3666b6417d4410 100644 --- a/components/strings/components_strings_pt-BR.xtb +++ b/components/strings/components_strings_pt-BR.xtb @@ -728,6 +728,7 @@ Se não fizer isso, a permissão será bloqueada pelas configurações de privac <translation id="3631244953324577188">Biometria</translation> <translation id="3633738897356909127">Botão "Atualizar o Chrome". Pressione "Enter" para atualizar o Chrome pelas configurações dele</translation> <translation id="3634530185120165534">Bandeja 5</translation> +<translation id="3637662659967048211">Salvar na Conta do Google</translation> <translation id="3640766068866876100">102 mm × 152 mm</translation> <translation id="3642638418806704195">Aplicativo:</translation> <translation id="3650584904733503804">Validação bem-sucedida</translation> @@ -1400,6 +1401,7 @@ Se não fizer isso, a permissão será bloqueada pelas configurações de privac <translation id="6106989379647458772">A página da Web no endereço <ph name="PAGE" /> pode estar temporariamente inativa ou pode ter sido transferida para um novo endereço.</translation> <translation id="6107012941649240045">Emitido para</translation> <translation id="610911394827799129">Sua Conta do Google pode ter outras formas de histórico de navegação em <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Botão "Retomar jornada". Pressione Enter para retomar a jornada e ver as atividades relevantes no seu histórico do Chrome</translation> <translation id="6116338172782435947">Ver os textos e imagens copiados para a área de transferência</translation> <translation id="6120179357481664955">Lembrar código da UPI?</translation> <translation id="6123290840358279103">Ver cartão virtual</translation> @@ -1475,6 +1477,7 @@ Se não fizer isso, a permissão será bloqueada pelas configurações de privac <translation id="6423385022588644828">Confirme seus cartões mais rapidamente usando o Touch ID de agora em diante</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Dobra janela</translation> +<translation id="6428146287756735566">Retomar a jornada para ver as atividades relevantes no seu histórico do Chrome</translation> <translation id="6428450836711225518">Verificar seu número de telefone</translation> <translation id="6433490469411711332">Editar informações de contato</translation> <translation id="6433595998831338502">A conexão com <ph name="HOST_NAME" /> foi recusada.</translation> @@ -1526,6 +1529,7 @@ Se não fizer isso, a permissão será bloqueada pelas configurações de privac <translation id="6643016212128521049">Limpar</translation> <translation id="6645291930348198241">Acesso a cookies e dados do site.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Nenhum}=1{De 1 site (você não será desconectado da sua Conta do Google)}one{De # site (você não será desconectado da sua Conta do Google)}other{De # sites (você não será desconectado da sua Conta do Google)}}</translation> +<translation id="6647197322759179819">Retomar jornada</translation> <translation id="6648459603387803038">O administrador pode mudar as configurações do navegador remotamente. A atividade deste dispositivo também pode ser gerenciada fora do Chrome.</translation> <translation id="6648524591329069940">Fonte Serif</translation> <translation id="6651270836885078973">Gerenciamento por:</translation> @@ -2179,6 +2183,7 @@ incomuns e incorretas. Isso pode acontecer quando um invasor está fingindo ser <translation id="9114524666733003316">Confirmando cartão…</translation> <translation id="9114581008513152754">Este navegador não é gerenciado por uma empresa ou outra organização. A atividade deste dispositivo pode ser gerenciada fora do Chrome. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Revigorado</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />. Pressione Tab e depois Enter para retomar a jornada e ver as atividades no seu histórico do Chrome</translation> <translation id="9119042192571987207">Enviado</translation> <translation id="9128016270925453879">As políticas foram carregadas</translation> <translation id="9128870381267983090">Conectar à rede</translation> diff --git a/components/strings/components_strings_pt-PT.xtb b/components/strings/components_strings_pt-PT.xtb index bda1bcb18ca386..2c518cd8d993a8 100644 --- a/components/strings/components_strings_pt-PT.xtb +++ b/components/strings/components_strings_pt-PT.xtb @@ -734,6 +734,7 @@ Se não permitir, isto será bloqueado pelas suas definições de privacidade. I <translation id="3631244953324577188">Biometria</translation> <translation id="3633738897356909127">Botão Atualizar Chrome; prima Enter para atualizar o Chrome nas Definições do Chrome.</translation> <translation id="3634530185120165534">Tabuleiro 5</translation> +<translation id="3637662659967048211">Guardar na Conta Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplicação:</translation> <translation id="3650584904733503804">Validação com êxito</translation> @@ -1411,6 +1412,7 @@ Se não permitir, isto será bloqueado pelas suas definições de privacidade. I <translation id="6106989379647458772">A página Web em <ph name="PAGE" /> pode estar temporariamente indisponível ou pode ter sido permanentemente movida para um novo endereço Web.</translation> <translation id="6107012941649240045">Emitido para</translation> <translation id="610911394827799129">A sua Conta Google pode ter outras formas do histórico de navegação em <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Botão Retomar percurso, prima Enter para retomar o percurso e ver atividade relevante no Histórico do Chrome</translation> <translation id="6116338172782435947">Ver o texto e as imagens copiados para a área de transferência</translation> <translation id="6120179357481664955">Lembra-se do seu ID do UPI?</translation> <translation id="6123290840358279103">Ver cartão virtual</translation> @@ -1486,6 +1488,7 @@ Se não permitir, isto será bloqueado pelas suas definições de privacidade. I <translation id="6423385022588644828">Confirme os seus cartões mais rapidamente ao utilizar o Touch ID a partir de agora.</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Dobra simétrica</translation> +<translation id="6428146287756735566">Retome o percurso para ver atividade relevante no Histórico do Chrome</translation> <translation id="6428450836711225518">Valide o seu número de telefone</translation> <translation id="6433490469411711332">Editar informações de contacto</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> recusou estabelecer ligação.</translation> @@ -1537,6 +1540,7 @@ Se não permitir, isto será bloqueado pelas suas definições de privacidade. I <translation id="6643016212128521049">Limpar</translation> <translation id="6645291930348198241">Aceder aos cookies e dados de sites.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Nenhum}=1{De 1 site (a sessão na sua Conta Google não é terminada).}other{De # sites (a sessão na sua Conta Google não é terminada).}}</translation> +<translation id="6647197322759179819">Retomar percurso</translation> <translation id="6648459603387803038">O administrador pode alterar a configuração do navegador remotamente. A atividade neste dispositivo também pode ser gerida fora do Chrome.</translation> <translation id="6648524591329069940">Tipo de letra Serif</translation> <translation id="6651270836885078973">Gerido por:</translation> @@ -2188,6 +2192,7 @@ Detalhes adicionais: <translation id="9114524666733003316">A confirmar o cartão…</translation> <translation id="9114581008513152754">Este navegador não é gerido por uma empresa ou outra entidade. A atividade neste dispositivo pode ser gerida fora do Chrome. <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Moderno</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, prima Tab e, em seguida, Enter para retomar o percurso e ver atividade relevante no Histórico do Chrome</translation> <translation id="9119042192571987207">Carregado</translation> <translation id="9128016270925453879">As políticas foram carregadas.</translation> <translation id="9128870381267983090">Ligar à rede</translation> diff --git a/components/strings/components_strings_ro.xtb b/components/strings/components_strings_ro.xtb index 2068196e377c74..fb4f993e65d0f6 100644 --- a/components/strings/components_strings_ro.xtb +++ b/components/strings/components_strings_ro.xtb @@ -732,6 +732,7 @@ <translation id="3631244953324577188">Sisteme biometrice</translation> <translation id="3633738897356909127">Butonul Actualizează Chrome, apasă pe Enter pentru a actualiza Chrome din setările Chrome</translation> <translation id="3634530185120165534">Tava 5</translation> +<translation id="3637662659967048211">Salvează în Contul Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplicație:</translation> <translation id="3650584904733503804">Validarea a reușit</translation> @@ -1409,6 +1410,7 @@ <translation id="6106989379647458772">Este posibil ca pagina web de la <ph name="PAGE" /> să fie blocată temporar sau să fi fost mutată definitiv la o nouă adresă web.</translation> <translation id="6107012941649240045">Emis către</translation> <translation id="610911394827799129">Contul Google poate să ofere alte forme ale istoricului de navigare la <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Butonul Repetă experiența, apasă pe Enter pentru a repeta experiența și a vedea activitatea relevantă din istoricul Chrome</translation> <translation id="6116338172782435947">să afișeze textul și imaginile copiate în clipboard</translation> <translation id="6120179357481664955">Îți amintești ID-ul UPI?</translation> <translation id="6123290840358279103">Vezi cardul virtual</translation> @@ -1484,6 +1486,7 @@ <translation id="6423385022588644828">Confirmă-ți cardurile mai rapid, folosind Touch ID</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Îndoire de tip fereastră</translation> +<translation id="6428146287756735566">Repetă experiența pentru a vedea activitatea relevantă din istoricul Chrome</translation> <translation id="6428450836711225518">Confirmă numărul de telefon</translation> <translation id="6433490469411711332">Editează informațiile de contact</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> a refuzat conexiunea.</translation> @@ -1535,6 +1538,7 @@ <translation id="6643016212128521049">Șterge</translation> <translation id="6645291930348198241">să acceseze cookie-urile și datele privind site-urile.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Niciunul}=1{De pe un site (nu te va deconecta de la Contul Google)}few{De pe # site-uri (nu te va deconecta de la Contul Google)}other{De pe # de site-uri (nu te va deconecta de la Contul Google)}}</translation> +<translation id="6647197322759179819">Repetă experiența</translation> <translation id="6648459603387803038">Administratorul poate schimba configurația browserului de la distanță. Este posibil ca activitatea de pe acest dispozitiv să fie gestionată și din afara Chrome.</translation> <translation id="6648524591329069940">Font Serif</translation> <translation id="6651270836885078973">Gestionat de:</translation> @@ -2187,6 +2191,7 @@ Detalii suplimentare: <translation id="9114524666733003316">Se confirmă cardul…</translation> <translation id="9114581008513152754">Browserul nu este gestionat de o companie sau o altă organizație. Este posibil ca activitatea de pe acest dispozitiv să fie gestionată în afara Chrome. <ph name="BEGIN_LINK" />Află mai multe<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Prospețime</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, apasă pe Tab, apoi pe Enter pentru a repeta experiența și a vedea activitatea relevantă din istoricul Chrome</translation> <translation id="9119042192571987207">Încărcat</translation> <translation id="9128016270925453879">Politicile s-au încărcat</translation> <translation id="9128870381267983090">Conectați-vă la rețea</translation> diff --git a/components/strings/components_strings_ru.xtb b/components/strings/components_strings_ru.xtb index 0b8bcaf26b55b3..443c625b1e7fc9 100644 --- a/components/strings/components_strings_ru.xtb +++ b/components/strings/components_strings_ru.xtb @@ -727,6 +727,7 @@ <translation id="3631244953324577188">Биометрия</translation> <translation id="3633738897356909127">Кнопка "Обновить Chrome". Нажмите Ввод, чтобы обновить Chrome.</translation> <translation id="3634530185120165534">Лоток 5</translation> +<translation id="3637662659967048211">Сохранить в аккаунте Google?</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Приложение:</translation> <translation id="3650584904733503804">Проверка выполнена успешно</translation> @@ -1399,6 +1400,7 @@ <translation id="6106989379647458772">Возможно, веб-страница <ph name="PAGE" /> временно недоступна или находится по новому адресу.</translation> <translation id="6107012941649240045">Кому выдан</translation> <translation id="610911394827799129">Информация о других ваших действиях в Интернете может также храниться на странице <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Кнопка "Продолжить поиск в истории". Нажмите Ввод, чтобы посмотреть похожие запросы в истории Chrome.</translation> <translation id="6116338172782435947">Просмотр текста и изображений, скопированных в буфер обмена</translation> <translation id="6120179357481664955">Запомнить идентификатор UPI?</translation> <translation id="6123290840358279103">Посмотреть виртуальную карту</translation> @@ -1474,6 +1476,7 @@ <translation id="6423385022588644828">Подтверждайте карты быстрее с помощью Touch ID</translation> <translation id="6425092077175753609">Material design</translation> <translation id="6427730057873428458">Фальцовка калиткой в два сгиба</translation> +<translation id="6428146287756735566">Посмотреть похожие запросы в истории Chrome</translation> <translation id="6428450836711225518">Подтвердите номер телефона</translation> <translation id="6433490469411711332">Изменить контактную информацию</translation> <translation id="6433595998831338502">Сайт <ph name="HOST_NAME" /> не позволяет установить соединение.</translation> @@ -1525,6 +1528,7 @@ <translation id="6643016212128521049">Удалить</translation> <translation id="6645291930348198241">доступ к файлам cookie и данным сайта.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Нет}=1{С 1 сайта (вы останетесь в аккаунте Google)}one{С # сайта (вы останетесь в аккаунте Google)}few{С # сайтов (вы останетесь в аккаунте Google)}many{С # сайтов (вы останетесь в аккаунте Google)}other{С # сайта (вы останетесь в аккаунте Google)}}</translation> +<translation id="6647197322759179819">Продолжить поиск в истории</translation> <translation id="6648459603387803038">Администратор может удаленно менять настройки браузера и управлять действиями вне браузера Chrome на этом устройстве.</translation> <translation id="6648524591329069940">Шрифты с засечками</translation> <translation id="6651270836885078973">Управляет:</translation> @@ -2176,6 +2180,7 @@ <translation id="9114524666733003316">Подтверждение карты...</translation> <translation id="9114581008513152754">Компания или организация не управляет этим браузером. Действиями на этом устройстве можно управлять вне браузера Chrome. <ph name="BEGIN_LINK" />Подробнее…<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Свежий</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />. Нажмите Tab и затем Ввод, чтобы посмотреть похожие запросы в истории Chrome.</translation> <translation id="9119042192571987207">Загружен</translation> <translation id="9128016270925453879">Правила загружены</translation> <translation id="9128870381267983090">Подключитесь к сети</translation> diff --git a/components/strings/components_strings_sk.xtb b/components/strings/components_strings_sk.xtb index 492de7d9bbe5c1..4f14ee41ccb2ae 100644 --- a/components/strings/components_strings_sk.xtb +++ b/components/strings/components_strings_sk.xtb @@ -724,6 +724,7 @@ Ich používanie by bolo inak blokované vašimi nastaveniami ochrany súkromia. <translation id="3631244953324577188">Biometria</translation> <translation id="3633738897356909127">Tlačidlo Aktualizovať Chrome. Stlačením tlačidla Enter aktualizujete Chrome v jeho nastaveniach.</translation> <translation id="3634530185120165534">Priehradka č. 5</translation> +<translation id="3637662659967048211">Uloženie do účtu Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplikácia:</translation> <translation id="3650584904733503804">Overenie bolo úspešné</translation> @@ -1396,6 +1397,7 @@ Ich používanie by bolo inak blokované vašimi nastaveniami ochrany súkromia. <translation id="6106989379647458772">Stránka <ph name="PAGE" /> je možno dočasne nedostupná, možno bola natrvalo presunutá na novú webovú adresu.</translation> <translation id="6107012941649240045">Vydané pre</translation> <translation id="610911394827799129">Váš účet Google môže mať ďalšie formy histórie prehliadania na adrese <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Tlačidlo Pokračovať v ceste, po stlačení klávesa Enter budete pokračovať v ceste a zobrazíte si relevantnú aktivitu v histórii Chromu</translation> <translation id="6116338172782435947">Prístup k textu a obrázkom skopírovaným do schránky</translation> <translation id="6120179357481664955">Chcete uložiť svoj identifikátor UPI?</translation> <translation id="6123290840358279103">Zobraziť virtuálnu kartu</translation> @@ -1470,6 +1472,7 @@ Ich používanie by bolo inak blokované vašimi nastaveniami ochrany súkromia. <translation id="6423385022588644828">Odteraz môžete potvrdzovať karty rýchlejšie pomocou funkcie Touch ID</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Obojstranná fazóna</translation> +<translation id="6428146287756735566">Pokračujte v ceste a zobrazte si relevantnú aktivitu v histórii Chromu</translation> <translation id="6428450836711225518">Overenie telefónneho čísla</translation> <translation id="6433490469411711332">Úprava kontaktných informácií</translation> <translation id="6433595998831338502">Web <ph name="HOST_NAME" /> zamietol pripojenie.</translation> @@ -1521,6 +1524,7 @@ Ich používanie by bolo inak blokované vašimi nastaveniami ochrany súkromia. <translation id="6643016212128521049">Vymazať</translation> <translation id="6645291930348198241">Používať súbory cookie a údaje webov.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Žiadne}=1{Z 1 webu (neodhlásime vás z účtu Google)}few{Z # webov (neodhlásime vás z účtu Google)}many{From # sites (you won't be signed out of your Google Account)}other{Z # webov (neodhlásime vás z účtu Google)}}</translation> +<translation id="6647197322759179819">Pokračovať v ceste</translation> <translation id="6648459603387803038">Nastavenia prehliadača môže vzdialene zmeniť správca. Aktivita v tomto zariadení môže byť tiež spravovaná mimo Chromu.</translation> <translation id="6648524591329069940">Písmo Serif</translation> <translation id="6651270836885078973">Spravuje:</translation> @@ -2173,6 +2177,7 @@ Ich používanie by bolo inak blokované vašimi nastaveniami ochrany súkromia. <translation id="9114524666733003316">Overuje sa karta…</translation> <translation id="9114581008513152754">Tento prehliadač nespravuje firma ani iná organizácia. Aktivita v tomto zariadení môže byť spravovaná mimo Chromu. <ph name="BEGIN_LINK" />Ďalšie informácie<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Príjemné</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, stlačte Tab, potom Enter a pokračujte tak v ceste so zobrazením relevantnej aktivity v histórii Chromu</translation> <translation id="9119042192571987207">Nahrané</translation> <translation id="9128016270925453879">Načítavajú sa pravidlá</translation> <translation id="9128870381267983090">Pripojiť k sieti</translation> diff --git a/components/strings/components_strings_sl.xtb b/components/strings/components_strings_sl.xtb index bcf8d09d84aa96..2d0701e0757c17 100644 --- a/components/strings/components_strings_sl.xtb +++ b/components/strings/components_strings_sl.xtb @@ -734,6 +734,7 @@ V nasprotnem primeru bodo to blokirale nastavitve zasebnosti. S tem bo vsebina, <translation id="3631244953324577188">Biometrika</translation> <translation id="3633738897356909127">Gumb za posodobitev Chroma, pritisnite Enter, če želite posodobiti Chrome v Chromovih nastavitvah</translation> <translation id="3634530185120165534">Pladenj 5</translation> +<translation id="3637662659967048211">Shranjevanje v račun Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Program:</translation> <translation id="3650584904733503804">Preverjanje veljavnosti uspešno</translation> @@ -1411,6 +1412,7 @@ V nasprotnem primeru bodo to blokirale nastavitve zasebnosti. S tem bo vsebina, <translation id="6106989379647458772">Spletna stran na naslovu <ph name="PAGE" /> morda začasno ni na voljo ali pa je trajno preseljena na drug spletni naslov.</translation> <translation id="6107012941649240045">Izdano za</translation> <translation id="610911394827799129">V Google Računu so morda druge vrste zgodovine brskanja na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Gumb za nadaljevanje poti, pritisnite Enter, če želite nadaljevati pot in si ogledati pomembno dejavnost v zgodovini uporabe Chroma.</translation> <translation id="6116338172782435947">ogled besedila in slik, kopiranih v odložišče</translation> <translation id="6120179357481664955">Si želite zapomniti ID za UPI?</translation> <translation id="6123290840358279103">Ogled navidezne kartice</translation> @@ -1486,6 +1488,7 @@ V nasprotnem primeru bodo to blokirale nastavitve zasebnosti. S tem bo vsebina, <translation id="6423385022588644828">Od zdaj naprej lahko uporabljate Touch ID in kartice potrjujete hitreje</translation> <translation id="6425092077175753609">Materialno</translation> <translation id="6427730057873428458">Prepogibanje v obliki okna</translation> +<translation id="6428146287756735566">Nadaljujte pot, če si želite ogledati pomembno dejavnost v zgodovini uporabe Chroma.</translation> <translation id="6428450836711225518">Preverjanje telefonske številke</translation> <translation id="6433490469411711332">Uredi informacije o stiku</translation> <translation id="6433595998831338502">Spletno mesto <ph name="HOST_NAME" /> ni dovolilo povezave.</translation> @@ -1537,6 +1540,7 @@ V nasprotnem primeru bodo to blokirale nastavitve zasebnosti. S tem bo vsebina, <translation id="6643016212128521049">Izbriši</translation> <translation id="6645291930348198241">Dostop do piškotkov in podatkov spletnih mest.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Nič}=1{Na 1 spletnem mestu (iz Google Računa ne boste odjavljeni)}one{Na # spletnem mestu (iz Google Računa ne boste odjavljeni)}two{Na # spletnih mestih (iz Google Računa ne boste odjavljeni)}few{Na # spletnih mestih (iz Google Računa ne boste odjavljeni)}other{Na # spletnih mestih (iz Google Računa ne boste odjavljeni)}}</translation> +<translation id="6647197322759179819">Nadaljuj pot</translation> <translation id="6648459603387803038">Skrbnik lahko spremeni nastavitev brskalnika na daljavo. Dejavnost v tej napravi morda tudi upravljajo zunaj Chroma.</translation> <translation id="6648524591329069940">Serifna pisava</translation> <translation id="6651270836885078973">Upravitelj:</translation> @@ -2188,6 +2192,7 @@ Dodatne podrobnosti: <translation id="9114524666733003316">Potrjevanje kartice …</translation> <translation id="9114581008513152754">Tega brskalnika ne upravlja podjetje ali druga organizacija. Dejavnost v tej napravi morda upravljajo zunaj Chroma. <ph name="BEGIN_LINK" />Več o tem<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Sveže</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite tabulatorko, nato Enter, če želite nadaljevati pot in si ogledati pomembno dejavnost v zgodovini uporabe Chroma.</translation> <translation id="9119042192571987207">Naloženo</translation> <translation id="9128016270925453879">Pravilniki so naloženi</translation> <translation id="9128870381267983090">Vzpostavi povezavo z omrežjem</translation> diff --git a/components/strings/components_strings_sr-Latn.xtb b/components/strings/components_strings_sr-Latn.xtb index 13ba30515dd77e..e59da9af5eda15 100644 --- a/components/strings/components_strings_sr-Latn.xtb +++ b/components/strings/components_strings_sr-Latn.xtb @@ -734,6 +734,7 @@ To inače blokiraju podešavanja privatnosti. To omogućava da sadržaj sa koji <translation id="3631244953324577188">Biometrija</translation> <translation id="3633738897356909127">Dugme Ažuriraj Chrome, pritisnite Enter da biste ažurirali Chrome iz podešavanja Chrome-a</translation> <translation id="3634530185120165534">5. fioka</translation> +<translation id="3637662659967048211">Sačuvajte na Google nalogu</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Aplikacija:</translation> <translation id="3650584904733503804">Potvrda valjanosti je uspela</translation> @@ -1411,6 +1412,7 @@ To inače blokiraju podešavanja privatnosti. To omogućava da sadržaj sa koji <translation id="6106989379647458772">Veb-stranica na adresi <ph name="PAGE" /> možda privremeno ne funkcioniše ili je trajno premeštena na novu veb-adresu.</translation> <translation id="6107012941649240045">Izdato za</translation> <translation id="610911394827799129">Google nalog može da ima druge oblike istorije pregledanja na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Dugme Nastavi putanjom, pritisnite Enter da biste nastavili putanjom i videli relevantne aktivnosti u istoriji Chrome-a</translation> <translation id="6116338172782435947">da vidi tekst i slike koji su kopirani u privremenu memoriju</translation> <translation id="6120179357481664955">Želite da sačuvate ID za UPI?</translation> <translation id="6123290840358279103">Prikaži virtuelnu karticu</translation> @@ -1485,6 +1487,7 @@ To inače blokiraju podešavanja privatnosti. To omogućava da sadržaj sa koji <translation id="6423385022588644828">Od sada brže potvrđujte kartice uz Touch ID</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Presavijanje u obliku prozora</translation> +<translation id="6428146287756735566">Nastavite putanjom da biste videli relevantne aktivnosti u istoriji Chrome-a</translation> <translation id="6428450836711225518">Verifikujte broj telefona</translation> <translation id="6433490469411711332">Izmenite kontakt informacije</translation> <translation id="6433595998831338502">Host <ph name="HOST_NAME" /> je odbio povezivanje.</translation> @@ -1536,6 +1539,7 @@ To inače blokiraju podešavanja privatnosti. To omogućava da sadržaj sa koji <translation id="6643016212128521049">Obriši</translation> <translation id="6645291930348198241">da pristupa kolačićima i podacima o sajtovima.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{None}=1{Sa 1 sajta (nećemo vas odjaviti sa Google naloga)}one{Sa # sajta (nećemo vas odjaviti sa Google naloga)}few{Sa # sajta (nećemo vas odjaviti sa Google naloga)}other{Sa # sajtova (nećemo vas odjaviti sa Google naloga)}}</translation> +<translation id="6647197322759179819">Nastavi putanjom</translation> <translation id="6648459603387803038">Administrator može daljinski da promeni podešavanje pregledača. Aktivnostima na ovom uređaju može da se upravlja i van Chrome-a.</translation> <translation id="6648524591329069940">Font Serif</translation> <translation id="6651270836885078973">Ovim upravlja:</translation> @@ -2188,6 +2192,7 @@ Dodatni detalji: <translation id="9114524666733003316">Kartica se potvrđuje...</translation> <translation id="9114581008513152754">Ovim pregledačem ne upravlja kompanija niti druga organizacija. Aktivnostima na ovom uređaju se možda upravlja van Chrome-a. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Sveže</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, pa Enter da biste nastavili putanjom i videli relevantne aktivnosti u istoriji Chrome-a</translation> <translation id="9119042192571987207">Otpremljeno</translation> <translation id="9128016270925453879">Smernice su učitane</translation> <translation id="9128870381267983090">Povezivanje sa mrežom</translation> diff --git a/components/strings/components_strings_sr.xtb b/components/strings/components_strings_sr.xtb index 0ecd4263fdfe02..a1a1d901d85e16 100644 --- a/components/strings/components_strings_sr.xtb +++ b/components/strings/components_strings_sr.xtb @@ -734,6 +734,7 @@ <translation id="3631244953324577188">Биометрија</translation> <translation id="3633738897356909127">Дугме Ажурирај Chrome, притисните Enter да бисте ажурирали Chrome из подешавања Chrome-а</translation> <translation id="3634530185120165534">5. фиока</translation> +<translation id="3637662659967048211">Сачувајте на Google налогу</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Апликација:</translation> <translation id="3650584904733503804">Потврда ваљаности је успела</translation> @@ -1411,6 +1412,7 @@ <translation id="6106989379647458772">Веб-страница на адреси <ph name="PAGE" /> можда привремено не функционише или је трајно премештена на нову веб-адресу.</translation> <translation id="6107012941649240045">Издато за</translation> <translation id="610911394827799129">Google налог може да има друге облике историје прегледања на <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Дугме Настави путањом, притисните Enter да бисте наставили путањом и видели релевантне активности у историји Chrome-а</translation> <translation id="6116338172782435947">да види текст и слике који су копирани у привремену меморију</translation> <translation id="6120179357481664955">Желите да сачувате ИД за UPI?</translation> <translation id="6123290840358279103">Прикажи виртуелну картицу</translation> @@ -1485,6 +1487,7 @@ <translation id="6423385022588644828">Од сада брже потврђујте картице уз Touch ID</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Пресавијање у облику прозора</translation> +<translation id="6428146287756735566">Наставите путањом да бисте видели релевантне активности у историји Chrome-а</translation> <translation id="6428450836711225518">Верификујте број телефона</translation> <translation id="6433490469411711332">Измените контакт информације</translation> <translation id="6433595998831338502">Хост <ph name="HOST_NAME" /> је одбио повезивање.</translation> @@ -1536,6 +1539,7 @@ <translation id="6643016212128521049">Обриши</translation> <translation id="6645291930348198241">да приступа колачићима и подацима о сајтовима.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{None}=1{Са 1 сајта (нећемо вас одјавити са Google налога)}one{Са # сајта (нећемо вас одјавити са Google налога)}few{Са # сајта (нећемо вас одјавити са Google налога)}other{Са # сајтова (нећемо вас одјавити са Google налога)}}</translation> +<translation id="6647197322759179819">Настави путањом</translation> <translation id="6648459603387803038">Администратор може даљински да промени подешавање прегледача. Активностима на овом уређају може да се управља и ван Chrome-а.</translation> <translation id="6648524591329069940">Фонт Serif</translation> <translation id="6651270836885078973">Овим управља:</translation> @@ -2188,6 +2192,7 @@ <translation id="9114524666733003316">Картица се потврђује...</translation> <translation id="9114581008513152754">Овим прегледачем не управља компанија нити друга организација. Активностима на овом уређају се можда управља ван Chrome-а. <ph name="BEGIN_LINK" />Сазнајте више<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Свеже</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, притисните Tab, па Enter да бисте наставили путањом и видели релевантне активности у историји Chrome-а</translation> <translation id="9119042192571987207">Отпремљено</translation> <translation id="9128016270925453879">Смернице су учитане</translation> <translation id="9128870381267983090">Повезивање са мрежом</translation> diff --git a/components/strings/components_strings_sv.xtb b/components/strings/components_strings_sv.xtb index 70ca7bffcf1288..4b6b4e83606571 100644 --- a/components/strings/components_strings_sv.xtb +++ b/components/strings/components_strings_sv.xtb @@ -734,6 +734,7 @@ Annars blockeras detta av sekretessinställningarna. Om du tillåter detta kan i <translation id="3631244953324577188">Biometri</translation> <translation id="3633738897356909127">Knappen Uppdatera Chrome, tryck på retur om du vill uppdatera Chrome i inställningarna för Chrome</translation> <translation id="3634530185120165534">Fack 5</translation> +<translation id="3637662659967048211">Spara i Google-kontot</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Program:</translation> <translation id="3650584904733503804">Valideringen har genomförts</translation> @@ -1411,6 +1412,7 @@ Annars blockeras detta av sekretessinställningarna. Om du tillåter detta kan i <translation id="6106989379647458772">Webbsidan på <ph name="PAGE" /> kan vara nere tillfälligt eller ha flyttats permanent till en ny webbadress.</translation> <translation id="6107012941649240045">Utfärdat till</translation> <translation id="610911394827799129">Det kan finnas andra former av webbhistorik i Google-kontot på <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Knappen Återuppta sökning, tryck på Retur om du vill återuppta sökningen och se relevant aktivitet i Chrome-historiken</translation> <translation id="6116338172782435947">Tillgång till text och bilder som kopierats till Urklipp</translation> <translation id="6120179357481664955">Vill du spara UPI-id?</translation> <translation id="6123290840358279103">Visa virtuellt kort</translation> @@ -1486,6 +1488,7 @@ Annars blockeras detta av sekretessinställningarna. Om du tillåter detta kan i <translation id="6423385022588644828">Verifiera kreditkort snabbare genom att använda Touch ID från och med nu</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Fönsterfalsning</translation> +<translation id="6428146287756735566">Återuppta sökningen för att se relevant aktivitet i Chrome-historiken</translation> <translation id="6428450836711225518">Bekräfta ditt telefonnummer</translation> <translation id="6433490469411711332">Redigera kontaktuppgifter</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> avvisade anslutningen.</translation> @@ -1537,6 +1540,7 @@ Annars blockeras detta av sekretessinställningarna. Om du tillåter detta kan i <translation id="6643016212128521049">Rensa</translation> <translation id="6645291930348198241">få åtkomst till cookies och webbplatsdata.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Ingen}=1{Från 1 webbplats (du loggas inte ut från Google-kontot)}other{Från # webbplatser (du loggas inte ut från Google-kontot)}}</translation> +<translation id="6647197322759179819">Återuppta sökning</translation> <translation id="6648459603387803038">Administratören kan ändra webbläsarinställningarna på distans. Aktivitet på den här enheten kan hanteras även utanför Chrome.</translation> <translation id="6648524591329069940">Serif-teckensnitt</translation> <translation id="6651270836885078973">Hanteras av:</translation> @@ -2189,6 +2193,7 @@ Mer information: <translation id="9114524666733003316">Kortet kontrolleras …</translation> <translation id="9114581008513152754">Den här webbläsaren hanteras inte av ett företag eller en organisation. Aktiviteter på den här enheten kan hanteras utanför Chrome. <ph name="BEGIN_LINK" />Läs mer<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Fräsch</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, tryck på Tabb och sedan på Retur om du vill återuppta sökningen och se relevant aktivitet i Chrome-historiken</translation> <translation id="9119042192571987207">Uppladdad</translation> <translation id="9128016270925453879">Policyer har lästs in</translation> <translation id="9128870381267983090">Anslut till ett nätverk</translation> diff --git a/components/strings/components_strings_sw.xtb b/components/strings/components_strings_sw.xtb index f317db9d2f1e84..a73af1ab2e1921 100644 --- a/components/strings/components_strings_sw.xtb +++ b/components/strings/components_strings_sw.xtb @@ -733,6 +733,7 @@ Usipoiruhusu, itazuiwa na mipangilio yako ya faragha. Hali hii itaruhusu maudhui <translation id="3631244953324577188">Bayometriki</translation> <translation id="3633738897356909127">Kitufe cha 'Sasisha Chrome', bonyeza 'Enter' ili usasishe Chrome katika mipangilio yako ya Chrome</translation> <translation id="3634530185120165534">Trei ya tano</translation> +<translation id="3637662659967048211">Hifadhi kwenye Akaunti ya Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Programu:</translation> <translation id="3650584904733503804">Uhalalishaji umefanikiwa</translation> @@ -1410,6 +1411,7 @@ Usipoiruhusu, itazuiwa na mipangilio yako ya faragha. Hali hii itaruhusu maudhui <translation id="6106989379647458772">Huenda ukurasa wa wavuti ulio kwenye <ph name="PAGE" /> haupatikani kwa muda au umehamishwa kabisa hadi kwenye anwani mpya ya wavuti.</translation> <translation id="6107012941649240045">Kimetolewa Kwa</translation> <translation id="610911394827799129">Huenda Akaunti yako ya Google ina aina nyingine za historia ya kuvinjari katika <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Kitufe cha kuendelea na ziara, bonyeza Enter ili uendelee na ziara yako na uone shughuli muhimu katika historia yako kwenye Chrome</translation> <translation id="6116338172782435947">Kuona maandishi na picha zilizonakiliwa kwenye ubao wa kunakili</translation> <translation id="6120179357481664955">Ungependa kukumbuka kitambulisho chako cha UPI?</translation> <translation id="6123290840358279103">Angalia kadi pepe</translation> @@ -1485,6 +1487,7 @@ Usipoiruhusu, itazuiwa na mipangilio yako ya faragha. Hali hii itaruhusu maudhui <translation id="6423385022588644828">Thibitisha kadi zako kwa haraka zaidi ukitumia Touch ID kuanzia sasa</translation> <translation id="6425092077175753609">Usanifu bora</translation> <translation id="6427730057873428458">Mikunjo miwili sambamba</translation> +<translation id="6428146287756735566">Endelea na ziara yako ili uone shughuli muhimu katika historia yako kwenye Chrome</translation> <translation id="6428450836711225518">Thibitisha nambari yako ya simu</translation> <translation id="6433490469411711332">Badilisha maelezo ya mawasiliano</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> imekataa kuunganisha.</translation> @@ -1536,6 +1539,7 @@ Usipoiruhusu, itazuiwa na mipangilio yako ya faragha. Hali hii itaruhusu maudhui <translation id="6643016212128521049">Futa</translation> <translation id="6645291930348198241">Kufikia data ya tovuti na vidakuzi.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Hamna}=1{Kutoka tovuti 1 (hutaondolewa kwenye Akaunti ya Google)}other{Kutoka tovuti # (hutaondolewa kwenye Akaunti ya Google)}}</translation> +<translation id="6647197322759179819">Endelea na ziara yako</translation> <translation id="6648459603387803038">Msimamizi wako anaweza kubadilisha mipangilio ya kivinjari chako kwa mbali. Huenda shughuli kwenye kifaa hiki zikadhibitiwa nje ya Chrome.</translation> <translation id="6648524591329069940">Fonti ya "Serif"</translation> <translation id="6651270836885078973">Inadhibitiwa na:</translation> @@ -2184,6 +2188,7 @@ Usipoiruhusu, itazuiwa na mipangilio yako ya faragha. Hali hii itaruhusu maudhui <translation id="9114524666733003316">Inathibitisha kadi…</translation> <translation id="9114581008513152754">Kivinjari hiki hakidhibitiwi na kampuni au shirika lingine. Huenda shughuli kwenye kifaa hiki zinadhibitiwa nje ya Chrome. <ph name="BEGIN_LINK" />Pata maelezo zaidi<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Fresh</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, bonyeza kifufe cha Tab, kisha Enter ili uendelee na ziara yako na uone shughuli muhimu katika historia yako kwenye Chrome</translation> <translation id="9119042192571987207">Imepakiwa</translation> <translation id="9128016270925453879">Sera zimepakiwa</translation> <translation id="9128870381267983090">Unganisha kwenye mtandao</translation> diff --git a/components/strings/components_strings_te.xtb b/components/strings/components_strings_te.xtb index ed12a335c57d37..b71b3bde26ef13 100644 --- a/components/strings/components_strings_te.xtb +++ b/components/strings/components_strings_te.xtb @@ -523,7 +523,7 @@ <translation id="2880660355386638022">విండో స్థలం</translation> <translation id="2881276955470682203">కార్డ్ను సేవ్ చేయాలా?</translation> <translation id="2882949212241984732">డబుల్-గేట్ ఫోల్డ్</translation> -<translation id="2903493209154104877">చిరునామాలు</translation> +<translation id="2903493209154104877">అడ్రస్లు</translation> <translation id="290376772003165898">పేజీ <ph name="LANGUAGE" />లో లేదా?</translation> <translation id="2909946352844186028">నెట్వర్క్ మార్పు గుర్తించబడింది.</translation> <translation id="2911973620368911614">జాబ్ అకౌంటింగ్ యూజర్ ID</translation> diff --git a/components/strings/components_strings_th.xtb b/components/strings/components_strings_th.xtb index 41364113eab6de..a43ed20bd513a1 100644 --- a/components/strings/components_strings_th.xtb +++ b/components/strings/components_strings_th.xtb @@ -727,6 +727,7 @@ <translation id="3631244953324577188">ข้อมูลไบโอเมตริก</translation> <translation id="3633738897356909127">ปุ่มอัปเดต Chrome กด Enter เพื่ออัปเดต Chrome จากการตั้งค่า Chrome</translation> <translation id="3634530185120165534">ถาด 5</translation> +<translation id="3637662659967048211">บันทึกลงในบัญชี Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">แอปพลิเคชัน:</translation> <translation id="3650584904733503804">การตรวจสอบสำเร็จ</translation> @@ -1399,6 +1400,7 @@ <translation id="6106989379647458772">หน้าเว็บที่ <ph name="PAGE" /> อาจใช้งานไม่ได้ชั่วคราวหรืออาจมีการย้ายไปยังที่อยู่เว็บใหม่อย่างถาวรแล้ว</translation> <translation id="6107012941649240045">ออกให้แก่</translation> <translation id="610911394827799129">บัญชี Google อาจมีประวัติการท่องเว็บรูปแบบอื่นๆ ที่ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">ปุ่มดำเนินการสำรวจต่อ กด Enter เพื่อดำเนินการสำรวจต่อและดูกิจกรรมที่เกี่ยวข้องในประวัติการเข้าชมใน Chrome</translation> <translation id="6116338172782435947">ดูข้อความและรูปภาพที่คัดลอกไปที่คลิปบอร์ด</translation> <translation id="6120179357481664955">จำรหัส UPI ไหม</translation> <translation id="6123290840358279103">ดูบัตรเสมือน</translation> @@ -1474,6 +1476,7 @@ <translation id="6423385022588644828">ยืนยันบัตรได้เร็วขึ้นโดยใช้ Touch ID จากนี้ไป</translation> <translation id="6425092077175753609">วัสดุ</translation> <translation id="6427730057873428458">พับทบ</translation> +<translation id="6428146287756735566">ดำเนินการสำรวจต่อเพื่อดูกิจกรรมที่เกี่ยวข้องในประวัติการเข้าชมใน Chrome</translation> <translation id="6428450836711225518">ยืนยันเบอร์โทรศัพท์</translation> <translation id="6433490469411711332">แก้ไขข้อมูลติดต่อ</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> ปฏิเสธการเชื่อมต่อ</translation> @@ -1525,6 +1528,7 @@ <translation id="6643016212128521049">ล้าง</translation> <translation id="6645291930348198241">เข้าถึงคุกกี้และข้อมูลเว็บไซต์</translation> <translation id="6646269444027925224">{COUNT,plural, =0{ไม่มี}=1{จาก 1 เว็บไซต์ (คุณจะไม่ออกจากระบบบัญชี Google)}other{จาก # เว็บไซต์ (คุณจะไม่ออกจากระบบบัญชี Google)}}</translation> +<translation id="6647197322759179819">ดำเนินการสำรวจต่อ</translation> <translation id="6648459603387803038">ผู้ดูแลระบบจะเปลี่ยนการตั้งค่าเบราว์เซอร์จากระยะไกลได้ กิจกรรมในอุปกรณ์นี้อาจมีการจัดการภายนอก Chrome ได้ด้วย</translation> <translation id="6648524591329069940">แบบอักษร Serif</translation> <translation id="6651270836885078973">จัดการโดย:</translation> @@ -2177,6 +2181,7 @@ <translation id="9114524666733003316">กำลังยืนยันบัตร…</translation> <translation id="9114581008513152754">เบราว์เซอร์นี้ไม่ได้จัดการโดยบริษัทหรือองค์กรอื่นๆ กิจกรรมในอุปกรณ์นี้อาจมีการจัดการภายนอก Chrome <ph name="BEGIN_LINK" />ดูข้อมูลเพิ่มเติม<ph name="END_LINK" /></translation> <translation id="9117930699067497412">สดชื่น</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" /> กด Tab ตามด้วย Enter เพื่อดำเนินการสำรวจต่อและดูกิจกรรมที่เกี่ยวข้องในประวัติการเข้าชมใน Chrome</translation> <translation id="9119042192571987207">อัปโหลดแล้ว</translation> <translation id="9128016270925453879">โหลดนโยบายแล้ว</translation> <translation id="9128870381267983090">เชื่อมต่อกับเครือข่าย</translation> diff --git a/components/strings/components_strings_tr.xtb b/components/strings/components_strings_tr.xtb index 5b454d1fee3194..81a3a4de7605bf 100644 --- a/components/strings/components_strings_tr.xtb +++ b/components/strings/components_strings_tr.xtb @@ -729,6 +729,7 @@ Aksi halde bu işlem gizlilik ayarlarınız tarafından engellenecek. Buna izin <translation id="3631244953324577188">Biyometri</translation> <translation id="3633738897356909127">Chrome'u güncelle düğmesi, Chrome ayarlarınızdan Chrome'u güncellemek için Enter'a basın</translation> <translation id="3634530185120165534">Tepsi 5</translation> +<translation id="3637662659967048211">Google Hesabı'na kaydedin</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Uygulama:</translation> <translation id="3650584904733503804">Doğrulama başarılı</translation> @@ -1402,6 +1403,7 @@ Aksi halde bu işlem gizlilik ayarlarınız tarafından engellenecek. Buna izin <translation id="6106989379647458772"><ph name="PAGE" /> adresindeki web sayfası geçici olarak kullanılamıyor veya kalıcı olarak yeni bir web adresine taşınmış olabilir.</translation> <translation id="6107012941649240045">Verilen:</translation> <translation id="610911394827799129">Google Hesabınızın <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> adresinde başka biçimlerde tarama geçmişi olabilir</translation> +<translation id="6113594885686374546">Yolculuğu sürdür düğmesi, yolculuğunuzu devam ettirmek ve Chrome geçmişinizdeki alakalı etkinlikleri görmek için Enter'a basın</translation> <translation id="6116338172782435947">Panoya kopyalanan metin ve resimleri görme</translation> <translation id="6120179357481664955">UPI ID'nizi hatırlıyor musunuz?</translation> <translation id="6123290840358279103">Sanal kartı görüntüle</translation> @@ -1477,6 +1479,7 @@ Aksi halde bu işlem gizlilik ayarlarınız tarafından engellenecek. Buna izin <translation id="6423385022588644828">Bundan böyle Touch ID'yi kullanarak kartlarınızı daha hızlı onaylayın</translation> <translation id="6425092077175753609">Malzeme</translation> <translation id="6427730057873428458">İki kırımlı katlama</translation> +<translation id="6428146287756735566">Chrome geçmişinizde alakalı etkinlikleri görmek için yolculuğu devam ettirin</translation> <translation id="6428450836711225518">Telefon numaranızı doğrulayın</translation> <translation id="6433490469411711332">İletişim bilgilerini düzenle</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> bağlanmayı reddetti.</translation> @@ -1528,6 +1531,7 @@ Aksi halde bu işlem gizlilik ayarlarınız tarafından engellenecek. Buna izin <translation id="6643016212128521049">Temizle</translation> <translation id="6645291930348198241">Çerezlere ve site verilerine erişmek.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Yok}=1{1 siteden (Google Hesabınızdan çıkış yapılmaz)}other{# siteden (Google Hesabınızdan çıkış yapılmaz)}}</translation> +<translation id="6647197322759179819">Yolculuğu sürdür</translation> <translation id="6648459603387803038">Yöneticiniz, tarayıcınızın kurulumunu uzaktan değiştirebilir. Bu cihazdaki etkinlikler Chrome dışında da yönetilebilir.</translation> <translation id="6648524591329069940">Serif Yazı Tipi</translation> <translation id="6651270836885078973">Yöneten:</translation> @@ -2180,6 +2184,7 @@ Ek ayrıntılar: <translation id="9114524666733003316">Kart onaylanıyor...</translation> <translation id="9114581008513152754">Bu tarayıcı bir şirket veya başka bir kuruluş tarafından yönetilmemektedir. Bu cihazdaki etkinlikler Chrome dışında yönetilebilir. <ph name="BEGIN_LINK" />Daha fazla bilgi<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Taze</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, Sekme'ye basın, ardından yolculuğunuzu devam ettirmek ve Chrome geçmişinizdeki alakalı etkinlikleri görmek için Enter'a basın</translation> <translation id="9119042192571987207">Yüklendi</translation> <translation id="9128016270925453879">Politikalar yüklendi</translation> <translation id="9128870381267983090">Ağa bağlan</translation> diff --git a/components/strings/components_strings_uk.xtb b/components/strings/components_strings_uk.xtb index bf2a01640decf1..54d6a5b3c59e45 100644 --- a/components/strings/components_strings_uk.xtb +++ b/components/strings/components_strings_uk.xtb @@ -732,6 +732,7 @@ <translation id="3631244953324577188">Біометрія</translation> <translation id="3633738897356909127">Кнопка "Оновити Chrome"; натисніть Enter, щоб оновити веб-переглядач Chrome у його налаштуваннях</translation> <translation id="3634530185120165534">Лоток 5</translation> +<translation id="3637662659967048211">Зберегти в обліковий запис Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Додаток:</translation> <translation id="3650584904733503804">Перевірку закінчено</translation> @@ -1409,6 +1410,7 @@ <translation id="6106989379647458772">Можливо, веб-сторінка <ph name="PAGE" /> тимчасово недоступна або її назавжди переміщено на нову веб-адресу.</translation> <translation id="6107012941649240045">Кому видано</translation> <translation id="610911394827799129">Історія веб-перегляду може також зберігатися у вашому обліковому записі Google на сторінці <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Кнопка "Відновити пошук"; натисніть Enter, щоб відновити пошук і переглянути релевантні дії в історії Chrome</translation> <translation id="6116338172782435947">Переглядати тексти й зображення в буфері обміну</translation> <translation id="6120179357481664955">Запам'ятати ідентифікатор UPI?</translation> <translation id="6123290840358279103">Переглянути віртуальну картку</translation> @@ -1484,6 +1486,7 @@ <translation id="6423385022588644828">Відтепер ви можете підтверджувати картки швидше за допомогою Touch ID</translation> <translation id="6425092077175753609">Матеріальний</translation> <translation id="6427730057873428458">Зігнути за типом "ворота"</translation> +<translation id="6428146287756735566">Щоб бачити релевантні дії в історії Chrome, відновіть пошук</translation> <translation id="6428450836711225518">Підтвердьте номер телефону</translation> <translation id="6433490469411711332">Змінити контактні дані</translation> <translation id="6433595998831338502">Хост <ph name="HOST_NAME" /> відхилив запит на з’єднання.</translation> @@ -1535,6 +1538,7 @@ <translation id="6643016212128521049">Очистити</translation> <translation id="6645291930348198241">Отримати доступ до файлів cookie й даних сайту.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Немає}=1{З 1 сайту (ви не вийдете з облікового запису Google)}one{З # сайту (ви не вийдете з облікового запису Google)}few{З # сайтів (ви не вийдете з облікового запису Google)}many{З # сайтів (ви не вийдете з облікового запису Google)}other{З # сайту (ви не вийдете з облікового запису Google)}}</translation> +<translation id="6647197322759179819">Відновити пошук</translation> <translation id="6648459603387803038">Адміністратор може змінити налаштування веб-переглядача віддалено. Діями на цьому пристрої можна керувати за межами Chrome.</translation> <translation id="6648524591329069940">Шрифт Serif</translation> <translation id="6651270836885078973">Керує:</translation> @@ -2187,6 +2191,7 @@ <translation id="9114524666733003316">Підтверджуються дані картки…</translation> <translation id="9114581008513152754">Цим веб-переглядачем не керує адміністратор компанії чи іншої організації. Діями на цьому пристрої можна керувати за межами Chrome. <ph name="BEGIN_LINK" />Докладніше<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Свіжий</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />; натисніть Tab, а потім – Enter, щоб відновити пошук і переглянути релевантні дії в історії Chrome</translation> <translation id="9119042192571987207">Завантажено</translation> <translation id="9128016270925453879">Правила завантажено</translation> <translation id="9128870381267983090">З'єднатися з мережею</translation> diff --git a/components/strings/components_strings_vi.xtb b/components/strings/components_strings_vi.xtb index d0f2f84e446b4b..37743e57babc8c 100644 --- a/components/strings/components_strings_vi.xtb +++ b/components/strings/components_strings_vi.xtb @@ -734,6 +734,7 @@ Nếu bạn từ chối, chế độ cài đặt quyền riêng tư của bạn <translation id="3631244953324577188">Sinh trắc học</translation> <translation id="3633738897356909127">Nút Cập nhật Chrome, nhấn phím Enter để cập nhật Chrome trong phần cài đặt của Chrome</translation> <translation id="3634530185120165534">Khay 5</translation> +<translation id="3637662659967048211">Lưu vào Tài khoản Google</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">Ứng dụng:</translation> <translation id="3650584904733503804">Xác thực thành công</translation> @@ -1411,6 +1412,7 @@ Nếu bạn từ chối, chế độ cài đặt quyền riêng tư của bạn <translation id="6106989379647458772">Trang web tại <ph name="PAGE" /> có thể tạm thời không hoạt động hoặc có thể đã được chuyển vĩnh viễn sang địa chỉ web mới.</translation> <translation id="6107012941649240045">Cấp cho</translation> <translation id="610911394827799129">Tài khoản Google của bạn có thể có các dạng lịch sử duyệt web khác tại <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> +<translation id="6113594885686374546">Nút Tiếp tục hành trình, nhấn phím Enter để tiếp tục hành trình và xem hoạt động liên quan trong nhật ký duyệt web trên Chrome</translation> <translation id="6116338172782435947">Xem văn bản và hình ảnh đã sao chép sang bảng nhớ tạm</translation> <translation id="6120179357481664955">Ghi nhớ mã nhận dạng sản phẩm duy nhất (UPI) của bạn?</translation> <translation id="6123290840358279103">Xem thẻ ảo</translation> @@ -1486,6 +1488,7 @@ Nếu bạn từ chối, chế độ cài đặt quyền riêng tư của bạn <translation id="6423385022588644828">Từ giờ trở đi, bạn có thể xác nhận các thẻ nhanh hơn bằng Touch ID</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">Gấp dạng cửa</translation> +<translation id="6428146287756735566">Tiếp tục hành trình để xem hoạt động liên quan trong nhật ký duyệt web trên Chrome</translation> <translation id="6428450836711225518">Xác minh số điện thoại của bạn</translation> <translation id="6433490469411711332">Chỉnh sửa thông tin liên hệ</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> đã từ chối kết nối.</translation> @@ -1537,6 +1540,7 @@ Nếu bạn từ chối, chế độ cài đặt quyền riêng tư của bạn <translation id="6643016212128521049">Xóa</translation> <translation id="6645291930348198241">Truy cập vào cookie và dữ liệu trang web.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Không có}=1{Của 1 trang web (bạn sẽ không bị đăng xuất khỏi Tài khoản Google của mình)}other{Của # trang web (bạn sẽ không bị đăng xuất khỏi Tài khoản Google của mình)}}</translation> +<translation id="6647197322759179819">Tiếp tục hành trình</translation> <translation id="6648459603387803038">Quản trị viên có thể thay đổi quy trình thiết lập trình duyệt của bạn từ xa. Hoạt động trên thiết bị này cũng có thể được quản lý bên ngoài Chrome.</translation> <translation id="6648524591329069940">Phông chữ Serif</translation> <translation id="6651270836885078973">Người quản lý:</translation> @@ -1676,7 +1680,7 @@ Nếu bạn từ chối, chế độ cài đặt quyền riêng tư của bạn <translation id="7217745192097460130">Dùng Touch ID để xác minh và hoàn tất việc mua hàng?</translation> <translation id="7219179957768738017">Kết nối sử dụng <ph name="SSL_VERSION" />.</translation> <translation id="7220786058474068424">Đang xử lý</translation> -<translation id="7221855153210829124">Hiển thị thông báo</translation> +<translation id="7221855153210829124">Hiện thông báo</translation> <translation id="7229659723041939809">Bạn vừa nhập mật khẩu vào một trang web lừa đảo. Chrome khuyên bạn nên kiểm tra ngay những mật khẩu bạn đã lưu cho <ph name="WEBSITE_1" />, <ph name="WEBSITE_2" />, <ph name="WEBSITE_3" /> và các trang web khác mà bạn sử dụng mật khẩu này.</translation> <translation id="7233592378249864828">In tờ xác nhận</translation> <translation id="7238585580608191973">SHA-256 Fingerprint</translation> @@ -2189,6 +2193,7 @@ Thông tin chi tiết bổ sung: <translation id="9114524666733003316">Đang xác nhận thẻ...</translation> <translation id="9114581008513152754">Không có công ty hay tổ chức nào quản lý trình duyệt này. Hoạt động trên thiết bị này có thể được quản lý ở bên ngoài Chrome. <ph name="BEGIN_LINK" />Tìm hiểu thêm<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Tươi mới</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, nhấn phím Tab rồi nhấn Enter để tiếp tục hành trình và xem hoạt động liên quan trong nhật ký duyệt web trên Chrome</translation> <translation id="9119042192571987207">Đã tải lên</translation> <translation id="9128016270925453879">Đã tải chính sách</translation> <translation id="9128870381267983090">Kết nối đến mạng</translation> diff --git a/components/strings/components_strings_zh-CN.xtb b/components/strings/components_strings_zh-CN.xtb index 7a964c46a144bc..dc4d37c38e8baa 100644 --- a/components/strings/components_strings_zh-CN.xtb +++ b/components/strings/components_strings_zh-CN.xtb @@ -724,6 +724,7 @@ <translation id="3631244953324577188">生物识别</translation> <translation id="3633738897356909127">“更新 Chrome”按钮,按 Enter 键即可前往 Chrome 设置以更新 Chrome</translation> <translation id="3634530185120165534">纸匣 5</translation> +<translation id="3637662659967048211">保存到 Google 帐号</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">应用:</translation> <translation id="3650584904733503804">验证成功</translation> @@ -1396,6 +1397,7 @@ <translation id="6106989379647458772">位于 <ph name="PAGE" /> 的网页可能暂时无法打开或已永久移至新网址。</translation> <translation id="6107012941649240045">颁发对象</translation> <translation id="610911394827799129">您的 Google 帐号在 <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> 上可能有其他形式的浏览记录</translation> +<translation id="6113594885686374546">“继续您的历程”按钮,按 Enter 键即可继续您的历程,以查看您的 Chrome 历史记录中的相关活动记录</translation> <translation id="6116338172782435947">查看复制到剪贴板的文字和图片</translation> <translation id="6120179357481664955">要记住您的 UPI ID 吗?</translation> <translation id="6123290840358279103">查看虚拟卡</translation> @@ -1470,6 +1472,7 @@ <translation id="6423385022588644828">从现在开始,您只需使用 Touch ID 便能更快速地确认银行卡</translation> <translation id="6425092077175753609">Material</translation> <translation id="6427730057873428458">关门折</translation> +<translation id="6428146287756735566">继续您的历程,以查看您的 Chrome 历史记录中的相关活动记录</translation> <translation id="6428450836711225518">验证您的手机号码</translation> <translation id="6433490469411711332">修改联系信息</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> 拒绝了我们的连接请求。</translation> @@ -1521,6 +1524,7 @@ <translation id="6643016212128521049">清除</translation> <translation id="6645291930348198241">访问 Cookie 和网站数据。</translation> <translation id="6646269444027925224">{COUNT,plural, =0{无}=1{来自 1 个网站(这不会致使您退出自己的 Google 帐号)}other{来自 # 个网站(这不会致使您退出自己的 Google 帐号)}}</translation> +<translation id="6647197322759179819">继续您的历程</translation> <translation id="6648459603387803038">您的管理员可以远程更改您的浏览器设置。此设备上的活动可能也在接受 Chrome 外部的管理。</translation> <translation id="6648524591329069940">Serif 字体</translation> <translation id="6651270836885078973">管理者:</translation> @@ -2173,6 +2177,7 @@ <translation id="9114524666733003316">正在确认信用卡…</translation> <translation id="9114581008513152754">此浏览器并未由某个公司或其他组织管理。此设备上的活动可能在接受 Chrome 外部的管理。<ph name="BEGIN_LINK" />了解详情<ph name="END_LINK" /></translation> <translation id="9117930699067497412">清新</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />,依次按 Tab 键和 Enter 键即可继续您的历程,以查看您的 Chrome 历史记录中的相关活动记录</translation> <translation id="9119042192571987207">已上传</translation> <translation id="9128016270925453879">政策已加载完毕</translation> <translation id="9128870381267983090">连接到网络</translation> diff --git a/components/strings/components_strings_zh-TW.xtb b/components/strings/components_strings_zh-TW.xtb index 5ec8d4086c1e8b..04c1c05536ee14 100644 --- a/components/strings/components_strings_zh-TW.xtb +++ b/components/strings/components_strings_zh-TW.xtb @@ -728,6 +728,7 @@ <translation id="3631244953324577188">生物特徵辨識</translation> <translation id="3633738897356909127">「更新 Chrome」按鈕,按下 Enter 鍵即可透過 Chrome 設定來更新 Chrome</translation> <translation id="3634530185120165534">紙匣 5</translation> +<translation id="3637662659967048211">儲存至 Google 帳戶</translation> <translation id="3640766068866876100">Index-4x6-Ext</translation> <translation id="3642638418806704195">應用程式:</translation> <translation id="3650584904733503804">驗證成功</translation> @@ -1400,6 +1401,7 @@ <translation id="6106989379647458772">位於 <ph name="PAGE" /> 的網頁可能暫時無法使用,或是已永久移至新的網址。</translation> <translation id="6107012941649240045">核發對象</translation> <translation id="610911394827799129">你的 Google 帳戶仍可能保留了其他類型的瀏覽記錄 (可前往 <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> 查詢)。</translation> +<translation id="6113594885686374546">「繼續歷程」按鈕;按下 Enter 鍵即可繼續歷程,查看 Chrome 歷史記錄中的相關活動</translation> <translation id="6116338172782435947">讀取已複製到剪貼簿的文字和圖片</translation> <translation id="6120179357481664955">還記得你的 UPI ID 嗎?</translation> <translation id="6123290840358279103">查看虛擬卡片</translation> @@ -1475,6 +1477,7 @@ <translation id="6423385022588644828">現在就開始使用 Touch ID,加快卡片驗證速度</translation> <translation id="6425092077175753609">質感</translation> <translation id="6427730057873428458">開門摺</translation> +<translation id="6428146287756735566">繼續歷程即可查看 Chrome 歷史記錄中的相關活動</translation> <translation id="6428450836711225518">驗證你的電話號碼</translation> <translation id="6433490469411711332">編輯聯絡資訊</translation> <translation id="6433595998831338502"><ph name="HOST_NAME" /> 拒絕連線。</translation> @@ -1526,6 +1529,7 @@ <translation id="6643016212128521049">清除</translation> <translation id="6645291930348198241">存取 Cookie 和網站資料。</translation> <translation id="6646269444027925224">{COUNT,plural, =0{無}=1{1 個網站 (你不會因此登出 Google 帳戶)}other{# 個網站 (你不會因此登出 Google 帳戶)}}</translation> +<translation id="6647197322759179819">繼續歷程</translation> <translation id="6648459603387803038">你的系統管理員可以遠端變更瀏覽器設定。這部裝置上的活動也可以透過 Chrome 以外的服務管理。</translation> <translation id="6648524591329069940">Serif 字型</translation> <translation id="6651270836885078973">管理網域/帳戶:</translation> @@ -2177,6 +2181,7 @@ <translation id="9114524666733003316">正在驗證信用卡...</translation> <translation id="9114581008513152754">這個瀏覽器未受到任何公司或其他機構管理。這部裝置上的活動可透過 Chrome 以外的服務管理。<ph name="BEGIN_LINK" />瞭解詳情<ph name="END_LINK" /></translation> <translation id="9117930699067497412">新鮮</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />;按下 Tab 鍵再按下 Enter 鍵即可繼續歷程,查看 Chrome 歷史記錄中的相關活動</translation> <translation id="9119042192571987207">已上傳</translation> <translation id="9128016270925453879">已載入政策</translation> <translation id="9128870381267983090">連線至網路</translation> diff --git a/components/strings/components_strings_zu.xtb b/components/strings/components_strings_zu.xtb index 4adfb6ff6f2da4..91fc5a6f0d63c1 100644 --- a/components/strings/components_strings_zu.xtb +++ b/components/strings/components_strings_zu.xtb @@ -731,6 +731,7 @@ Lokhu uma kungenjalo kuzovinjelwa izilungiselelo zakho zobumfihlo. Lokhu kuzovum <translation id="3631244953324577188">I-biometrics</translation> <translation id="3633738897356909127">Inkinoho yokubuyekekeza ye-Chrome, cindezela u-Enter ukuze ubuyekeze i-Chrome kusuka kumasethingi akho e-Chrome</translation> <translation id="3634530185120165534">Ithileyi elingu-5</translation> +<translation id="3637662659967048211">Londoloza ku-akhawunti ye-Google</translation> <translation id="3640766068866876100">I-Index-4x6-Ext</translation> <translation id="3642638418806704195">Uhlelo lokusebenza:</translation> <translation id="3650584904733503804">Ukuqinisekiswa kuphumelele</translation> @@ -1408,6 +1409,7 @@ Lokhu uma kungenjalo kuzovinjelwa izilungiselelo zakho zobumfihlo. Lokhu kuzovum <translation id="6106989379647458772">Ikhasi lewebhu ku-<ph name="PAGE" /> lingahle liphansi okwesikhashana noma lingahle liye unaphakathi ekheli elisha lewebhu.</translation> <translation id="6107012941649240045">Ikhishelwe ku-</translation> <translation id="610911394827799129">I-akhawunti yakho ye-Google ingaba namanye amafomu omlando wokuphequlula ku-<ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="6113594885686374546">Inkinobho yokuqhubeka, cindezela u-Enter ukuqhubeka nohambo lwakho futhi ubone umsebenzi ohambisanayo kumlando wakho we-Chrome</translation> <translation id="6116338172782435947">Bona umbhalo nezithombe ezikopishelwe kubhodi lokunamathisela</translation> <translation id="6120179357481664955">Khumbula i-UPI ID yakho?</translation> <translation id="6123290840358279103">Buka ikhadi elibonakalayo</translation> @@ -1483,6 +1485,7 @@ Lokhu uma kungenjalo kuzovinjelwa izilungiselelo zakho zobumfihlo. Lokhu kuzovum <translation id="6423385022588644828">Qinisekisa amakhadi akho ngokushesha ngokusebenzisa i-Touch ID kusuka manje</translation> <translation id="6425092077175753609">Okubalulekile</translation> <translation id="6427730057873428458">Ukugoqa kwesango</translation> +<translation id="6428146287756735566">Qhubeka nohambo ukubona umsebenzi ohambisanayo kumlando wakho we-Chrome</translation> <translation id="6428450836711225518">Iqinisekisa inombolo yakho yefoni</translation> <translation id="6433490469411711332">Hlela ulwazi loxhumana naye</translation> <translation id="6433595998831338502">I-<ph name="HOST_NAME" /> inqabe ukuxhumeka.</translation> @@ -1534,6 +1537,7 @@ Lokhu uma kungenjalo kuzovinjelwa izilungiselelo zakho zobumfihlo. Lokhu kuzovum <translation id="6643016212128521049">Sula</translation> <translation id="6645291930348198241">Finyelela amakhukhi nedatha yesayithi.</translation> <translation id="6646269444027925224">{COUNT,plural, =0{Lutho}=1{Kusukela kusayithi elingu-1 (ngeke ukhishwe ngemvume ku-akhawunti yakho ye-Google)}one{Kusukela kumasayithi angu-# (ngeke ukhishwe ngemvume ku-akhawunti yakho ye-Google)}other{Kusukela kumasayithi angu-# (ngeke ukhishwe ngemvume ku-akhawunti yakho ye-Google)}}</translation> +<translation id="6647197322759179819">Qhubeka nohambo</translation> <translation id="6648459603387803038">Umlawuli wakho angaguqula ukusethwa kwesiphequluli sakho akude. Umsebenzi kule divayisi ungaphinda aphathwe ngaphandle kwe-Chrome.</translation> <translation id="6648524591329069940">Ifonti ye-Serif</translation> <translation id="6651270836885078973">Iphethwe i-:</translation> @@ -2185,6 +2189,7 @@ Imininingwane engeziwe: <translation id="9114524666733003316">Iqinisekisa ikhadi...</translation> <translation id="9114581008513152754">Lesi siphequluli asiphethwe inkampani noma enye inhlangano. Umsebenzi kule divayisi ungaphathwa ngaphandle kwe-Chrome. <ph name="BEGIN_LINK" />Funda kabanzi<ph name="END_LINK" /></translation> <translation id="9117930699067497412">Okusha</translation> +<translation id="9118692854637641831"><ph name="HISTORY_CLUSTERS_SEARCH_FOCUSED_FRIENDLY_MATCH_TEXT" />, cindezela u-Tab, bese ucindezela u-Enter ukuqhubeka nohambo lwakho futhi ubone umsebenzi ohambisanayo kumlando wakho we-Chrome</translation> <translation id="9119042192571987207">Kulayishiwe</translation> <translation id="9128016270925453879">Izinqubomgomo zilayishiwe</translation> <translation id="9128870381267983090">Xhuma kunethiwekhi</translation> diff --git a/extensions/strings/extensions_strings_eu.xtb b/extensions/strings/extensions_strings_eu.xtb index fa3217087151bf..7e8060077f99a3 100644 --- a/extensions/strings/extensions_strings_eu.xtb +++ b/extensions/strings/extensions_strings_eu.xtb @@ -28,7 +28,7 @@ <translation id="4115165561519362854"><ph name="EXTENSION_NAME" /> luzapenaren bertsioak gutxienez <ph name="EXTENSION_VERSION" /> izatea behar du makinaren administratzaileak. Ezin da gaitu eguneratzen ez den arte (bertsio horretara edo berriago batera).</translation> <translation id="4233778200880751280">Ezin izan da "<ph name="ABOUT_PAGE" />" orria kargatu.</translation> <translation id="471800408830181311">Ezin izan da gako pribatua eman.</translation> -<translation id="4811956658694082538">Ezin izan da paketea instalatu utilitate-prozesuak huts egin duelako. Berrabiarazi Chrome eta saiatu berriro.</translation> +<translation id="4811956658694082538">Ezin izan da paketea instalatu zerbitzu-aplikazioaren prozesuak huts egin duelako. Berrabiarazi Chrome eta saiatu berriro.</translation> <translation id="4988792151665380515">Ezin izan da gako publikoa esportatu.</translation> <translation id="5026754133087629784">Web-ikuspegia: <ph name="WEBVIEW_TAG_NAME" /></translation> <translation id="5098647635849512368">Ezin da aurkitu bide absolutu bat paketatu nahi den direktoriorako.</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_am.xtb b/ios/chrome/app/strings/resources/ios_strings_am.xtb index c489f2ec278ff8..26279a1d4fee17 100644 --- a/ios/chrome/app/strings/resources/ios_strings_am.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_am.xtb @@ -492,6 +492,7 @@ Handoff እንዲሁም በSettings ውስጥ ባለው የGeneral ክፍል ላ <translation id="6059830886158432458">የእርስዎን ታሪክ እና እንቅስቃሴ እዚህ ይቆጣጠሩ</translation> <translation id="6066301408025741299">ይቅር ለማለት መታ ያድርጉ።</translation> <translation id="60829778314739003">ይቀበሉ እና ይቀጥሉ</translation> +<translation id="6084848228346514841">ትሮችን ይምረጡ</translation> <translation id="6108923351542677676">ማዋቀር በሂደት ላይ…</translation> <translation id="6119050551270742952">የአሁኑ ድረ-ገጽ ማንነት በማያሳውቅ ላይ ነው</translation> <translation id="6122191549521593678">መስመር ላይ</translation> @@ -782,6 +783,7 @@ Handoff እንዲሁም በSettings ውስጥ ባለው የGeneral ክፍል ላ <ph name="BEGIN_LINK" />የበለጠ ለመረዳት<ph name="END_LINK" /></translation> <translation id="8820817407110198400">ዕልባቶች</translation> <translation id="8840513115188359703">ከእርስዎ የGoogle መለያ ዘግተው እንዲወጡ አይደረጉም።</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} ትር}one{{count} ትሮች}other{{count} ትሮች}}</translation> <translation id="8870413625673593573">በቅርብ ጊዜ የተዘጉ</translation> <translation id="8876882697946675716">መሳሪያዎችዎን በስምረት ላይ ያቆዩዋቸው</translation> <translation id="8881801611828450202">ይህን ምስል በ<ph name="SEARCH_ENGINE" /> ውስጥ ፈልግ</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_ar.xtb b/ios/chrome/app/strings/resources/ios_strings_ar.xtb index 6636566feeaf09..517790aaaa7716 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ar.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ar.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">يمكنك التحكُّم بقصصك ونشاطك هنا.</translation> <translation id="6066301408025741299">انقر للإلغاء.</translation> <translation id="60829778314739003">قبول ومتابعة</translation> +<translation id="6084848228346514841">اختيار علامات التبويب</translation> <translation id="6108923351542677676">الإعداد قيد التقدّم…</translation> <translation id="6119050551270742952">صفحة الويب الحالية في وضع التصفح المتخفي</translation> <translation id="6122191549521593678">متصل</translation> @@ -782,6 +783,7 @@ <ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" /></translation> <translation id="8820817407110198400">الإشارات المرجعية</translation> <translation id="8840513115188359703">لن يتم تسجيل خروجك من حساب Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{علامة تبويب واحدة ({count})}zero{{count} علامة تبويب}two{علامتا تبويب ({count})}few{{count} علامات تبويب}many{{count} علامة تبويب}other{{count} علامة تبويب}}</translation> <translation id="8870413625673593573">العناصر المغلقة مؤخرًا</translation> <translation id="8876882697946675716">مواصلة مزامنة الأجهزة</translation> <translation id="8881801611828450202">البحث في <ph name="SEARCH_ENGINE" /> عن هذه الصورة</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_as.xtb b/ios/chrome/app/strings/resources/ios_strings_as.xtb index c300db9be462ad..5b2887b676e373 100644 --- a/ios/chrome/app/strings/resources/ios_strings_as.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_as.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">আপোনাৰ কাহিনীসমূহ আৰু কাৰ্যকলাপ ইয়াত নিয়ন্ত্ৰণ কৰক</translation> <translation id="6066301408025741299">বাতিল কৰিবলৈ টিপক।</translation> <translation id="60829778314739003">গ্ৰহণ কৰি অব্যাহত ৰাখক</translation> +<translation id="6084848228346514841">টেব বাছনি কৰক</translation> <translation id="6108923351542677676">ছেট আপ প্ৰক্ৰিয়া চলি আছে…</translation> <translation id="6119050551270742952">বৰ্তমানৰ ৱেবপৃষ্ঠাটো ইনক’গনিট’ত আছে</translation> <translation id="6122191549521593678">অনলাইন</translation> @@ -779,6 +780,7 @@ <ph name="BEGIN_LINK" />অধিক জানক<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Bookmarks</translation> <translation id="8840513115188359703">আপোনাক নিজৰ Google Accountৰ পৰা ছাইন আউট কৰোৱা নহয়।</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} টা টেব}one{{count} টা টেব}other{{count} টা টেব}}</translation> <translation id="8870413625673593573">শেহতীয়াকৈ বন্ধ কৰা</translation> <translation id="8876882697946675716">আপোনাৰ ডিভাইচসমূহ ছিংক কৰি ৰাখক</translation> <translation id="8881801611828450202">এই প্ৰতিচ্ছবিটোৰ কাৰণে <ph name="SEARCH_ENGINE" />ত সন্ধান কৰক</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_az.xtb b/ios/chrome/app/strings/resources/ios_strings_az.xtb index 07dd66d2a4da6c..d93385ba2a1aeb 100644 --- a/ios/chrome/app/strings/resources/ios_strings_az.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_az.xtb @@ -492,6 +492,7 @@ Handoff Ayarların Ümumi bölməsindən də aktiv edilə bilər və cihazların <translation id="6059830886158432458">Hekayələrinizi və fəaliyyətlərinizi burada idarə edin</translation> <translation id="6066301408025741299">Ləğv etmək üçün tıklayın.</translation> <translation id="60829778314739003">Qəbul edin və Davam edin</translation> +<translation id="6084848228346514841">Tablar seçin</translation> <translation id="6108923351542677676">Quraşdırma icra olunur...</translation> <translation id="6119050551270742952">Hazırkı veb səhifə anonim rejimdədir</translation> <translation id="6122191549521593678">Onlayn</translation> @@ -782,6 +783,7 @@ Saytlar müxtəlif saytlarda baxış fəaliyyətinizi görmək üçün kukilərd <ph name="BEGIN_LINK" />Ətraflı məlumat<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Əlfəcinlər</translation> <translation id="8840513115188359703">Google Hesabınızdan çıxmayacaqsınız.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} Tab}other{{count} Tab}}</translation> <translation id="8870413625673593573">Son Qapadılan</translation> <translation id="8876882697946675716">Cihazlarınızı Sinxronlaşdırın</translation> <translation id="8881801611828450202">Bu Şəkil üçün <ph name="SEARCH_ENGINE" /> Axtarışı Edin</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_be.xtb b/ios/chrome/app/strings/resources/ios_strings_be.xtb index b4809e8b01c017..190110c905c76f 100644 --- a/ios/chrome/app/strings/resources/ios_strings_be.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_be.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">Кіруйце паказам артыкулаў і гісторыяй дзеянняў тут</translation> <translation id="6066301408025741299">Каб скасаваць, націсніце тут.</translation> <translation id="60829778314739003">Прыняць і працягнуць</translation> +<translation id="6084848228346514841">Выбраць укладкі</translation> <translation id="6108923351542677676">Ідзе наладка…</translation> <translation id="6119050551270742952">Вэб-старонка адкрыта ў рэжыме інкогніта</translation> <translation id="6122191549521593678">У інтэрнэце</translation> @@ -782,6 +783,7 @@ <ph name="BEGIN_LINK" />Даведацца больш<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Закладкі</translation> <translation id="8840513115188359703">З Уліковага запісу Google вы не выйдзеце.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} укладка}one{{count} укладка}few{{count} укладкі}many{{count} укладак}other{{count} укладкі}}</translation> <translation id="8870413625673593573">Нядаўна закрытыя</translation> <translation id="8876882697946675716">Сінхранізуйце свае прылады</translation> <translation id="8881801611828450202">Шукаць гэты відарыс праз <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_bg.xtb b/ios/chrome/app/strings/resources/ios_strings_bg.xtb index ca45f5c3e25d90..7b638f953b4052 100644 --- a/ios/chrome/app/strings/resources/ios_strings_bg.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_bg.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">Управлявайте материалите и активността си тук</translation> <translation id="6066301408025741299">Докоснете, за да анулирате.</translation> <translation id="60829778314739003">Приемам и продължавам</translation> +<translation id="6084848228346514841">Избиране на раздели</translation> <translation id="6108923351542677676">Извършва се настройване…</translation> <translation id="6119050551270742952">Страницата е в режим „инкогнито“</translation> <translation id="6122191549521593678">Онлайн</translation> @@ -782,6 +783,7 @@ <ph name="BEGIN_LINK" />Научете повече<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Отметки</translation> <translation id="8840513115188359703">Няма да излезете от профила си в Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} раздел}other{{count} раздела}}</translation> <translation id="8870413625673593573">Наскоро затворени</translation> <translation id="8876882697946675716">Синхронизирайте устройствата си</translation> <translation id="8881801611828450202">Търсене на изобр. със: <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_bs.xtb b/ios/chrome/app/strings/resources/ios_strings_bs.xtb index 42068230528838..3662b935acfb60 100644 --- a/ios/chrome/app/strings/resources/ios_strings_bs.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_bs.xtb @@ -492,6 +492,7 @@ Također, Handoff mora biti omogućen u odjeljku Općenito u Postavkama, a vaši <translation id="6059830886158432458">Upravljajte pričama i aktivnostima ovdje</translation> <translation id="6066301408025741299">Dodirnite da otkažete.</translation> <translation id="60829778314739003">Prihvati i nastavi</translation> +<translation id="6084848228346514841">Odaberite kartice</translation> <translation id="6108923351542677676">U toku je postavljanje…</translation> <translation id="6119050551270742952">Trenutna web stranica je u Anonimnom načinu</translation> <translation id="6122191549521593678">Na mreži</translation> @@ -782,6 +783,7 @@ Web lokacije mogu koristiti kolačiće da vide vašu aktivnost pregledanja na ra <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Oznake</translation> <translation id="8840513115188359703">Nećete se odjaviti sa svog Google računa.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} kartica}one{{count} kartica}few{{count} kartice}other{{count} kartica}}</translation> <translation id="8870413625673593573">Nedavno zatvoreno</translation> <translation id="8876882697946675716">Kontinuirano sinhronizirajte uređaje</translation> <translation id="8881801611828450202">Pretraži <ph name="SEARCH_ENGINE" /> za ovu sliku</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_ca.xtb b/ios/chrome/app/strings/resources/ios_strings_ca.xtb index 7e3deb860fe80f..84ee7242b6f480 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ca.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ca.xtb @@ -492,6 +492,7 @@ Handoff també ha d'estar activat a la secció General de Configuració, i els v <translation id="6059830886158432458">Controla les teves històries i la teva activitat aquí</translation> <translation id="6066301408025741299">Toca per cancel·lar.</translation> <translation id="60829778314739003">Accepta i continua</translation> +<translation id="6084848228346514841">Selecciona pestanyes</translation> <translation id="6108923351542677676">Configuració en curs...</translation> <translation id="6119050551270742952">La pàgina web actual està en mode d'incògnit</translation> <translation id="6122191549521593678">En línia</translation> @@ -782,6 +783,7 @@ Els llocs web poden fer servir galetes per veure la teva activitat de navegació <ph name="BEGIN_LINK" />Més informació<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Adreces d'interès</translation> <translation id="8840513115188359703">No se us tancarà la sessió del compte de Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} pestanya}other{{count} pestanyes}}</translation> <translation id="8870413625673593573">Tancades recentment</translation> <translation id="8876882697946675716">Mantén els dispositius sincronitzats</translation> <translation id="8881801611828450202">Cerca aquesta imatge a <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_cs.xtb b/ios/chrome/app/strings/resources/ios_strings_cs.xtb index c152d26a282051..2c6abddebaa2e5 100644 --- a/ios/chrome/app/strings/resources/ios_strings_cs.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_cs.xtb @@ -492,6 +492,7 @@ Funkce Handoff musí být povolena také v Nastavení v sekci Obecné a zaříze <translation id="6059830886158432458">Zde můžete ovládat své příběhy a aktivity</translation> <translation id="6066301408025741299">Stahování zrušíte klepnutím.</translation> <translation id="60829778314739003">Přijmout a pokračovat</translation> +<translation id="6084848228346514841">Vybrat karty</translation> <translation id="6108923351542677676">Probíhá nastavování…</translation> <translation id="6119050551270742952">Webová stránka je v anonymním režimu</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ Weby pomocí souborů cookie mohou sledovat vaši aktivitu prohlížení na růz <ph name="BEGIN_LINK" />Další informace<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Záložky</translation> <translation id="8840513115188359703">Nebudete odhlášeni ze svého účtu Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} karta}few{{count} karty}many{{count} karty}other{{count} karet}}</translation> <translation id="8870413625673593573">Nedávno zavřené</translation> <translation id="8876882697946675716">Synchronizujte svá zařízení</translation> <translation id="8881801611828450202">Vyhledat tento obrázek ve službě <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_da.xtb b/ios/chrome/app/strings/resources/ios_strings_da.xtb index 96a949180c1af9..b18a14ab456a7d 100644 --- a/ios/chrome/app/strings/resources/ios_strings_da.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_da.xtb @@ -492,6 +492,7 @@ Handoff skal være aktiveret i afsnittet Generelt i Indstillinger, og dine enhed <translation id="6059830886158432458">Administrer dine historier og din aktivitet her</translation> <translation id="6066301408025741299">Tryk for at annullere.</translation> <translation id="60829778314739003">Acceptér og fortsæt</translation> +<translation id="6084848228346514841">Vælg faner</translation> <translation id="6108923351542677676">Konfigurationen er i gang...</translation> <translation id="6119050551270742952">Den aktuelle webside er i inkognitotilstand</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ Websites kan bruge cookies til at se din browseraktivitet på forskellige websit <ph name="BEGIN_LINK" />Få flere oplysninger<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Bogmærker</translation> <translation id="8840513115188359703">Du bliver ikke logget ud af din Google-konto.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} fane}one{{count} fane}other{{count} faner}}</translation> <translation id="8870413625673593573">Senest lukkede</translation> <translation id="8876882697946675716">Bevar synkroniseringen af dine enheder</translation> <translation id="8881801611828450202">Søg på <ph name="SEARCH_ENGINE" /> efter dette billede</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_el.xtb b/ios/chrome/app/strings/resources/ios_strings_el.xtb index f321bf4c15d4b2..37c3ddc72e0d9f 100644 --- a/ios/chrome/app/strings/resources/ios_strings_el.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_el.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">Ελέγξτε τις ειδήσεις και τη δραστηριότητά σας εδώ</translation> <translation id="6066301408025741299">Πατήστε για ακύρωση.</translation> <translation id="60829778314739003">Αποδοχή και συνέχεια</translation> +<translation id="6084848228346514841">Επιλογή καρτελών</translation> <translation id="6108923351542677676">Ρύθμιση σε εξέλιξη…</translation> <translation id="6119050551270742952">Ιστοσελίδα σε ανώνυμη περιήγηση</translation> <translation id="6122191549521593678">Συνδεδεμένο</translation> @@ -783,6 +784,7 @@ <ph name="BEGIN_LINK" />Μάθετε περισσότερα<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Σελιδοδείκτες</translation> <translation id="8840513115188359703">Δεν θα αποσυνδεθείτε από το Λογαριασμό σας Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} καρτέλα}other{{count} καρτέλες}}</translation> <translation id="8870413625673593573">Έκλεισαν πρόσφατα</translation> <translation id="8876882697946675716">Διατηρήστε συγχρονισμένες τις συσκευές σας</translation> <translation id="8881801611828450202">Αναζήτηση εικόνας σε <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_es-419.xtb b/ios/chrome/app/strings/resources/ios_strings_es-419.xtb index 8a16e0d939a218..1542991b997847 100644 --- a/ios/chrome/app/strings/resources/ios_strings_es-419.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_es-419.xtb @@ -492,6 +492,7 @@ Handoff también debe estar habilitado en la sección General de la configuraci <translation id="6059830886158432458">Controla tus noticias y actividad aquí</translation> <translation id="6066301408025741299">Toca para cancelar.</translation> <translation id="60829778314739003">Aceptar y continuar</translation> +<translation id="6084848228346514841">Seleccionar pestañas</translation> <translation id="6108923351542677676">Configuración en curso…</translation> <translation id="6119050551270742952">Pág. incógnito</translation> <translation id="6122191549521593678">En línea</translation> @@ -782,6 +783,7 @@ También pueden usar cookies para ver la actividad de navegación en diferentes <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Favoritos</translation> <translation id="8840513115188359703">No saldrás de tu cuenta de Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} pestaña}other{{count} pestañas}}</translation> <translation id="8870413625673593573">Cerrado recientemente</translation> <translation id="8876882697946675716">Mantén tus dispositivos sincronizados</translation> <translation id="8881801611828450202">Buscar esta imagen en <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_es.xtb b/ios/chrome/app/strings/resources/ios_strings_es.xtb index 59bbb4bc5c2169..6d9443e4f2ffd8 100644 --- a/ios/chrome/app/strings/resources/ios_strings_es.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_es.xtb @@ -492,6 +492,7 @@ Handoff también debe estar habilitado en la sección General de Configuración, <translation id="6059830886158432458">Controla tus noticias y tu actividad aquí</translation> <translation id="6066301408025741299">Toca para cancelar.</translation> <translation id="60829778314739003">Aceptar y continuar</translation> +<translation id="6084848228346514841">Seleccionar pestañas</translation> <translation id="6108923351542677676">Configuración en curso…</translation> <translation id="6119050551270742952">Sitio actual en modo incógnito</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ Los sitios pueden usar cookies para ver tu actividad de navegación en otros sit <ph name="BEGIN_LINK" />Más información<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Marcadores</translation> <translation id="8840513115188359703">No se cerrará la sesión en tu cuenta de Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} pestaña}other{{count} pestañas}}</translation> <translation id="8870413625673593573">Cerrado recientemente</translation> <translation id="8876882697946675716">Mantén tus dispositivos sincronizados</translation> <translation id="8881801611828450202">Buscar esta imagen en <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_et.xtb b/ios/chrome/app/strings/resources/ios_strings_et.xtb index 08d561f8225b17..4fae63f6a659a6 100644 --- a/ios/chrome/app/strings/resources/ios_strings_et.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_et.xtb @@ -492,6 +492,7 @@ Handoff peab olema lubatud seadete jaotises General ja seadmed peavad kasutama s <translation id="6059830886158432458">Hallake oma lugusid ja tegevusi siin</translation> <translation id="6066301408025741299">Tühistamiseks puudutage.</translation> <translation id="60829778314739003">Nõustu ja jätka</translation> +<translation id="6084848228346514841">Valige vahelehed</translation> <translation id="6108923351542677676">Seadistamine on pooleli ...</translation> <translation id="6119050551270742952">Praegune veebileht on inkognito režiimis</translation> <translation id="6122191549521593678">Onlain</translation> @@ -782,6 +783,7 @@ Saidid saavad küpsisefailide abil eri saitidel teie sirvimistegevust jälgida, <ph name="BEGIN_LINK" />Lisateave<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Järjehoidjad</translation> <translation id="8840513115188359703">Teid ei logita teie Google'i kontolt välja.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} vaheleht}other{{count} vahelehte}}</translation> <translation id="8870413625673593573">Viimati suletud</translation> <translation id="8876882697946675716">Hoidke oma seadmed sünkroonituna</translation> <translation id="8881801611828450202">Otsi pilti teenusest <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_eu.xtb b/ios/chrome/app/strings/resources/ios_strings_eu.xtb index c4b41aa0c0b114..62944d71ec4efb 100644 --- a/ios/chrome/app/strings/resources/ios_strings_eu.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_eu.xtb @@ -492,6 +492,7 @@ Ezarpena aldatzeko, <ph name="BEGIN_LINK" />berrezarri sinkronizazioa<ph name="E <translation id="6059830886158432458">Kontrolatu istorioak eta jarduerak hemen</translation> <translation id="6066301408025741299">Sakatu bertan behera uzteko</translation> <translation id="60829778314739003">Onartu eta egin aurrera</translation> +<translation id="6084848228346514841">Hautatu fitxak</translation> <translation id="6108923351542677676">Konfigurazioa abian da…</translation> <translation id="6119050551270742952">Web-orri hau ezkutuko moduan dago</translation> <translation id="6122191549521593678">Konektatu</translation> @@ -782,6 +783,7 @@ Webguneek cookieak erabil ditzakete beste webguneetan egiten dituzun arakatze-ja <ph name="BEGIN_LINK" />Lortu informazio gehiago<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Laster-markak</translation> <translation id="8840513115188359703">Ez da amaituko Google-ko kontuko saioa.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} fitxa}other{{count} fitxa}}</translation> <translation id="8870413625673593573">Itxitako azkenak</translation> <translation id="8876882697946675716">Mantendu gailuak sinkronizatuta</translation> <translation id="8881801611828450202">Bilatu irudia <ph name="SEARCH_ENGINE" /> bilatzailean</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_fa.xtb b/ios/chrome/app/strings/resources/ios_strings_fa.xtb index f7e410387bb7b5..98ec1988f46624 100644 --- a/ios/chrome/app/strings/resources/ios_strings_fa.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_fa.xtb @@ -492,6 +492,7 @@ Handoff باید در بخش عمومی تنظیمات نیز فعال شود و <translation id="6059830886158432458">داستانها و فعالیت خود را اینجا کنترل کنید</translation> <translation id="6066301408025741299">برای لغو ضربه بزنید.</translation> <translation id="60829778314739003">پذیرش و ادامه</translation> +<translation id="6084848228346514841">انتخاب برگهها</translation> <translation id="6108923351542677676">تنظیم در حال انجام است...</translation> <translation id="6119050551270742952">صفحه وب کنونی در حالت ناشناس است</translation> <translation id="6122191549521593678">آنلاین</translation> @@ -782,6 +783,7 @@ Handoff باید در بخش عمومی تنظیمات نیز فعال شود و <ph name="BEGIN_LINK" />بیشتر بدانید<ph name="END_LINK" /></translation> <translation id="8820817407110198400">نشانکها</translation> <translation id="8840513115188359703">از حساب Google خود خارج نمیشوید.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} برگه}one{{count} برگه}other{{count} برگه}}</translation> <translation id="8870413625673593573">اخیراً بستهشده</translation> <translation id="8876882697946675716">دستگاههایتان را همگام نگه دارید</translation> <translation id="8881801611828450202">جستجوی <ph name="SEARCH_ENGINE" /> برای این تصویر</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_fi.xtb b/ios/chrome/app/strings/resources/ios_strings_fi.xtb index d674f557c95e7b..a1957885f84ad6 100644 --- a/ios/chrome/app/strings/resources/ios_strings_fi.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_fi.xtb @@ -492,6 +492,7 @@ Handoff täytyy ottaa käyttöön myös Asetusten Yleiset-osiossa. Lisäksi mole <translation id="6059830886158432458">Muuta tarinoiden ja toiminnan asetuksia täällä</translation> <translation id="6066301408025741299">Peru napauttamalla.</translation> <translation id="60829778314739003">Hyväksy ja jatka</translation> +<translation id="6084848228346514841">Valitse välilehdet</translation> <translation id="6108923351542677676">Synkronointia valmistellaan…</translation> <translation id="6119050551270742952">Nykyinen verkkosivu on incognito-tilassa</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ Sivustot voivat nähdä selaustoimintaasi eri sivustoilta evästeiden kautta esi <ph name="BEGIN_LINK" />Lue lisää<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Kirjanmerkit</translation> <translation id="8840513115188359703">Sinua ei kirjata ulos Google-tililtäsi.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} välilehti}other{{count} välilehteä}}</translation> <translation id="8870413625673593573">Hiljattain suljetut</translation> <translation id="8876882697946675716">Pidä laitteesi synkronoituina</translation> <translation id="8881801611828450202">Hae kuvaa seuraavasta palvelusta: <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_fr-CA.xtb b/ios/chrome/app/strings/resources/ios_strings_fr-CA.xtb index 4ed16a93ab3e26..ef639f032041ca 100644 --- a/ios/chrome/app/strings/resources/ios_strings_fr-CA.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_fr-CA.xtb @@ -492,6 +492,7 @@ La fonction de transfert doit également être activée dans la section Généra <translation id="6059830886158432458">Gérez vos histoires et votre activité ici</translation> <translation id="6066301408025741299">Appuyez pour annuler.</translation> <translation id="60829778314739003">Accepter et continuer</translation> +<translation id="6084848228346514841">Sélectionner des onglets</translation> <translation id="6108923351542677676">Configuration en cours...</translation> <translation id="6119050551270742952">La page Web actuelle est ouverte en mode de navigation privée</translation> <translation id="6122191549521593678">En ligne</translation> @@ -782,6 +783,7 @@ Les sites peuvent utiliser des témoins afin de voir votre activité de navigati <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Favoris</translation> <translation id="8840513115188359703">Vous ne serez pas déconnecté(e) de votre compte Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} onglet}one{{count} onglets}other{{count} onglets}}</translation> <translation id="8870413625673593573">Éléments récemment fermés</translation> <translation id="8876882697946675716">Synchroniser vos appareils</translation> <translation id="8881801611828450202">Rechercher cette image avec <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_fr.xtb b/ios/chrome/app/strings/resources/ios_strings_fr.xtb index 2930287b5ff269..fd5df006225dce 100644 --- a/ios/chrome/app/strings/resources/ios_strings_fr.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_fr.xtb @@ -492,6 +492,7 @@ Handoff doit également être activé dans la section "Général" des paramètre <translation id="6059830886158432458">Contrôlez vos articles et votre activité via ce menu</translation> <translation id="6066301408025741299">Appuyez sur l'écran pour annuler.</translation> <translation id="60829778314739003">Accepter et continuer</translation> +<translation id="6084848228346514841">Sélectionner des onglets</translation> <translation id="6108923351542677676">Configuration en cours…</translation> <translation id="6119050551270742952">La page Web actuelle est en mode navigation privée</translation> <translation id="6122191549521593678">En ligne</translation> @@ -783,6 +784,7 @@ Ils peuvent également s'en servir pour voir votre activité de navigation sur l <ph name="BEGIN_LINK" />En savoir plus<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Favoris</translation> <translation id="8840513115188359703">Vous ne serez pas déconnecté de votre compte Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} onglet}one{{count} onglet}other{{count} onglets}}</translation> <translation id="8870413625673593573">Récemment fermés</translation> <translation id="8876882697946675716">Synchroniser vos appareils</translation> <translation id="8881801611828450202">Chercher cette image sur <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_gl.xtb b/ios/chrome/app/strings/resources/ios_strings_gl.xtb index 0f06e3f54d7c4e..8d1b2dae2e32b9 100644 --- a/ios/chrome/app/strings/resources/ios_strings_gl.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_gl.xtb @@ -492,6 +492,7 @@ Handoff tamén debe estar activado na sección Xeral da configuración e os teus <translation id="6059830886158432458">Controla as túas historias e a túa actividade aquí</translation> <translation id="6066301408025741299">Toca para cancelar.</translation> <translation id="60829778314739003">Aceptar e continuar</translation> +<translation id="6084848228346514841">Seleccionar pestanas</translation> <translation id="6108923351542677676">Configuración en curso…</translation> <translation id="6119050551270742952">O sitio web actual está no modo de incógnito</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ Tamén poden utilizalas para ver a túa actividade de navegación en varios siti <ph name="BEGIN_LINK" />Máis información<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Marcadores</translation> <translation id="8840513115188359703">Non se pechará sesión na túa conta de Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} pestana}other{{count} pestanas}}</translation> <translation id="8870413625673593573">Pechados recentemente</translation> <translation id="8876882697946675716">Mantén sincronizados os teus dispositivos</translation> <translation id="8881801611828450202">Buscar esta imaxe en <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_hi.xtb b/ios/chrome/app/strings/resources/ios_strings_hi.xtb index a42804fe7471a3..06ef56fa55541e 100644 --- a/ios/chrome/app/strings/resources/ios_strings_hi.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_hi.xtb @@ -492,6 +492,7 @@ Handoff को Settings के General अनुभाग में भी स <translation id="6059830886158432458">अपनी खबरों और गतिविधि को यहां नियंत्रित करें</translation> <translation id="6066301408025741299">रद्द करने के लिए टैप करें.</translation> <translation id="60829778314739003">स्वीकार करें और जारी रखें</translation> +<translation id="6084848228346514841">टैब चुनें</translation> <translation id="6108923351542677676">सेटअप प्रगति में है…</translation> <translation id="6119050551270742952">मौजूदा वेबपेज गुप्त मोड में खोला गया है</translation> <translation id="6122191549521593678">ऑनलाइन</translation> @@ -782,6 +783,7 @@ Handoff को Settings के General अनुभाग में भी स <ph name="BEGIN_LINK" />ज़्यादा जानें<ph name="END_LINK" /></translation> <translation id="8820817407110198400">बुकमार्क</translation> <translation id="8840513115188359703">आप अपने Google खाते से प्रस्थान नहीं करेंगे.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} टैब}one{{count} टैब}other{{count} टैब}}</translation> <translation id="8870413625673593573">हाल ही में बंद किए गए</translation> <translation id="8876882697946675716">अपने डिवाइसों को सिंक करके रखें</translation> <translation id="8881801611828450202">इस इमेज को <ph name="SEARCH_ENGINE" /> पर खोजें</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_hr.xtb b/ios/chrome/app/strings/resources/ios_strings_hr.xtb index 2d6317af177474..785f6ae47e9375 100644 --- a/ios/chrome/app/strings/resources/ios_strings_hr.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_hr.xtb @@ -492,6 +492,7 @@ Handoff mora biti omogućen i u odjeljku Općenito u Postavkama, a vaši uređaj <translation id="6059830886158432458">Svojim pričama i aktivnostima upravljajte ovdje</translation> <translation id="6066301408025741299">Dotaknite da biste otkazali.</translation> <translation id="60829778314739003">Prihvaćam, nastavi</translation> +<translation id="6084848228346514841">Odaberite kartice</translation> <translation id="6108923351542677676">Postavljanje je u tijeku…</translation> <translation id="6119050551270742952">Stranica u anonimnom načinu</translation> <translation id="6122191549521593678">Na mreži</translation> @@ -782,6 +783,7 @@ Web-lokacije mogu upotrebljavati kolačiće za uvid u vašu aktivnost pregledava <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Knjižne oznake</translation> <translation id="8840513115188359703">Nećete se odjaviti s Google računa.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} kartica}one{{count} kartica}few{{count} kartice}other{{count} kartica}}</translation> <translation id="8870413625673593573">Nedavno zatvoreno</translation> <translation id="8876882697946675716">Sinkronizacija uređaja</translation> <translation id="8881801611828450202">Potraži sliku na usluzi <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_hu.xtb b/ios/chrome/app/strings/resources/ios_strings_hu.xtb index 63b499747281d7..e2806efa806957 100644 --- a/ios/chrome/app/strings/resources/ios_strings_hu.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_hu.xtb @@ -492,6 +492,7 @@ Az Átadást engedélyezni kell a Beállítások általános részében is, és <translation id="6059830886158432458">Itt kezelheti a híreket és a tevékenységeket</translation> <translation id="6066301408025741299">Érintse meg a visszavonáshoz</translation> <translation id="60829778314739003">Elfogadás és folytatás</translation> +<translation id="6084848228346514841">Lapok kiválasztása</translation> <translation id="6108923351542677676">A telepítés folyamatban...</translation> <translation id="6119050551270742952">Ez a weboldal inkognitó módban van megnyitva</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ A webhelyek használhatnak cookie-kat arra, hogy megfigyeljék más webhelyekre <ph name="BEGIN_LINK" />További információ<ph name="END_LINK" />.</translation> <translation id="8820817407110198400">Könyvjelzők</translation> <translation id="8840513115188359703">A rendszer nem jelentkezteti ki Google-fiókjából.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} lap}other{{count} lap}}</translation> <translation id="8870413625673593573">Mostanában bezárt</translation> <translation id="8876882697946675716">Biztosítsa, hogy eszközei szinkronban maradjanak</translation> <translation id="8881801611828450202">Kép keresése a(z) <ph name="SEARCH_ENGINE" /> segítségével</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_hy.xtb b/ios/chrome/app/strings/resources/ios_strings_hy.xtb index 15e7e0c3334076..2681fece8dd30e 100644 --- a/ios/chrome/app/strings/resources/ios_strings_hy.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_hy.xtb @@ -492,6 +492,7 @@ Handoff-ը պետք է միացված լինի նաև Կարգավորումնե <translation id="6059830886158432458">Կառավարեք ձեր պատմություններն ու գործողություններն այստեղ</translation> <translation id="6066301408025741299">Հպեք՝ չեղարկելու համար:</translation> <translation id="60829778314739003">Ընդունել և շարունակել</translation> +<translation id="6084848228346514841">Ընտրեք ներդիրներ</translation> <translation id="6108923351542677676">Կարգավորումն ընթացքի մեջ է…</translation> <translation id="6119050551270742952">Ընթացիկ կայքէջը ինկոգնիտո ռեժիմում է բացված</translation> <translation id="6122191549521593678">Առցանց</translation> @@ -782,6 +783,7 @@ Handoff-ը պետք է միացված լինի նաև Կարգավորումնե <ph name="BEGIN_LINK" />Իմանալ ավելին<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Էջանիշներ</translation> <translation id="8840513115188359703">Դուք դուրս չեք գա ձեր Google հաշվից:</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} ներդիր}one{{count} ներդիր}other{{count} ներդիր}}</translation> <translation id="8870413625673593573">Վերջին փակվածները</translation> <translation id="8876882697946675716">Համաժամացրեք ձեր սարքերը</translation> <translation id="8881801611828450202">Որոնել այս պատկերը <ph name="SEARCH_ENGINE" />-ում</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_id.xtb b/ios/chrome/app/strings/resources/ios_strings_id.xtb index 4d241f049747c5..9c7098ad76b76b 100644 --- a/ios/chrome/app/strings/resources/ios_strings_id.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_id.xtb @@ -492,6 +492,7 @@ Handoff juga harus diaktifkan pada bagian General di Settings, dan perangkat And <translation id="6059830886158432458">Kontrol artikel dan aktivitas Anda di sini</translation> <translation id="6066301408025741299">Ketuk untuk membatalkan.</translation> <translation id="60829778314739003">Setujui dan Lanjutkan</translation> +<translation id="6084848228346514841">Pilih Tab</translation> <translation id="6108923351542677676">Penyiapan sedang berlangsung...</translation> <translation id="6119050551270742952">Halaman Web saat ini sedang dalam Mode Samaran</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ Situs dapat menggunakan cookie untuk melihat aktivitas penjelajahan Anda di berb <ph name="BEGIN_LINK" />Pelajari lebih lanjut<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Bookmark</translation> <translation id="8840513115188359703">Anda tidak akan keluar dari Akun Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} Tab}other{{count} Tab}}</translation> <translation id="8870413625673593573">Baru Saja Ditutup</translation> <translation id="8876882697946675716">Jaga Perangkat Anda Tetap Sinkron</translation> <translation id="8881801611828450202">Telusuri Gambar Ini di <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_is.xtb b/ios/chrome/app/strings/resources/ios_strings_is.xtb index 5e458f20aac8bf..e251d55c739531 100644 --- a/ios/chrome/app/strings/resources/ios_strings_is.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_is.xtb @@ -492,6 +492,7 @@ Einnig þarf að vera kveikt á Handoff í hlutanum General í Settings og tæki <translation id="6059830886158432458">Stjórnaðu sögunum þínum og virkni hér</translation> <translation id="6066301408025741299">Ýttu til að hætta við.</translation> <translation id="60829778314739003">Samþykkja og halda áfram</translation> +<translation id="6084848228346514841">Velja flipa</translation> <translation id="6108923351542677676">Uppsetning fer fram…</translation> <translation id="6119050551270742952">Opin vefsíða er í huliðsstillingu</translation> <translation id="6122191549521593678">Á netinu</translation> @@ -782,6 +783,7 @@ Vefsvæði geta notað fótspor til að sjá vafranotkun þína á mismunandi ve <ph name="BEGIN_LINK" />Frekari upplýsingar<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Bókamerki</translation> <translation id="8840513115188359703">Þú verður ekki skráð(ur) út af Google reikningnum þínum.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} flipi}one{{count} flipi}other{{count} flipar}}</translation> <translation id="8870413625673593573">Nýlega lokað</translation> <translation id="8876882697946675716">Samstilltu öll tækin þín</translation> <translation id="8881801611828450202">Leita að þessari mynd á <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_it.xtb b/ios/chrome/app/strings/resources/ios_strings_it.xtb index 386f1255f49b2c..69fb30e8eb43af 100644 --- a/ios/chrome/app/strings/resources/ios_strings_it.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_it.xtb @@ -492,6 +492,7 @@ La funzione Handoff deve anche essere attivata nella sezione Generali di Imposta <translation id="6059830886158432458">Controlla notizie e attività qui</translation> <translation id="6066301408025741299">Tocca per annullare.</translation> <translation id="60829778314739003">Accetta e continua</translation> +<translation id="6084848228346514841">Seleziona schede</translation> <translation id="6108923351542677676">Configurazione in corso…</translation> <translation id="6119050551270742952">Pagina web corrente in incognito</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ I siti possono utilizzare i cookie per conoscere la tua attività di navigazione <ph name="BEGIN_LINK" />Scopri di più<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Preferiti</translation> <translation id="8840513115188359703">Non verrai disconnesso dal tuo Account Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} scheda}other{{count} schede}}</translation> <translation id="8870413625673593573">Chiusi di recente</translation> <translation id="8876882697946675716">Mantieni sincronizzati i tuoi dispositivi</translation> <translation id="8881801611828450202">Cerca questa immagine su <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_iw.xtb b/ios/chrome/app/strings/resources/ios_strings_iw.xtb index 9848ab190dcc5b..b49670501bd918 100644 --- a/ios/chrome/app/strings/resources/ios_strings_iw.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_iw.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">כאן אפשר לנהל את הסטוריז והפעילות שלך</translation> <translation id="6066301408025741299">יש להקיש כדי לבטל.</translation> <translation id="60829778314739003">אישור והמשך</translation> +<translation id="6084848228346514841">בחירת כרטיסיות</translation> <translation id="6108923351542677676">ההגדרה מתבצעת…</translation> <translation id="6119050551270742952">דף האינטרנט הנוכחי מוצג במצב אנונימי</translation> <translation id="6122191549521593678">אונליין</translation> @@ -782,6 +783,7 @@ <ph name="BEGIN_LINK" />מידע נוסף<ph name="END_LINK" /></translation> <translation id="8820817407110198400">סימניות</translation> <translation id="8840513115188359703">פעולה זו לא תוציא אותך מחשבון Google שלך.</translation> +<translation id="8868471676553493380">{count,plural, =1{כרטיסייה אחת ({count})}two{{count} כרטיסיות}many{{count} כרטיסיות}other{{count} כרטיסיות}}</translation> <translation id="8870413625673593573">נסגרו לאחרונה</translation> <translation id="8876882697946675716">אפשר לסנכרן בין המכשירים</translation> <translation id="8881801611828450202">חיפוש התמונה הזו ב-<ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_ka.xtb b/ios/chrome/app/strings/resources/ios_strings_ka.xtb index 67025bb786188f..7baffe23e7d79f 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ka.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ka.xtb @@ -492,6 +492,7 @@ Handoff ასევე უნდა იყოს ჩართული პა <translation id="6059830886158432458">აქ შეგიძლიათ მართოთ ამბები და აქტივობა</translation> <translation id="6066301408025741299">შეეხეთ გასაუქმებლად.</translation> <translation id="60829778314739003">დათანხმება და გაგრძელება</translation> +<translation id="6084848228346514841">აირჩიეთ ჩანართები</translation> <translation id="6108923351542677676">მიმდინარეობს დაყენება…</translation> <translation id="6119050551270742952">ამჟამად გახსნილი ვებგვერდი ინკოგნიტო რეჟიმშია</translation> <translation id="6122191549521593678">ონლაინ</translation> @@ -782,6 +783,7 @@ Handoff ასევე უნდა იყოს ჩართული პა <ph name="BEGIN_LINK" />შეიტყვეთ მეტი<ph name="END_LINK" /></translation> <translation id="8820817407110198400">სანიშნეები</translation> <translation id="8840513115188359703">თქვენ არ გამოხვალთ თქვენი Google ანგარიშიდან.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} ჩანართი}other{{count} ჩანართი}}</translation> <translation id="8870413625673593573">ბოლოს დახურული</translation> <translation id="8876882697946675716">შეინარჩუნეთ მოწყობილობები სინქრონიზებულ მდგომარეობაში</translation> <translation id="8881801611828450202">ამ სურათის ძიება <ph name="SEARCH_ENGINE" />-ში</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_kk.xtb b/ios/chrome/app/strings/resources/ios_strings_kk.xtb index 807b5dd68eb216..96a9ef063017d4 100644 --- a/ios/chrome/app/strings/resources/ios_strings_kk.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_kk.xtb @@ -492,6 +492,7 @@ Handoff функциясы параметрлердің жалпы бөлімі <translation id="6059830886158432458">Жаңалықтар мен әрекеттерді осы жерде басқарыңыз.</translation> <translation id="6066301408025741299">Болдырмау үшін түртіңіз.</translation> <translation id="60829778314739003">Қабылдап, жалғастыру</translation> +<translation id="6084848228346514841">Қойындыларды таңдау</translation> <translation id="6108923351542677676">Орнатылуда…</translation> <translation id="6119050551270742952">Ағымдағы веб-бет инкогнито режимінде</translation> <translation id="6122191549521593678">Онлайн</translation> @@ -782,6 +783,7 @@ Handoff функциясы параметрлердің жалпы бөлімі <ph name="BEGIN_LINK" />Толығырақ<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Бетбелгілер</translation> <translation id="8840513115188359703">Google есептік жазбаңыздан шықпайсыз.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} қойынды}other{{count} қойынды}}</translation> <translation id="8870413625673593573">Жақында жабылған</translation> <translation id="8876882697946675716">Құрылғыларыңызды синхрондаңыз</translation> <translation id="8881801611828450202">Осы кескінді <ph name="SEARCH_ENGINE" /> ішінен іздеу</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_km.xtb b/ios/chrome/app/strings/resources/ios_strings_km.xtb index e9a0ab0cab2852..e252e9e31bc1f5 100644 --- a/ios/chrome/app/strings/resources/ios_strings_km.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_km.xtb @@ -492,6 +492,7 @@ Handoff ត្រូវបើកដំណើរការនៅក្នុងផ <translation id="6059830886158432458">គ្រប់គ្រងអត្ថបទ និងសកម្មភាពរបស់អ្នកនៅទីនេះ</translation> <translation id="6066301408025741299">ប៉ះដើម្បីបោះបង់</translation> <translation id="60829778314739003">ទទួលយក និងបន្ត</translation> +<translation id="6084848228346514841">ជ្រើសរើសផ្ទាំង</translation> <translation id="6108923351542677676">ការដំឡើងកំពុងដំណើរការ…</translation> <translation id="6119050551270742952">ទំព័របណ្ដាញបច្ចុប្បន្នស្ថិតនៅក្នុងមុខងារឯកជន</translation> <translation id="6122191549521593678">លើអ៊ីនធឺណិត</translation> @@ -782,6 +783,7 @@ Handoff ត្រូវបើកដំណើរការនៅក្នុងផ <ph name="BEGIN_LINK" />ស្វែងយល់បន្ថែម<ph name="END_LINK" /></translation> <translation id="8820817407110198400">ចំណាំ</translation> <translation id="8840513115188359703">អ្នកនឹងមិនត្រូវបាននាំចេញពីគណនី Google របស់អ្នកទេ។</translation> +<translation id="8868471676553493380">{count,plural, =1{ផ្ទាំង {count}}other{ផ្ទាំង {count}}}</translation> <translation id="8870413625673593573">បានបិទកន្លងទៅថ្មីៗ</translation> <translation id="8876882697946675716">បន្តឱ្យឧបករណ៍របស់អ្នកធ្វើសមកាលកម្ម</translation> <translation id="8881801611828450202">ស្វែងរករួបភាពនេះនៅលើ <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_kn.xtb b/ios/chrome/app/strings/resources/ios_strings_kn.xtb index d00ea59c0856a8..2345a5f8925af7 100644 --- a/ios/chrome/app/strings/resources/ios_strings_kn.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_kn.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">ನಿಮ್ಮ ಕತೆಗಳು ಮತ್ತು ಚಟುವಟಿಕೆಯನ್ನು ಇಲ್ಲಿ ನಿರ್ವಹಿಸಿ</translation> <translation id="6066301408025741299">ರದ್ದುಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ</translation> <translation id="60829778314739003">ಸಮ್ಮತಿಸಿ ಮತ್ತು ಮುಂದುವರಿಯಿರಿ</translation> +<translation id="6084848228346514841">ಟ್ಯಾಬ್ಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ</translation> <translation id="6108923351542677676">ಸೆಟಪ್ ಪ್ರಗತಿಯಲ್ಲಿದೆ...</translation> <translation id="6119050551270742952">ಪ್ರಸ್ತುತ ವೆಬ್ ಪುಟವು ಅಜ್ಞಾತ ಮೋಡ್ನಲ್ಲಿದೆ</translation> <translation id="6122191549521593678">ಆನ್ಲೈನ್</translation> @@ -782,6 +783,7 @@ <ph name="BEGIN_LINK" />ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ<ph name="END_LINK" /></translation> <translation id="8820817407110198400">ಬುಕ್ಮಾರ್ಕ್ಗಳು</translation> <translation id="8840513115188359703">ನಿಮ್ಮನ್ನು ನಿಮ್ಮ Google ಖಾತೆಯಿಂದ ಸೈನ್ ಔಟ್ ಮಾಡುವುದಿಲ್ಲ.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} ಟ್ಯಾಬ್}one{{count} ಟ್ಯಾಬ್ಗಳು}other{{count} ಟ್ಯಾಬ್ಗಳು}}</translation> <translation id="8870413625673593573">ಇತ್ತೀಚೆಗೆ ಮುಚ್ಚಿರುವುದು</translation> <translation id="8876882697946675716">ನಿಮ್ಮ ಸಾಧನಗಳನ್ನು ಸಿಂಕ್ನಲ್ಲಿ ಇರಿಸಿ</translation> <translation id="8881801611828450202">ಈ ಚಿತ್ರಕ್ಕಾಗಿ <ph name="SEARCH_ENGINE" /> ನಲ್ಲಿ ಹುಡುಕಿ</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_ko.xtb b/ios/chrome/app/strings/resources/ios_strings_ko.xtb index 78947be80d8ce8..741e4c6efe9372 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ko.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ko.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">여기에서 스토리 및 활동을 관리하세요.</translation> <translation id="6066301408025741299">취소하려면 탭하세요.</translation> <translation id="60829778314739003">동의 및 계속</translation> +<translation id="6084848228346514841">탭 선택</translation> <translation id="6108923351542677676">설정 진행 중...</translation> <translation id="6119050551270742952">현재 시크릿 모드에서 웹페이지 사용 중</translation> <translation id="6122191549521593678">온라인</translation> @@ -782,6 +783,7 @@ <ph name="BEGIN_LINK" />자세히 알아보기<ph name="END_LINK" /></translation> <translation id="8820817407110198400">북마크</translation> <translation id="8840513115188359703">Google 계정에서 로그아웃되지 않습니다.</translation> +<translation id="8868471676553493380">{count,plural, =1{탭 {count}개}other{탭 {count}개}}</translation> <translation id="8870413625673593573">최근에 닫은 탭</translation> <translation id="8876882697946675716">기기 동기화 상태 유지</translation> <translation id="8881801611828450202"><ph name="SEARCH_ENGINE" />에서 이 이미지 검색</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_ky.xtb b/ios/chrome/app/strings/resources/ios_strings_ky.xtb index 6d23ccb110b669..d5d4e80018c939 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ky.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ky.xtb @@ -492,6 +492,7 @@ Handoff Жөндөөлөрдүн жалпы бөлүмүндө да иштети <translation id="6059830886158432458">Окуяларыңызды жана аракеттериңизди бул жерден көзөмөлдөңүз</translation> <translation id="6066301408025741299">Жокко чыгаруу үчүн таптаңыз.</translation> <translation id="60829778314739003">Кабыл алуу жана улантуу</translation> +<translation id="6084848228346514841">Өтмөктөрдү тандоо</translation> <translation id="6108923351542677676">Орнотулуп жатат…</translation> <translation id="6119050551270742952">Учурдагы веб-баракча Жашыруун режимде</translation> <translation id="6122191549521593678">Онлайн</translation> @@ -782,6 +783,7 @@ Handoff Жөндөөлөрдүн жалпы бөлүмүндө да иштети <ph name="BEGIN_LINK" />Кеңири маалымат<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Кыстармалар</translation> <translation id="8840513115188359703">Google Каттоо эсебиңизден чыгарылбайсыз.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} өтмөк}other{{count} өтмөк}}</translation> <translation id="8870413625673593573">Жакында жабылган</translation> <translation id="8876882697946675716">Түзмөктөрүңүздү шайкештириңиз</translation> <translation id="8881801611828450202">Бул сүрөттү <ph name="SEARCH_ENGINE" /> издөө каражатынан издөө</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_lo.xtb b/ios/chrome/app/strings/resources/ios_strings_lo.xtb index 88461cba35fa89..188a9e21e40a1f 100644 --- a/ios/chrome/app/strings/resources/ios_strings_lo.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_lo.xtb @@ -492,6 +492,7 @@ Handoff ຍັງຕ້ອງໄດ້ເປີດໃຊ້ງາ <translation id="6059830886158432458">ຄວບຄຸມເລື່ອງລາວ ແລະ ການເຄື່ອນໄຫວຢູ່ບ່ອນນີ້</translation> <translation id="6066301408025741299">ແຕະເພື່ອຍົກເລີກ.</translation> <translation id="60829778314739003">ຍອມຮັບ ແລະ ສືບຕໍ່</translation> +<translation id="6084848228346514841">ເລືອກແຖບ</translation> <translation id="6108923351542677676">ກຳລັງດຳເນີນການຕັ້ງຄ່າ...</translation> <translation id="6119050551270742952">ໜ້າເວັບປັດຈຸບັນຢູ່ໃນໂໝດບໍ່ເປີດເຜີຍຕົວຕົນ</translation> <translation id="6122191549521593678">ອອນລາຍ</translation> @@ -782,6 +783,7 @@ Handoff ຍັງຕ້ອງໄດ້ເປີດໃຊ້ງາ <ph name="BEGIN_LINK" />ສຶກສາເພີ່ມເຕີມ<ph name="END_LINK" /></translation> <translation id="8820817407110198400">ບຸກມາກ</translation> <translation id="8840513115188359703">ທ່ານຈະບໍ່ຖືກນຳອອກຈາກລະບົບບັນຊີ Google ຂອງທ່ານ.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} ແຖບ}other{{count} ແຖບ}}</translation> <translation id="8870413625673593573">ປິດບໍ່ດົນມານີ້</translation> <translation id="8876882697946675716">ຊິ້ງຂໍ້ມູນອຸປະກອນຂອງທ່ານສະເໝີ</translation> <translation id="8881801611828450202">ຊອກຫາຮູບນີ້ໃນ <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_lt.xtb b/ios/chrome/app/strings/resources/ios_strings_lt.xtb index 1fed90a5517b13..15b60f81156426 100644 --- a/ios/chrome/app/strings/resources/ios_strings_lt.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_lt.xtb @@ -492,6 +492,7 @@ Be to, reikia įgalinti „Handoff“ nustatymų skiltyje „Bendrieji“, o įr <translation id="6059830886158432458">Čia galite valdyti savo pasakojimus ir veiklą</translation> <translation id="6066301408025741299">Palieskite, jei norite atšaukti.</translation> <translation id="60829778314739003">Sutikti ir tęsti</translation> +<translation id="6084848228346514841">Skirtukų pasirinkimas</translation> <translation id="6108923351542677676">Nustatoma…</translation> <translation id="6119050551270742952">Dabartinė svetainė atidaryta inkognito režimu</translation> <translation id="6122191549521593678">Prisijungęs</translation> @@ -782,6 +783,7 @@ Svetainės gali naudoti slapukus, kad sužinotų apie naršymo veiklą skirtingo <ph name="BEGIN_LINK" />Sužinokite daugiau<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Žymės</translation> <translation id="8840513115188359703">Nebūsite atjungti nuo „Google“ paskyros.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} skirtukas}one{{count} skirtukas}few{{count} skirtukai}many{{count} skirtuko}other{{count} skirtukų}}</translation> <translation id="8870413625673593573">Neseniai uždaryta</translation> <translation id="8876882697946675716">Įrenginių sinchronizavimas</translation> <translation id="8881801611828450202">Ieškoti „<ph name="SEARCH_ENGINE" />“ šio vaizdo</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_lv.xtb b/ios/chrome/app/strings/resources/ios_strings_lv.xtb index 5d8f8c310bd252..d7e1a3ebe01787 100644 --- a/ios/chrome/app/strings/resources/ios_strings_lv.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_lv.xtb @@ -492,6 +492,7 @@ Funkcija Handoff ir jāiespējo arī iestatījumu sadaļā General (Vispārīgi) <translation id="6059830886158432458">Šeit varat kontrolēt jums rādītos rakstus un darbības.</translation> <translation id="6066301408025741299">Pieskarieties, lai atceltu.</translation> <translation id="60829778314739003">Piekrist un turpināt</translation> +<translation id="6084848228346514841">Atlasiet cilnes</translation> <translation id="6108923351542677676">Notiek iestatīšana...</translation> <translation id="6119050551270742952">Šajā lapā esat inkognito</translation> <translation id="6122191549521593678">Tiešsaistē</translation> @@ -782,6 +783,7 @@ Vietnes drīkst izmantot sīkfailus, lai skatītu jūsu pārlūkošanas darbība <ph name="BEGIN_LINK" />Uzzināt vairāk<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Grāmatzīmes</translation> <translation id="8840513115188359703">Jūs netiksiet izrakstīts no sava Google konta.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} cilne}zero{{count} ciļņu}one{{count} cilne}other{{count} cilnes}}</translation> <translation id="8870413625673593573">Nesen aizvērtas</translation> <translation id="8876882697946675716">Sinhronizējiet savas ierīces</translation> <translation id="8881801611828450202">Meklēt šo attēlu ar <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_mk.xtb b/ios/chrome/app/strings/resources/ios_strings_mk.xtb index aedfe4c0695964..5f77429edc85c9 100644 --- a/ios/chrome/app/strings/resources/ios_strings_mk.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_mk.xtb @@ -492,6 +492,7 @@ Handoff мора да биде овозможен и во Општиот дел <translation id="6059830886158432458">Контролирајте ги сториите и активноста тука</translation> <translation id="6066301408025741299">Допри за откажување.</translation> <translation id="60829778314739003">Прифати и продолжи</translation> +<translation id="6084848228346514841">Изберете картички</translation> <translation id="6108923351542677676">Поставувањето е во тек…</translation> <translation id="6119050551270742952">Веб-страницата е во режим инкогнито</translation> <translation id="6122191549521593678">Онлајн</translation> @@ -782,6 +783,7 @@ Handoff мора да биде овозможен и во Општиот дел <ph name="BEGIN_LINK" />Дознајте повеќе<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Обележувачи</translation> <translation id="8840513115188359703">Нема да ве одјавиме од сметката на Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} картичка}one{{count} картичка}other{{count} картички}}</translation> <translation id="8870413625673593573">Неодамна затворено</translation> <translation id="8876882697946675716">Уредите нека ви бидат синхронизирани</translation> <translation id="8881801611828450202">Пребарај <ph name="SEARCH_ENGINE" /> за сликава</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_mr.xtb b/ios/chrome/app/strings/resources/ios_strings_mr.xtb index 86098f59e8eb22..03b945ed7d5b90 100644 --- a/ios/chrome/app/strings/resources/ios_strings_mr.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_mr.xtb @@ -493,6 +493,7 @@ <translation id="6059830886158432458">तुमच्या स्टोरी आणि अॅक्टिव्हिटी येथे नियंत्रित करा</translation> <translation id="6066301408025741299">रद्द करण्यासाठी टॅप करा.</translation> <translation id="60829778314739003">स्वीकारा आणि पुढे सुरू ठेवा</translation> +<translation id="6084848228346514841">टॅब निवडा</translation> <translation id="6108923351542677676">सेटअप प्रगती पथावर आहे...</translation> <translation id="6119050551270742952">सध्याचे वेबपेज गुप्त मोडमध्ये सुरू आहे</translation> <translation id="6122191549521593678">ऑनलाइन</translation> @@ -784,6 +785,7 @@ <ph name="BEGIN_LINK" />अधिक जाणून घ्या<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Bookmarks</translation> <translation id="8840513115188359703">तुम्हाला आपल्या Google खात्यामधून साइन आउट केले जाणार नाही.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} टॅब}other{{count} टॅब}}</translation> <translation id="8870413625673593573">अलीकडे बंद</translation> <translation id="8876882697946675716">तुमची डिव्हाइस सिंकमध्ये ठेवा</translation> <translation id="8881801611828450202">या इमेजसाठी <ph name="SEARCH_ENGINE" /> शोधा</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_ms.xtb b/ios/chrome/app/strings/resources/ios_strings_ms.xtb index 8b26fcfa3e9e39..d16f88afb97b7f 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ms.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ms.xtb @@ -492,6 +492,7 @@ Serah mestilah turut didayakan dalam bahagian Umum pada Tetapan dan peranti anda <translation id="6059830886158432458">Kawal cerita dan aktiviti anda di sini</translation> <translation id="6066301408025741299">Ketik untuk membatalkan.</translation> <translation id="60829778314739003">Terima dan Teruskan</translation> +<translation id="6084848228346514841">Pilih Tab</translation> <translation id="6108923351542677676">Persediaan sedang berjalan...</translation> <translation id="6119050551270742952">Halaman web semasa dalam mod Inkognito</translation> <translation id="6122191549521593678">Dalam talian</translation> @@ -782,6 +783,7 @@ Tapak boleh menggunakan kuki untuk melihat aktiviti penyemakan imbas anda merent <ph name="BEGIN_LINK" />Ketahui lebih lanjut<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Penanda buku</translation> <translation id="8840513115188359703">Anda tidak akan dilog keluar daripada Akaun Google anda.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} Tab}other{{count} Tab}}</translation> <translation id="8870413625673593573">Ditutup Baru-baru Ini</translation> <translation id="8876882697946675716">Pastikan Peranti Anda Segerak</translation> <translation id="8881801611828450202">Cari Imej Ini di <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_my.xtb b/ios/chrome/app/strings/resources/ios_strings_my.xtb index 235360f01385bc..e1dca749a2979f 100644 --- a/ios/chrome/app/strings/resources/ios_strings_my.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_my.xtb @@ -491,6 +491,7 @@ Handoff ကို ဆက်တင်များ၏ ယေဘူယျအပိ <translation id="6059830886158432458">သင့်သတင်းများနှင့် လုပ်ဆောင်ချက်ကို ဤနေရာတွင် ထိန်းချုပ်နိုင်သည်</translation> <translation id="6066301408025741299">မလုပ်တော့ပါ ထိပါ</translation> <translation id="60829778314739003">လက်ခံပြီး ရှေ့ဆက်ရန်</translation> +<translation id="6084848228346514841">တဘ်ရွေးပါ</translation> <translation id="6108923351542677676">စဖွင့် သတ်မှတ်မှု လုပ်ကိုင်…</translation> <translation id="6119050551270742952">လက်ရှိဝဘ်စာမျက်နှာကို ရုပ်ဖျက်မုဒ်တွင် ဖွင့်ထားသည်</translation> <translation id="6122191549521593678">အွန်လိုင်း</translation> @@ -781,6 +782,7 @@ Handoff ကို ဆက်တင်များ၏ ယေဘူယျအပိ <ph name="BEGIN_LINK" />ပိုမိုလေ့လာရန်<ph name="END_LINK" /></translation> <translation id="8820817407110198400">စာညှပ်များ</translation> <translation id="8840513115188359703">Google အကောင့်မှ သင်ထွက်သွားမည် မဟုတ်ပါ။</translation> +<translation id="8868471676553493380">{count,plural, =1{တဘ် {count} ခု}other{တဘ် {count} ခု}}</translation> <translation id="8870413625673593573">မကြာမီက ပိတ်ခဲ့</translation> <translation id="8876882697946675716">သင့်စက်များကို စင့်ခ်လုပ်ထားခြင်း</translation> <translation id="8881801611828450202">ဤရုပ်ပုံကို <ph name="SEARCH_ENGINE" /> တွင်ရှာရန်</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_nl.xtb b/ios/chrome/app/strings/resources/ios_strings_nl.xtb index d1292043e0eda1..5029105b2dfee4 100644 --- a/ios/chrome/app/strings/resources/ios_strings_nl.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_nl.xtb @@ -492,6 +492,7 @@ Handoff moet ook aanstaan in het gedeelte Algemeen van Instellingen en je appara <translation id="6059830886158432458">Beheer hier je artikelen en activiteiten</translation> <translation id="6066301408025741299">Tik om te annuleren.</translation> <translation id="60829778314739003">Accepteren en verder</translation> +<translation id="6084848228346514841">Tabbladen selecteren</translation> <translation id="6108923351542677676">Instellen wordt uitgevoerd...</translation> <translation id="6119050551270742952">De huidige webpagina is in de incognitomodus</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ Sites mogen cookies gebruiken om je browse-activiteit op verschillende sites te <ph name="BEGIN_LINK" />Meer informatie<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Bookmarks</translation> <translation id="8840513115188359703">Je wordt niet uitgelogd van je Google-account.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} tabblad}other{{count} tabbladen}}</translation> <translation id="8870413625673593573">Recent gesloten</translation> <translation id="8876882697946675716">Je apparaten synchroniseren</translation> <translation id="8881801611828450202">Zoeken op <ph name="SEARCH_ENGINE" /> naar deze afbeelding</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_no.xtb b/ios/chrome/app/strings/resources/ios_strings_no.xtb index d6fa732304389c..3547d4cefdf655 100644 --- a/ios/chrome/app/strings/resources/ios_strings_no.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_no.xtb @@ -492,6 +492,7 @@ Handoff må også være aktivert i Generelt-delen av Innstillinger, og enhetene <translation id="6059830886158432458">Styr nyhetssakene dine og aktiviteten din her</translation> <translation id="6066301408025741299">Trykk for å avbryte.</translation> <translation id="60829778314739003">Godta og fortsett</translation> +<translation id="6084848228346514841">Velg faner</translation> <translation id="6108923351542677676">Konfigurasjon pågår …</translation> <translation id="6119050551270742952">Den gjeldende nettsiden er på inkognito</translation> <translation id="6122191549521593678">Pålogget</translation> @@ -782,6 +783,7 @@ Nettsteder kan bruke informasjonskapsler til å se nettleseraktiviteten din på <ph name="BEGIN_LINK" />Finn ut mer<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Bokmerker</translation> <translation id="8840513115188359703">Du blir ikke logget av Google-kontoen din.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} fane}other{{count} faner}}</translation> <translation id="8870413625673593573">Nylig lukket</translation> <translation id="8876882697946675716">Hold enhetene dine synkronisert</translation> <translation id="8881801611828450202">Søk etter dette bildet i <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_pl.xtb b/ios/chrome/app/strings/resources/ios_strings_pl.xtb index 3e3d95fc0a75bb..35fc31f0968421 100644 --- a/ios/chrome/app/strings/resources/ios_strings_pl.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_pl.xtb @@ -490,6 +490,7 @@ Funkcja Handoff musi być też włączona w sekcji Ogólne w Ustawieniach, a urz <translation id="6059830886158432458">Tutaj możesz zarządzać wyświetlanymi wiadomościami i aktywnością</translation> <translation id="6066301408025741299">Kliknij, by anulować.</translation> <translation id="60829778314739003">Zaakceptuj i kontynuuj</translation> +<translation id="6084848228346514841">Wybierz karty</translation> <translation id="6108923351542677676">Trwa konfigurowanie…</translation> <translation id="6119050551270742952">Bieżąca strona jest w trybie incognito</translation> <translation id="6122191549521593678">Online</translation> @@ -780,6 +781,7 @@ Witryny mogą używać plików cookie do śledzenia Twojej aktywności związane <ph name="BEGIN_LINK" />Więcej informacji<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Zakładki</translation> <translation id="8840513115188359703">Nie spowoduje to wylogowania z konta Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} karta}few{{count} karty}many{{count} kart}other{{count} karty}}</translation> <translation id="8870413625673593573">Ostatnio zamknięte</translation> <translation id="8876882697946675716">Synchronizacja urządzeń</translation> <translation id="8881801611828450202">Szukaj tego obrazu w: <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_pt-BR.xtb b/ios/chrome/app/strings/resources/ios_strings_pt-BR.xtb index d4b4fd5356ef5b..5d26784d51b69c 100644 --- a/ios/chrome/app/strings/resources/ios_strings_pt-BR.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_pt-BR.xtb @@ -492,6 +492,7 @@ A "Transição" também deve ser ativada na seção "Geral" das configurações. <translation id="6059830886158432458">Controle suas matérias e atividade aqui</translation> <translation id="6066301408025741299">Toque para cancelar.</translation> <translation id="60829778314739003">Aceitar e continuar</translation> +<translation id="6084848228346514841">Selecionar guias</translation> <translation id="6108923351542677676">Configuração em andamento...</translation> <translation id="6119050551270742952">Esta pág. está no modo anônimo</translation> <translation id="6122191549521593678">On-line</translation> @@ -782,6 +783,7 @@ Eles também podem usar cookies para ver sua atividade de navegação em diferen <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Favoritos</translation> <translation id="8840513115188359703">Você não será desconectado da sua Conta do Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} guia}one{{count} guia}other{{count} guias}}</translation> <translation id="8870413625673593573">Fechadas recentemente</translation> <translation id="8876882697946675716">Manter os dispositivos sincronizados</translation> <translation id="8881801611828450202">Pesquisar esta imagem no <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_pt-PT.xtb b/ios/chrome/app/strings/resources/ios_strings_pt-PT.xtb index 83e0f6466f9491..4d970530538370 100644 --- a/ios/chrome/app/strings/resources/ios_strings_pt-PT.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_pt-PT.xtb @@ -492,6 +492,7 @@ A Entrega também tem de estar ativada na secção Geral das Definições e os s <translation id="6059830886158432458">Controle as suas notícias e atividade aqui.</translation> <translation id="6066301408025741299">Toque para cancelar.</translation> <translation id="60829778314739003">Aceitar e continuar</translation> +<translation id="6084848228346514841">Selecionar separadores</translation> <translation id="6108923351542677676">Configuração em curso…</translation> <translation id="6119050551270742952">Página Web atual – Nav. anónima</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ Os sites podem utilizar cookies para ver a sua atividade de navegação em difer <ph name="BEGIN_LINK" />Saiba mais<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Marcadores</translation> <translation id="8840513115188359703">A sessão na sua Conta Google não é terminada.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} separador}other{{count} separadores}}</translation> <translation id="8870413625673593573">Fechadas recentemente</translation> <translation id="8876882697946675716">Mantenha os seus dispositivos sincronizados</translation> <translation id="8881801611828450202">Pesquisar esta imagem no <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_ro.xtb b/ios/chrome/app/strings/resources/ios_strings_ro.xtb index 0bafdb9de956bd..a638dea14f1488 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ro.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ro.xtb @@ -492,6 +492,7 @@ Trebuie să activezi Handoff în secțiunea General din Setări, iar dispozitive <translation id="6059830886158432458">Gestionează subiectele și activitatea aici</translation> <translation id="6066301408025741299">Atinge pentru a anula.</translation> <translation id="60829778314739003">Accept și continui</translation> +<translation id="6084848228346514841">Selectează file</translation> <translation id="6108923351542677676">Configurare în curs...</translation> <translation id="6119050551270742952">Pagina web actuală este în modul Incognito</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ Site-urile pot folosi cookie-uri pentru a vedea activitatea ta de navigare de pe <ph name="BEGIN_LINK" />Află mai multe<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Marcaje</translation> <translation id="8840513115188359703">Nu vei fi deconectat(ă) de la Contul Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} filă}few{{count} file}other{{count} de file}}</translation> <translation id="8870413625673593573">Închise recent</translation> <translation id="8876882697946675716">Menține dispozitivele sincronizate</translation> <translation id="8881801611828450202">Caută această imagine cu <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_ru.xtb b/ios/chrome/app/strings/resources/ios_strings_ru.xtb index daff92ee8a41f0..081aab9abeab32 100644 --- a/ios/chrome/app/strings/resources/ios_strings_ru.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_ru.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">Управление рекомендациями</translation> <translation id="6066301408025741299">Нажмите, чтобы отменить загрузку</translation> <translation id="60829778314739003">Принять и продолжить</translation> +<translation id="6084848228346514841">Выберите вкладки</translation> <translation id="6108923351542677676">Настройка…</translation> <translation id="6119050551270742952">Открыто в режиме инкогнито</translation> <translation id="6122191549521593678">Онлайн</translation> @@ -782,6 +783,7 @@ <ph name="BEGIN_LINK" />Подробнее…<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Закладки</translation> <translation id="8840513115188359703">Вы останетесь в аккаунте Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} вкладка}one{{count} вкладка}few{{count} вкладки}many{{count} вкладок}other{{count} вкладки}}</translation> <translation id="8870413625673593573">Недавно закрытые</translation> <translation id="8876882697946675716">Синхронизируйте устройства</translation> <translation id="8881801611828450202">Найти это изображение в <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_sk.xtb b/ios/chrome/app/strings/resources/ios_strings_sk.xtb index 0cfff7a0ccdbab..61237cc3753b87 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sk.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sk.xtb @@ -492,6 +492,7 @@ Funkciu Handoff musíte povoliť v nastaveniach v časti Všeobecné a vaše zar <translation id="6059830886158432458">Tu ovládajte svoje príbehy aj aktivitu</translation> <translation id="6066301408025741299">Sťahovanie zrušíte klepnutím.</translation> <translation id="60829778314739003">Súhlasiť a pokračovať</translation> +<translation id="6084848228346514841">Výber kariet</translation> <translation id="6108923351542677676">Inštaluje sa...</translation> <translation id="6119050551270742952">Aktuálna webová stránka je v anonymnom režime</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ Na základe súborov cookie si môžu zobraziť vašu históriu prehliadania v <ph name="BEGIN_LINK" />Ďalšie informácie<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Záložky</translation> <translation id="8840513115188359703">Neodhlásime vás z účtu Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} karta}few{{count} karty}many{{count} Tabs}other{{count} kariet}}</translation> <translation id="8870413625673593573">Nedávno zatvorené</translation> <translation id="8876882697946675716">Udržiavajte svoje zariadenia synchronizované</translation> <translation id="8881801611828450202">Hľadať tento obrázok v službe <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_sl.xtb b/ios/chrome/app/strings/resources/ios_strings_sl.xtb index 426a37e1ed0f79..2e9409f6bf8878 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sl.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sl.xtb @@ -492,6 +492,7 @@ Handoff must also be enabled in the General section of Settings, and your device <translation id="6059830886158432458">Nadzirajte članke in dejavnost tukaj</translation> <translation id="6066301408025741299">Dotaknite se, da prekinete.</translation> <translation id="60829778314739003">Sprejmi in nadaljuj</translation> +<translation id="6084848228346514841">Izbira zavihkov</translation> <translation id="6108923351542677676">Poteka nastavitev …</translation> <translation id="6119050551270742952">Trenutna spletna stran je v anonimnem načinu</translation> <translation id="6122191549521593678">Dosegljiv</translation> @@ -782,6 +783,7 @@ Spletna mesta lahko uporabljajo piškotke za ogled dejavnosti brskanja na razli <ph name="BEGIN_LINK" />Več o tem<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Zaznamki</translation> <translation id="8840513115188359703">Iz Google Računa ne boste odjavljeni.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} zavihek}one{{count} zavihek}two{{count} zavihka}few{{count} zavihki}other{{count} zavihkov}}</translation> <translation id="8870413625673593573">Nedavno zaprto</translation> <translation id="8876882697946675716">Poskrbite za sinhroniziranost naprav</translation> <translation id="8881801611828450202">Uporabi <ph name="SEARCH_ENGINE" /> za iskanje te slike</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_sr-Latn.xtb b/ios/chrome/app/strings/resources/ios_strings_sr-Latn.xtb index 2cc4988138d5c6..b0f839768832e3 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sr-Latn.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sr-Latn.xtb @@ -492,6 +492,7 @@ Handoff treba da se omogući u odeljku General (Opšte) u meniju Settings (Pode <translation id="6059830886158432458">Ovde kontrolišite priče i aktivnosti</translation> <translation id="6066301408025741299">Dodirnite da biste otkazali.</translation> <translation id="60829778314739003">Prihvatam, nastavi</translation> +<translation id="6084848228346514841">Izaberite kartice</translation> <translation id="6108923351542677676">Podešavanje je u toku...</translation> <translation id="6119050551270742952">Aktuelna veb-stranica je u režimu bez arhiviranja</translation> <translation id="6122191549521593678">Onlajn</translation> @@ -782,6 +783,7 @@ Sajtovi mogu da koriste kolačiće da bi videli vaše aktivnosti pregledanja na <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Obeleživači</translation> <translation id="8840513115188359703">Nećemo vas odjaviti sa Google naloga.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} kartica}one{{count} kartica}few{{count} kartice}other{{count} kartica}}</translation> <translation id="8870413625673593573">Nedavno zatvoreno</translation> <translation id="8876882697946675716">Sinhronizujte uređaje</translation> <translation id="8881801611828450202">Pretraži ovu sliku u <ph name="SEARCH_ENGINE" />-u</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_sr.xtb b/ios/chrome/app/strings/resources/ios_strings_sr.xtb index a3dc186cf36c53..c36a53ebf321a7 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sr.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sr.xtb @@ -492,6 +492,7 @@ Handoff треба да се омогући у одељку General (Опште) <translation id="6059830886158432458">Овде контролишите приче и активности</translation> <translation id="6066301408025741299">Додирните да бисте отказали.</translation> <translation id="60829778314739003">Прихватам, настави</translation> +<translation id="6084848228346514841">Изаберите картице</translation> <translation id="6108923351542677676">Подешавање је у току...</translation> <translation id="6119050551270742952">Актуелна веб-страница је у режиму без архивирања</translation> <translation id="6122191549521593678">Онлајн</translation> @@ -782,6 +783,7 @@ Handoff треба да се омогући у одељку General (Опште) <ph name="BEGIN_LINK" />Сазнајте више<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Обележивачи</translation> <translation id="8840513115188359703">Нећемо вас одјавити са Google налога.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} картица}one{{count} картица}few{{count} картице}other{{count} картица}}</translation> <translation id="8870413625673593573">Недавно затворено</translation> <translation id="8876882697946675716">Синхронизујте уређаје</translation> <translation id="8881801611828450202">Претражи ову слику у <ph name="SEARCH_ENGINE" />-у</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_sv.xtb b/ios/chrome/app/strings/resources/ios_strings_sv.xtb index 770278fe77023f..726e240f69ee22 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sv.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sv.xtb @@ -492,6 +492,7 @@ Du måste även aktivera Handoff i avsnittet Allmänt i inställningarna och sam <translation id="6059830886158432458">Styr dina berättelser och din aktivitet här</translation> <translation id="6066301408025741299">Avbryt genom att trycka här.</translation> <translation id="60829778314739003">Godkänn och fortsätt</translation> +<translation id="6084848228346514841">Välj flikar</translation> <translation id="6108923351542677676">Konfigurationen pågår ...</translation> <translation id="6119050551270742952">Webbsidan är i inkognitoläge</translation> <translation id="6122191549521593678">Online</translation> @@ -782,6 +783,7 @@ Webbplatser får se din webbaktivitet på olika webbplatser med hjälp av cookie <ph name="BEGIN_LINK" />Läs mer<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Bokmärken</translation> <translation id="8840513115188359703">Du loggas inte ut från Google-kontot.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} flik}other{{count} flikar}}</translation> <translation id="8870413625673593573">Nyligen stängda</translation> <translation id="8876882697946675716">Håll dina enheter synkroniserade</translation> <translation id="8881801611828450202">Sök på <ph name="SEARCH_ENGINE" /> efter denna bild</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_sw.xtb b/ios/chrome/app/strings/resources/ios_strings_sw.xtb index 92ebe5154aafef..e7229004d6e09a 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sw.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sw.xtb @@ -492,6 +492,7 @@ Lazima Handoff iwashwe pia katika sehemu ya Jumla ya Mipangilio, na lazima vifaa <translation id="6059830886158432458">Dhibiti hadithi na shughuli zako hapa</translation> <translation id="6066301408025741299">Gusa ili kughairi.</translation> <translation id="60829778314739003">Kubali na Uendelee</translation> +<translation id="6084848228346514841">Chagua Vichupo</translation> <translation id="6108923351542677676">Usanidi unaendelea...</translation> <translation id="6119050551270742952">Ukurasa wa sasa wa Wavuti uko katika Hali Fiche</translation> <translation id="6122191549521593678">Mtandaoni</translation> @@ -782,6 +783,7 @@ Tovuti zinaweza kutumia vidakuzi kuona shughuli zako za kuvinjari kwenye tovuti <ph name="BEGIN_LINK" />Pata maelezo zaidi<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Alamisho</translation> <translation id="8840513115188359703">Hutaondolewa katika Akaunti yako ya Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{Kichupo {count}}other{Vichupo {count}}}</translation> <translation id="8870413625673593573">Zilizofungwa Hivi Karibuni</translation> <translation id="8876882697946675716">Hakikisha Vifaa Vyako Vinasawazishwa</translation> <translation id="8881801611828450202">Tafuta Picha Hii kwenye <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_te.xtb b/ios/chrome/app/strings/resources/ios_strings_te.xtb index 648362138d2e24..dc4952b56f607d 100644 --- a/ios/chrome/app/strings/resources/ios_strings_te.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_te.xtb @@ -286,7 +286,7 @@ <translation id="3915450441834151894">సైట్ సమాచారం</translation> <translation id="3922310737605261887">కాపీ చేసిన వచనం కోసం వెతకండి</translation> <translation id="3928666092801078803">నా డేటాను కలపండి</translation> -<translation id="3929457972718048006">చిరునామాలు</translation> +<translation id="3929457972718048006">అడ్రస్లు</translation> <translation id="3943492037546055397">పాస్వర్డ్లు</translation> <translation id="3967822245660637423">డౌన్లోడ్ పూర్తయింది</translation> <translation id="3968505803272650567">ఆసక్తులను మేనేజ్ చేయండి</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_th.xtb b/ios/chrome/app/strings/resources/ios_strings_th.xtb index ac049d8d04b21d..78b56bf5b081dc 100644 --- a/ios/chrome/app/strings/resources/ios_strings_th.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_th.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">ควบคุมเรื่องราวและกิจกรรมของคุณได้ที่นี่</translation> <translation id="6066301408025741299">แตะเพื่อยกเลิก</translation> <translation id="60829778314739003">ยอมรับและดำเนินการต่อ</translation> +<translation id="6084848228346514841">เลือกแท็บ</translation> <translation id="6108923351542677676">กำลังดำเนินการตั้งค่า…</translation> <translation id="6119050551270742952">หน้าเว็บนี้อยู่ในโหมดไม่ระบุตัวตน</translation> <translation id="6122191549521593678">ออนไลน์</translation> @@ -782,6 +783,7 @@ <ph name="BEGIN_LINK" />ดูข้อมูลเพิ่มเติม<ph name="END_LINK" /></translation> <translation id="8820817407110198400">บุ๊กมาร์ก</translation> <translation id="8840513115188359703">คุณจะไม่ออกจากระบบบัญชี Google</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} แท็บ}other{{count} แท็บ}}</translation> <translation id="8870413625673593573">เพิ่งปิด</translation> <translation id="8876882697946675716">ซิงค์อุปกรณ์อยู่เสมอ</translation> <translation id="8881801611828450202">ค้นหาภาพนี้ใน <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_tr.xtb b/ios/chrome/app/strings/resources/ios_strings_tr.xtb index f6958efe2b0840..f6ba1477d60baa 100644 --- a/ios/chrome/app/strings/resources/ios_strings_tr.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_tr.xtb @@ -492,6 +492,7 @@ Handoff'un ayrıca, Ayarlar'ın Genel bölümünde de etkinleştirilmesi ve ciha <translation id="6059830886158432458">Haberlerinizi ve aktivitenizi buradan yönetin</translation> <translation id="6066301408025741299">İptal etmek için hafifçe vurun.</translation> <translation id="60829778314739003">Kabul Et ve Devam Et</translation> +<translation id="6084848228346514841">Sekme Seçin</translation> <translation id="6108923351542677676">Kurulum devam ediyor…</translation> <translation id="6119050551270742952">Geçerli Web sayfası Gizli modda</translation> <translation id="6122191549521593678">Çevrimiçi</translation> @@ -782,6 +783,7 @@ Siteler, örneğin reklamları kişiselleştirmek amacıyla farklı sitelerde ta <ph name="BEGIN_LINK" />Daha fazla bilgi<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Yer işaretleri</translation> <translation id="8840513115188359703">Google Hesaplarınızdaki oturumlarınız kapatılmaz.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} Sekme}other{{count} Sekme}}</translation> <translation id="8870413625673593573">Son Kapatılan</translation> <translation id="8876882697946675716">Cihazlarınızı Senkronize Durumda Tutun</translation> <translation id="8881801611828450202">Bu Resmi <ph name="SEARCH_ENGINE" /> Üzerinde Ara</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_uk.xtb b/ios/chrome/app/strings/resources/ios_strings_uk.xtb index 38a196222b2271..e78408a06965dd 100644 --- a/ios/chrome/app/strings/resources/ios_strings_uk.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_uk.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">Керуйте новинами й діями тут</translation> <translation id="6066301408025741299">Торкніться, щоб скасувати.</translation> <translation id="60829778314739003">Прийняти та продовжити</translation> +<translation id="6084848228346514841">Виберіть вкладки</translation> <translation id="6108923351542677676">Виконується налаштування…</translation> <translation id="6119050551270742952">Поточна сторінка в анонімному режимі</translation> <translation id="6122191549521593678">Онлайн</translation> @@ -782,6 +783,7 @@ <ph name="BEGIN_LINK" />Докладніше<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Закладки</translation> <translation id="8840513115188359703">Ви не вийдете з облікового запису Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} вкладка}one{{count} вкладка}few{{count} вкладки}many{{count} вкладок}other{{count} вкладки}}</translation> <translation id="8870413625673593573">Нещодавно закриті</translation> <translation id="8876882697946675716">Синхронізуйте свої пристрої</translation> <translation id="8881801611828450202">Пошук цього зображення в <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_vi.xtb b/ios/chrome/app/strings/resources/ios_strings_vi.xtb index c99e0d21eb5ea5..0edf02c1d0c39b 100644 --- a/ios/chrome/app/strings/resources/ios_strings_vi.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_vi.xtb @@ -492,6 +492,7 @@ Dữ liệu của bạn đã được mã hóa bằng cụm mật khẩu đồng <translation id="6059830886158432458">Kiểm soát tin bài và hoạt động của bạn tại đây</translation> <translation id="6066301408025741299">Nhấn để hủy.</translation> <translation id="60829778314739003">Đồng ý và tiếp tục</translation> +<translation id="6084848228346514841">Chọn các thẻ</translation> <translation id="6108923351542677676">Đang thiết lập…</translation> <translation id="6119050551270742952">Trang web hiện tại đang ở chế độ ẩn danh</translation> <translation id="6122191549521593678">Trực tuyến</translation> @@ -782,6 +783,7 @@ Các trang web có thể dùng cookie để giám sát hoạt động duyệt we <ph name="BEGIN_LINK" />Tìm hiểu thêm<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Dấu trang</translation> <translation id="8840513115188359703">Bạn sẽ không được đăng xuất khỏi Tài khoản Google của mình.</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} thẻ}other{{count} thẻ}}</translation> <translation id="8870413625673593573">Các thẻ đã Đóng gần đây</translation> <translation id="8876882697946675716">Đồng bộ hóa các thiết bị của bạn</translation> <translation id="8881801611828450202">Tìm hình ảnh này trên <ph name="SEARCH_ENGINE" /></translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_zh-CN.xtb b/ios/chrome/app/strings/resources/ios_strings_zh-CN.xtb index 0484359571d296..dd326cf19654e9 100644 --- a/ios/chrome/app/strings/resources/ios_strings_zh-CN.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_zh-CN.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">在此处控制您的报道和活动</translation> <translation id="6066301408025741299">点按可取消。</translation> <translation id="60829778314739003">接受并继续</translation> +<translation id="6084848228346514841">选择标签页</translation> <translation id="6108923351542677676">正在设置…</translation> <translation id="6119050551270742952">当前网页处于无痕模式</translation> <translation id="6122191549521593678">在线</translation> @@ -782,6 +783,7 @@ <ph name="BEGIN_LINK" />了解详情<ph name="END_LINK" /></translation> <translation id="8820817407110198400">书签</translation> <translation id="8840513115188359703">您不会因此而退出自己的 Google 帐号。</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} 个标签页}other{{count} 个标签页}}</translation> <translation id="8870413625673593573">最近关闭的标签页</translation> <translation id="8876882697946675716">让您的各部设备保持同步</translation> <translation id="8881801611828450202">在 <ph name="SEARCH_ENGINE" /> 中搜索此图片</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_zh-TW.xtb b/ios/chrome/app/strings/resources/ios_strings_zh-TW.xtb index 02dd9fac592069..aa5c298ab38455 100644 --- a/ios/chrome/app/strings/resources/ios_strings_zh-TW.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_zh-TW.xtb @@ -492,6 +492,7 @@ <translation id="6059830886158432458">請在這裡控管你的報導和活動</translation> <translation id="6066301408025741299">輕觸即可取消。</translation> <translation id="60829778314739003">接受並繼續</translation> +<translation id="6084848228346514841">選取分頁</translation> <translation id="6108923351542677676">設定中…</translation> <translation id="6119050551270742952">目前的網頁處於無痕模式</translation> <translation id="6122191549521593678">線上</translation> @@ -782,6 +783,7 @@ <ph name="BEGIN_LINK" />瞭解詳情<ph name="END_LINK" /></translation> <translation id="8820817407110198400">書籤</translation> <translation id="8840513115188359703">您不會因此登出 Google 帳戶。</translation> +<translation id="8868471676553493380">{count,plural, =1{{count} 個分頁}other{{count} 個分頁}}</translation> <translation id="8870413625673593573">最近關閉的分頁</translation> <translation id="8876882697946675716">讓你的裝置保持同步</translation> <translation id="8881801611828450202">透過 <ph name="SEARCH_ENGINE" /> 搜尋這張圖片</translation> diff --git a/ios/chrome/app/strings/resources/ios_strings_zu.xtb b/ios/chrome/app/strings/resources/ios_strings_zu.xtb index e55895b6d09b84..9515d8fdfb03f2 100644 --- a/ios/chrome/app/strings/resources/ios_strings_zu.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_zu.xtb @@ -492,6 +492,7 @@ I-Handoff futhi kufanele inikwe amandla esigabeni sokuvamile zezilungiselelo, fu <translation id="6059830886158432458">Lawula izindaba nomsebenzi wakho lapha</translation> <translation id="6066301408025741299">Thepha ukuze ukhansele.</translation> <translation id="60829778314739003">Yamukela futhi Uqhubeke</translation> +<translation id="6084848228346514841">Khetha amathebhu</translation> <translation id="6108923351542677676">Ukusetha kuyaqhubeka…</translation> <translation id="6119050551270742952">Ikhasi lewebhu lamanje liku-Incognito</translation> <translation id="6122191549521593678">Ku-inthanethi</translation> @@ -782,6 +783,7 @@ Amasayithi angasebenzisa amakhukhi ukubona umsebenzi wakho wokuphequlula kumasay <ph name="BEGIN_LINK" />Funda kabanzi<ph name="END_LINK" /></translation> <translation id="8820817407110198400">Amabhukhimakhi</translation> <translation id="8840513115188359703">Ngeke uze ukhishwe ngemvume ku-Akhawunti yakho ye-Google.</translation> +<translation id="8868471676553493380">{count,plural, =1{Ithebhu engu-{count}}one{Amathebhu angu-{count}}other{Amathebhu angu-{count}}}</translation> <translation id="8870413625673593573">Okuvalwe kamuva</translation> <translation id="8876882697946675716">Gcina Amadivayisi Akho Ekuvumelaniseni</translation> <translation id="8881801611828450202">Sesha i-<ph name="SEARCH_ENGINE" /> yalesi sithombe</translation> diff --git a/remoting/resources/remoting_strings_eu.xtb b/remoting/resources/remoting_strings_eu.xtb index 3f9d53dde8f875..6aba458d6ba2bf 100644 --- a/remoting/resources/remoting_strings_eu.xtb +++ b/remoting/resources/remoting_strings_eu.xtb @@ -65,7 +65,7 @@ Baimen hori emateko, sakatu beheko "<ph name="BUTTON_NAME" />" botoia pantailare <translation id="4145029455188493639"><ph name="EMAIL_ADDRESS" /> gisa hasi duzu saioa.</translation> <translation id="4155497795971509630">Beharrezko osagai batzuk falta dira. Ziurtatu softwarearen azken bertsioa instalatuta daukazula eta saiatu berriro.</translation> <translation id="4176825807642096119">Sarbide-kodea</translation> -<translation id="4227991223508142681">Ostalaria hornitzeko funtzioa</translation> +<translation id="4227991223508142681">Ostalaria hornitzeko zerbitzu-aplikazioa</translation> <translation id="4240294130679914010">Chromoting ostalariaren desinstalatzailea</translation> <translation id="4277736576214464567">Sarbide-kodeak ez du balio. Saiatu berriro.</translation> <translation id="4281844954008187215">Zerbitzu-baldintzak</translation> From d76a6ad8344185665158029d2ffd223bf1f65794 Mon Sep 17 00:00:00 2001 From: Maksim Sisov <msisov@igalia.com> Date: Tue, 1 Jun 2021 10:26:25 +0000 Subject: [PATCH 33/81] ozone/wayland: fix GetAcceleratedWidgetAtScreenPoint when scale > 1 GetAcceleratedWidgetAtScreenPoint gets screen point, which is in DIP. Thus, it must be compared against bounds of windows in screen coordinates as well. Bug: 1214212 Change-Id: I49825201c6e039c9592dc57c11333104f3217ad1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2923205 Commit-Queue: Maksim Sisov <msisov@igalia.com> Reviewed-by: Nick Yamane <nickdiego@igalia.com> Cr-Commit-Position: refs/heads/master@{#887910} --- .../platform/wayland/host/wayland_screen.cc | 2 +- .../wayland/host/wayland_screen_unittest.cc | 35 ++++++++++++++++--- .../platform/wayland/host/wayland_window.cc | 4 +++ .../platform/wayland/host/wayland_window.h | 3 ++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/ui/ozone/platform/wayland/host/wayland_screen.cc b/ui/ozone/platform/wayland/host/wayland_screen.cc index e29a5eb5a2e729..73dc4637872e1e 100644 --- a/ui/ozone/platform/wayland/host/wayland_screen.cc +++ b/ui/ozone/platform/wayland/host/wayland_screen.cc @@ -209,7 +209,7 @@ gfx::AcceleratedWidget WaylandScreen::GetAcceleratedWidgetAtScreenPoint( // point or not. auto* window = connection_->wayland_window_manager()->GetCurrentFocusedWindow(); - if (window && window->GetBounds().Contains(point)) + if (window && window->GetBoundsInDIP().Contains(point)) return window->GetWidget(); return gfx::kNullAcceleratedWidget; } diff --git a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc index 1bfb72e76109ec..3ff6033165c1f4 100644 --- a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc @@ -10,6 +10,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/display_observer.h" #include "ui/display/display_switches.h" +#include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/native_widget_types.h" #include "ui/ozone/platform/wayland/host/wayland_connection.h" @@ -246,6 +247,14 @@ TEST_P(WaylandScreenTest, OutputPropertyChanges) { } TEST_P(WaylandScreenTest, GetAcceleratedWidgetAtScreenPoint) { + // Now, send enter event for the surface, which was created before. + wl::MockSurface* surface = server_.GetObject<wl::MockSurface>( + window_->root_surface()->GetSurfaceId()); + ASSERT_TRUE(surface); + wl_surface_send_enter(surface->resource(), output_->resource()); + + Sync(); + // If there is no focused window (focus is set whenever a pointer enters any // of the windows), there must be kNullAcceleratedWidget returned. There is no // real way to determine what window is located on a certain screen point in @@ -268,11 +277,13 @@ TEST_P(WaylandScreenTest, GetAcceleratedWidgetAtScreenPoint) { EXPECT_EQ(widget_at_screen_point, gfx::kNullAcceleratedWidget); MockPlatformWindowDelegate delegate; + auto menu_window_bounds = + gfx::Rect(window_->GetBounds().width() - 10, + window_->GetBounds().height() - 10, 100, 100); std::unique_ptr<WaylandWindow> menu_window = - CreateWaylandWindowWithProperties( - gfx::Rect(window_->GetBounds().width() - 10, - window_->GetBounds().height() - 10, 100, 100), - PlatformWindowType::kMenu, window_->GetWidget(), &delegate); + CreateWaylandWindowWithProperties(menu_window_bounds, + PlatformWindowType::kMenu, + window_->GetWidget(), &delegate); Sync(); @@ -296,6 +307,22 @@ TEST_P(WaylandScreenTest, GetAcceleratedWidgetAtScreenPoint) { // Reset the focus to avoid crash on dtor as long as there is no real pointer // object. window_->SetPointerFocus(false); + + // Part 2: test that the window is found when display's scale changes. + // Update scale. + output_->SetScale(2); + output_->Flush(); + + Sync(); + + auto menu_bounds_px = menu_window->GetBounds(); + // Translate the point to dip. + auto point_in_screen = + gfx::ScaleToRoundedPoint(menu_bounds_px.origin(), 1.f / 2); + menu_window->SetPointerFocus(true); + widget_at_screen_point = + platform_screen_->GetAcceleratedWidgetAtScreenPoint(point_in_screen); + EXPECT_EQ(widget_at_screen_point, menu_window->GetWidget()); } TEST_P(WaylandScreenTest, GetLocalProcessWidgetAtPoint) { diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc index 58bcf94a4b1e78..fc87907ca15fc1 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_window.cc @@ -264,6 +264,10 @@ gfx::Rect WaylandWindow::GetBounds() const { return bounds_px_; } +gfx::Rect WaylandWindow::GetBoundsInDIP() const { + return gfx::ScaleToRoundedRect(bounds_px_, 1.0 / buffer_scale()); +} + void WaylandWindow::SetTitle(const std::u16string& title) {} void WaylandWindow::SetCapture() { diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h index deaa271864cee5..21dfcca559e05c 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.h +++ b/ui/ozone/platform/wayland/host/wayland_window.h @@ -225,6 +225,9 @@ class WaylandWindow : public PlatformWindow, return ui_task_runner_; } + // Returns bounds in DIP. + gfx::Rect GetBoundsInDIP() const; + protected: WaylandWindow(PlatformWindowDelegate* delegate, WaylandConnection* connection); From 42ffc448ea9bebc968d13d1babe07c4c3e78233f Mon Sep 17 00:00:00 2001 From: Wei Lee <wtlee@google.com> Date: Tue, 1 Jun 2021 10:28:51 +0000 Subject: [PATCH 34/81] CCA: Don't play animation for spoken-only toast messages There is a known issue that sometimes visual toast message will be shown twice if a spoken-only toast message is sent at the same time. This CL fixes this issue. Bug: b:184583382, b:172341285, b:172214187 Test: Manually Change-Id: Ia681a944a291ca0c9c6d18371af91cc838657359 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2930098 Commit-Queue: Wei Lee <wtlee@chromium.org> Commit-Queue: Shik Chen <shik@chromium.org> Auto-Submit: Wei Lee <wtlee@chromium.org> Reviewed-by: Shik Chen <shik@chromium.org> Cr-Commit-Position: refs/heads/master@{#887911} --- chromeos/components/camera_app_ui/resources/js/toast.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/chromeos/components/camera_app_ui/resources/js/toast.js b/chromeos/components/camera_app_ui/resources/js/toast.js index 31d8bd8074b5fc..cd7f9fbf96da0e 100644 --- a/chromeos/components/camera_app_ui/resources/js/toast.js +++ b/chromeos/components/camera_app_ui/resources/js/toast.js @@ -19,7 +19,9 @@ function update(message, spoken) { element.textContent = message; element.classList.toggle('spoken', spoken); - animate.play(element); + if (!spoken) { + animate.play(element); + } } /** From ba18275e849a2190896ce0b53b3d48fb011a2b16 Mon Sep 17 00:00:00 2001 From: Richard Knoll <knollr@chromium.org> Date: Tue, 1 Jun 2021 10:49:55 +0000 Subject: [PATCH 35/81] Track container view location for DialogOverlay This starts tracking the location of the container view on WebLayer and updates the location of the DialogOverlay accordingly. This is required on WebLayer to make sure videos move to the correct location when WebLayer itself is moved inside the embedding app. Bug: 1131017 Change-Id: Ie838843dcabef2e25d5c9f817c657dcc0db4887e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2911419 Commit-Queue: Richard Knoll <knollr@chromium.org> Reviewed-by: John Abd-El-Malek <jam@chromium.org> Reviewed-by: Bo <boliu@chromium.org> Reviewed-by: Frank Liberato <liberato@chromium.org> Cr-Commit-Position: refs/heads/master@{#887912} --- .../browser/android/dialog_overlay_impl.cc | 46 +++++++++++++++-- content/browser/android/dialog_overlay_impl.h | 13 ++++- .../androidoverlay/DialogOverlayImpl.java | 49 ++++++++++++++++++- .../public/browser/content_browser_client.cc | 5 ++ .../public/browser/content_browser_client.h | 6 +++ .../browser/content_browser_client_impl.cc | 8 +++ .../browser/content_browser_client_impl.h | 1 + 7 files changed, 121 insertions(+), 7 deletions(-) diff --git a/content/browser/android/dialog_overlay_impl.cc b/content/browser/android/dialog_overlay_impl.cc index 54490eb6815b88..d221038b72d5b5 100644 --- a/content/browser/android/dialog_overlay_impl.cc +++ b/content/browser/android/dialog_overlay_impl.cc @@ -10,7 +10,9 @@ #include "content/public/android/content_jni_headers/DialogOverlayImpl_jni.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/content_browser_client.h" #include "content/public/browser/web_contents_delegate.h" +#include "content/public/common/content_client.h" #include "gpu/ipc/common/gpu_surface_tracker.h" #include "media/mojo/mojom/android_overlay.mojom.h" #include "mojo/public/cpp/bindings/sync_call_restrictions.h" @@ -64,18 +66,25 @@ static jlong JNI_DialogOverlayImpl_Init(JNIEnv* env, if (power_efficient && !web_contents_impl->IsFullscreen()) return 0; - return reinterpret_cast<jlong>( - new DialogOverlayImpl(obj, rfhi, web_contents_impl, power_efficient)); + bool observe_container_view = + GetContentClient() + ->browser() + ->ShouldObserveContainerViewLocationForDialogOverlays(); + + return reinterpret_cast<jlong>(new DialogOverlayImpl( + obj, rfhi, web_contents_impl, power_efficient, observe_container_view)); } DialogOverlayImpl::DialogOverlayImpl(const JavaParamRef<jobject>& obj, RenderFrameHostImpl* rfhi, WebContents* web_contents, - bool power_efficient) + bool power_efficient, + bool observe_container_view) : WebContentsObserver(web_contents), rfhi_(rfhi), power_efficient_(power_efficient), - observed_window_android_(false) { + observed_window_android_(false), + observe_container_view_(observe_container_view) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(rfhi_); @@ -116,6 +125,10 @@ void DialogOverlayImpl::CompleteInit(JNIEnv* env, ScopedJavaLocalRef<jobject> token = window->GetWindowToken(); Java_DialogOverlayImpl_onWindowToken(env, obj, token); } + + // Pass up a reference to the container view so we can observe its location. + // The observer will notify us if there is none yet. + StartObservingContainerView(); } DialogOverlayImpl::~DialogOverlayImpl() { @@ -157,6 +170,9 @@ void DialogOverlayImpl::UnregisterCallbacksIfNeeded() { if (!rfhi_) return; + // No need to track the container view location anymore. + StopObservingContainerView(); + // We clear overlay mode here rather than in Destroy(), because we may have // been called via a WebContentsDestroyed() event, and this might be the last // opportunity we have to access web_contents(). @@ -230,6 +246,8 @@ void DialogOverlayImpl::OnAttachedToWindow() { ScopedJavaLocalRef<jobject> obj = obj_.get(env); if (!obj.is_null()) Java_DialogOverlayImpl_onWindowToken(env, obj, token); + + StartObservingContainerView(); } void DialogOverlayImpl::OnDetachedFromWindow() { @@ -248,6 +266,26 @@ void DialogOverlayImpl::RegisterWindowObserverIfNeeded( } } +void DialogOverlayImpl::StartObservingContainerView() { + ObserveContainerViewIfNeeded( + web_contents()->GetNativeView()->GetContainerView()); +} + +void DialogOverlayImpl::StopObservingContainerView() { + ObserveContainerViewIfNeeded(/*container_view=*/nullptr); +} + +void DialogOverlayImpl::ObserveContainerViewIfNeeded( + const ScopedJavaLocalRef<jobject>& container_view) { + if (!observe_container_view_) + return; + + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = obj_.get(env); + if (!obj.is_null()) + Java_DialogOverlayImpl_observeContainerView(env, obj, container_view); +} + // Helper class that has permission to talk to SyncCallRestrictions. Rather // than friend the function directly, which has an odd signature, friend a class // that knows how to do the work. diff --git a/content/browser/android/dialog_overlay_impl.h b/content/browser/android/dialog_overlay_impl.h index 1912e5e567c956..fd97cbf329958c 100644 --- a/content/browser/android/dialog_overlay_impl.h +++ b/content/browser/android/dialog_overlay_impl.h @@ -30,7 +30,8 @@ class DialogOverlayImpl : public ui::ViewAndroidObserver, DialogOverlayImpl(const base::android::JavaParamRef<jobject>& obj, RenderFrameHostImpl* rfhi, WebContents* web_contents, - bool power_efficient); + bool power_efficient, + bool observe_container_view); ~DialogOverlayImpl() override; // Called when the java side is ready for token / dismissed callbacks. May @@ -77,6 +78,11 @@ class DialogOverlayImpl : public ui::ViewAndroidObserver, void Stop(); void RegisterWindowObserverIfNeeded(ui::WindowAndroid* window); + void StartObservingContainerView(); + void StopObservingContainerView(); + void ObserveContainerViewIfNeeded( + const base::android::ScopedJavaLocalRef<jobject>& container_view); + // Java object that owns us. JavaObjectWeakGlobalRef obj_; @@ -84,10 +90,13 @@ class DialogOverlayImpl : public ui::ViewAndroidObserver, RenderFrameHostImpl* rfhi_; // Do we care about power efficiency? - bool power_efficient_; + const bool power_efficient_; // Whether we added ourselves as an observer through WindowAndroid. bool observed_window_android_; + + // Whether we should observe the container view for location changes. + const bool observe_container_view_; }; } // namespace content diff --git a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java index d6a0b022da52bf..be596776b55d6c 100644 --- a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java @@ -7,6 +7,8 @@ import android.content.Context; import android.os.IBinder; import android.view.Surface; +import android.view.View; +import android.view.ViewTreeObserver; import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; @@ -26,7 +28,8 @@ * from that thread from the UI thread. */ @JNINamespace("content") -public class DialogOverlayImpl implements AndroidOverlay, DialogOverlayCore.Host { +public class DialogOverlayImpl + implements AndroidOverlay, DialogOverlayCore.Host, ViewTreeObserver.OnPreDrawListener { private static final String TAG = "DialogOverlayImpl"; private AndroidOverlayClient mClient; @@ -46,6 +49,12 @@ public class DialogOverlayImpl implements AndroidOverlay, DialogOverlayCore.Host // Temporary, so we don't need to keep allocating arrays. private final int[] mCompositorOffset = new int[2]; + // The last rect passed to scheduleLayout(). + private Rect mLastRect; + + // Observes the container view to update our location. + private ViewTreeObserver mContainerViewViewTreeObserver; + /** * @param client Mojo client interface. * @param config initial overlay configuration. @@ -58,6 +67,7 @@ public DialogOverlayImpl(AndroidOverlayClient client, final AndroidOverlayConfig mClient = client; mReleasedRunnable = releasedRunnable; + mLastRect = copyRect(config.rect); mDialogCore = new DialogOverlayCore(); @@ -123,6 +133,8 @@ public void onConnectionError(MojoException e) { public void scheduleLayout(final Rect rect) { ThreadUtils.assertOnUiThread(); + mLastRect = copyRect(rect); + if (mDialogCore == null) return; // |rect| is relative to the compositor surface. Convert it to be relative to the screen. @@ -166,6 +178,13 @@ public void onOverlayDestroyed() { // client to close their connection first. } + // ViewTreeObserver.OnPreDrawListener implementation. + @Override + public boolean onPreDraw() { + scheduleLayout(mLastRect); + return true; + } + /** * Callback from native that the window token has changed. */ @@ -183,6 +202,19 @@ public void onWindowToken(final IBinder token) { mDialogCore.onWindowToken(token); } + @CalledByNative + private void observeContainerView(View containerView) { + if (mContainerViewViewTreeObserver != null && mContainerViewViewTreeObserver.isAlive()) { + mContainerViewViewTreeObserver.removeOnPreDrawListener(this); + } + mContainerViewViewTreeObserver = null; + + if (containerView != null) { + mContainerViewViewTreeObserver = containerView.getViewTreeObserver(); + mContainerViewViewTreeObserver.addOnPreDrawListener(this); + } + } + /** * Callback from native that we will be getting no additional tokens. */ @@ -237,6 +269,9 @@ private void cleanup() { // We close |mClient| first to prevent leaking the mojo router object. if (mClient != null) mClient.close(); mClient = null; + + // Native should have cleaned up the container view before we reach this. + assert mContainerViewViewTreeObserver == null; } private void notifyDestroyed() { @@ -266,6 +301,18 @@ private void notifyDestroyed() { DialogOverlayImplJni.get().notifyDestroyedSynchronously(nativeHandle); } + /** + * Creates a copy of |rect| and returns it. + */ + private static Rect copyRect(Rect rect) { + Rect copy = new Rect(); + copy.x = rect.x; + copy.y = rect.y; + copy.width = rect.width; + copy.height = rect.height; + return copy; + } + @NativeMethods interface Natives { /** diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 53de48cce1212a..dcc9c2261a5a68 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc @@ -1086,6 +1086,11 @@ std::unique_ptr<TtsEnvironmentAndroid> ContentBrowserClient::CreateTtsEnvironmentAndroid() { return nullptr; } + +bool ContentBrowserClient:: + ShouldObserveContainerViewLocationForDialogOverlays() { + return false; +} #endif base::flat_set<std::string> diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 4b1479f606fd94..09ce07d6501e1c 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -1882,6 +1882,12 @@ class CONTENT_EXPORT ContentBrowserClient { // Creates the TtsEnvironmentAndroid. A return value of null results in using // a default implementation. virtual std::unique_ptr<TtsEnvironmentAndroid> CreateTtsEnvironmentAndroid(); + + // If enabled, DialogOverlays will observe the container view for location + // changes and reposition themselves automatically. Note that this comes with + // some overhead and should only be enabled if the embedder itself can be + // moved. Defaults to false. + virtual bool ShouldObserveContainerViewLocationForDialogOverlays(); #endif // Obtains the list of MIME types that are for plugins with external handlers. diff --git a/weblayer/browser/content_browser_client_impl.cc b/weblayer/browser/content_browser_client_impl.cc index a4ce7747c8f6f2..0281944759fcef 100644 --- a/weblayer/browser/content_browser_client_impl.cc +++ b/weblayer/browser/content_browser_client_impl.cc @@ -1129,6 +1129,14 @@ ContentBrowserClientImpl::CreateTtsEnvironmentAndroid() { return std::make_unique<TtsEnvironmentAndroidImpl>(); } +bool ContentBrowserClientImpl:: + ShouldObserveContainerViewLocationForDialogOverlays() { + // Observe location changes of the container view as WebLayer might be + // embedded in a scrollable container and we need to update the position of + // any DialogOverlays. + return true; +} + #endif // OS_ANDROID content::SpeechRecognitionManagerDelegate* diff --git a/weblayer/browser/content_browser_client_impl.h b/weblayer/browser/content_browser_client_impl.h index a45de63ce94f14..2ffb54e41b7704 100644 --- a/weblayer/browser/content_browser_client_impl.h +++ b/weblayer/browser/content_browser_client_impl.h @@ -201,6 +201,7 @@ class ContentBrowserClientImpl : public content::ContentBrowserClient { LoginAuthRequiredCallback auth_required_callback) override; std::unique_ptr<content::TtsEnvironmentAndroid> CreateTtsEnvironmentAndroid() override; + bool ShouldObserveContainerViewLocationForDialogOverlays() override; #endif // OS_ANDROID content::SpeechRecognitionManagerDelegate* CreateSpeechRecognitionManagerDelegate() override; From dcfadb5215b5577b8335e135bfeb47cb3c4ce650 Mon Sep 17 00:00:00 2001 From: Kent Tamura <tkent@chromium.org> Date: Tue, 1 Jun 2021 10:55:05 +0000 Subject: [PATCH 36/81] Reland "SVG Text NG: Use FontHeight with float ascent/descent on computing a line height" This is a reland of 8028d0cfbc3a46a4c5bbd6206a0f01a05fa1fddd Differences from the original CL: * Rebaseline of virtual/layout_ng_svg_text/svg/batik/text/verticalTextOnPath.svg Original change's description: > SVG Text NG: Use FontHeight with float ascent/descent on computing a line height > > We'd like to apply float font metrics if possible, and this CL switches > integer font metrics to float font metrics for SVG Text NG. > > * Add FontMetrics::FloatFontHeight() > * Add NGInlineBoxState::is_svg_text > * NGInlineBoxState::ComputeTextMetrics() and > NGInlineLayoutStateStack::AddBoxFragmentPlaceholder() use > FontMetrics::GetFloatFontHeight() instead of GetFontHeight() for SVG > text. > > Bug: 1179585 > Change-Id: I4c55be575b4d2bde5c7f729326a6dc29491fe35f > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928055 > Reviewed-by: Koji Ishii <kojii@chromium.org> > Reviewed-by: Yoshifumi Inoue <yosin@chromium.org> > Commit-Queue: Kent Tamura <tkent@chromium.org> > Commit-Queue: Yoshifumi Inoue <yosin@chromium.org> > Cr-Commit-Position: refs/heads/master@{#887826} Bug: 1179585 Change-Id: I8510c7371545167a1fa5ead0f07f3e3eb090377b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929617 Commit-Queue: Kent Tamura <tkent@chromium.org> Commit-Queue: Koji Ishii <kojii@chromium.org> Auto-Submit: Kent Tamura <tkent@chromium.org> Reviewed-by: Koji Ishii <kojii@chromium.org> Cr-Commit-Position: refs/heads/master@{#887913} --- .../layout/ng/inline/ng_inline_box_state.cc | 34 ++++++++++++------ .../layout/ng/inline/ng_inline_box_state.h | 5 +-- .../renderer/platform/fonts/font_metrics.h | 4 +++ .../W3C-SVG-1.1/text-align-05-b-expected.png | Bin 30870 -> 30869 bytes .../svg/batik/text/verticalText-expected.png | Bin 30735 -> 30747 bytes .../text/verticalTextOnPath-expected.png | Bin 51455 -> 51416 bytes .../text/verticalTextOnPath-expected.png | Bin 21796 -> 21873 bytes .../W3C-SVG-1.1/text-align-05-b-expected.png | Bin 8849 -> 0 bytes .../svg/batik/text/verticalText-expected.png | Bin 12471 -> 12454 bytes .../text/verticalTextOnPath-expected.png | Bin 21456 -> 21478 bytes 10 files changed, 30 insertions(+), 13 deletions(-) delete mode 100644 third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/W3C-SVG-1.1/text-align-05-b-expected.png diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc index 24443c13b41098..85a0e8fd82012f 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc @@ -55,15 +55,15 @@ NGInlineBoxState::NGInlineBoxState(const NGInlineBoxState&& state) pending_descendants(std::move(state.pending_descendants)), include_used_fonts(state.include_used_fonts), has_box_placeholder(state.has_box_placeholder), - needs_box_fragment(state.needs_box_fragment) { + needs_box_fragment(state.needs_box_fragment), + is_svg_text(state.is_svg_text) { if (state.scaled_font) font = &*scaled_font; else font = state.font; } -void NGInlineBoxState::InitializeFont(bool is_svg_text, - const LayoutObject& layout_object) { +void NGInlineBoxState::InitializeFont(const LayoutObject& layout_object) { if (!is_svg_text) { scaling_factor = 1.0f; font = &style->GetFont(); @@ -78,10 +78,16 @@ void NGInlineBoxState::InitializeFont(bool is_svg_text, void NGInlineBoxState::ComputeTextMetrics(const ComputedStyle& styleref, const Font& fontref, FontBaseline baseline_type) { - if (const SimpleFontData* font_data = fontref.PrimaryFont()) - text_metrics = font_data->GetFontMetrics().GetFontHeight(baseline_type); - else + if (const SimpleFontData* font_data = fontref.PrimaryFont()) { + if (is_svg_text) { + text_metrics = + font_data->GetFontMetrics().GetFloatFontHeight(baseline_type); + } else { + text_metrics = font_data->GetFontMetrics().GetFontHeight(baseline_type); + } + } else { text_metrics = FontHeight(); + } text_top = -text_metrics.ascent; text_height = text_metrics.LineHeight(); @@ -189,7 +195,8 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnBeginPlaceItems( NGInlineBoxState& line_box_state = LineBoxState(); if (line_box_state.style != &line_style) { line_box_state.style = &line_style; - line_box_state.InitializeFont(node.IsSvgText(), *node.GetLayoutBox()); + line_box_state.is_svg_text = node.IsSvgText(); + line_box_state.InitializeFont(*node.GetLayoutBox()); // Use a "strut" (a zero-width inline box with the element's font and // line height properties) as the initial metrics for the line box. @@ -227,7 +234,8 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag( NGInlineBoxState* box = &stack_.back(); box->fragment_start = line_box.size(); box->style = &style; - box->InitializeFont(is_svg_text_, *item.GetLayoutObject()); + box->is_svg_text = is_svg_text_; + box->InitializeFont(*item.GetLayoutObject()); box->item = &item; box->has_start_edge = item_result.has_edge; box->margin_inline_start = item_result.margins.inline_start; @@ -304,8 +312,6 @@ void NGInlineLayoutStateStack::AddBoxFragmentPlaceholder( DCHECK(box != stack_.begin() && box->item->Type() != NGInlineItem::kAtomicInline); box->has_box_placeholder = true; - DCHECK(box->style); - const ComputedStyle& style = *box->style; LayoutUnit block_offset; LayoutUnit block_size; @@ -313,7 +319,13 @@ void NGInlineLayoutStateStack::AddBoxFragmentPlaceholder( // The inline box should have the height of the font metrics without the // line-height property. Compute from style because |box->metrics| includes // the line-height property. - FontHeight metrics = style.GetFontHeight(baseline_type); + FontHeight metrics; + if (const auto* font_data = box->font->PrimaryFont()) { + metrics = + is_svg_text_ + ? font_data->GetFontMetrics().GetFloatFontHeight(baseline_type) + : font_data->GetFontMetrics().GetFontHeight(baseline_type); + } // Extend the block direction of the box by borders and paddings. Inline // direction is already included into positions in NGLineBreaker. diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h index ba903efdb832b9..a2174d8387cc4f 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h @@ -81,6 +81,7 @@ struct NGInlineBoxState { bool include_used_fonts = false; bool has_box_placeholder = false; bool needs_box_fragment = false; + bool is_svg_text = false; // If you add new data members, update the move constructor. @@ -91,8 +92,8 @@ struct NGInlineBoxState { NGInlineBoxState& operator=(const NGInlineBoxState&) = delete; // Initialize |font| and |scaled_font|. This should be called after setting - // |style|. - void InitializeFont(bool is_svg_text, const LayoutObject& layout_object); + // |style| and |is_svg_text|. + void InitializeFont(const LayoutObject& layout_object); // True if this box has a metrics, including pending ones. Pending metrics // will be activated in |EndBoxState()|. diff --git a/third_party/blink/renderer/platform/fonts/font_metrics.h b/third_party/blink/renderer/platform/fonts/font_metrics.h index 38d920712dbd9b..f2506e84ac48a4 100644 --- a/third_party/blink/renderer/platform/fonts/font_metrics.h +++ b/third_party/blink/renderer/platform/fonts/font_metrics.h @@ -129,6 +129,10 @@ class FontMetrics { return LayoutUnit::FromFloatRound(line_spacing_); } + FontHeight GetFloatFontHeight(FontBaseline baseline_type) const { + return FontHeight(FixedAscent(baseline_type), FixedDescent(baseline_type)); + } + FontHeight GetFontHeight( FontBaseline baseline_type = kAlphabeticBaseline) const { // TODO(kojii): In future, we'd like to use LayoutUnit metrics to support diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/W3C-SVG-1.1/text-align-05-b-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/W3C-SVG-1.1/text-align-05-b-expected.png index 763d0967d9fe9c124864556faad81ae29ea38cb4..a40e9e23adf532e771f5fb4adbb03f2fb33ced06 100644 GIT binary patch literal 30869 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 Tc@URvNTl=URONDIjeY(XgqKZk literal 30870 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 KCvz0cZ~hnm2JQR+ diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/batik/text/verticalText-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/batik/text/verticalText-expected.png index 9c30993f9c4c217b648e3e28072cea9a04dd305b..1cf7ba3d0faf3d203cd13a122909c7a3c414c829 100644 GIT binary patch delta 10522 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 delta 10492 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 G@ckb)r~tYE diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/batik/text/verticalTextOnPath-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/batik/text/verticalTextOnPath-expected.png index b32a4d7c332a800da720caa15821d41831b19f8d..202b229dc11f32fca1ab13a231475dd75a1a7af7 100644 GIT binary patch literal 51416 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�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 RE_4avfYxEn$9t^;{|msVWV8SP literal 51455 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 diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/batik/text/verticalTextOnPath-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/batik/text/verticalTextOnPath-expected.png index 1f69b6db02be92322852a4d0213bf909280b84df..40c83e1e71895df607fbac48747f451418f47f54 100644 GIT binary patch literal 21873 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%0A`7sYs4Cd;)O`}V#3xgAMgtJj{8}il6hQAI_Kum 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 literal 21796 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 diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/W3C-SVG-1.1/text-align-05-b-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/W3C-SVG-1.1/text-align-05-b-expected.png deleted file mode 100644 index c302e29b298f3e19447ea8d08e7249bc7bebc145..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8849 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 diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/batik/text/verticalText-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/batik/text/verticalText-expected.png index b823f3f8142fefd562c1d07a99807f30b9c1c25b..625163d4eeeaa1d795fdb530430d7b676c21d90b 100644 GIT binary patch delta 10302 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 Pz(-HVNSkmA@%(=QI4W48 delta 10436 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 diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/batik/text/verticalTextOnPath-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/batik/text/verticalTextOnPath-expected.png index 8ff13bd7fb7bd6278cbdc39ad89fcb53d7e0bc63..45c6ce60e9495e5fc1e93a95cd9f455c5b148c35 100644 GIT binary patch literal 21478 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y&;5Nw9E?n`RpK%tJ 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�eVgMdI!-Xrq;9nLf&HVD`)H_UrZ3cvigmS!@FRSrRZVaW6 zH+6PuFG{s{351QJLpztWv!S+VVzmu8*+0}qq&9Ryb^LqeU1fICJnub7pX2iVH8Dlk z2klHR%$tY^xO%rlcP@sCq%oKdx917)T()LWYaY|;`5n&~E6uL_ZI)EDrDE{W{RJ_Q z*^mRyCCv7dSmaVr=w}TMhveqPai{&yd<K5|?ktJA7A|Cxy-gz@PTkGb<Hh`l)<dMS z$X=!UzEz)LfL0o>U{HC`^;Q>^{;$CBy`?jqyU5`jkQVUji~YD%w0Ln+Q$wfzr72@z z!Uj~GcJoDO^Cku?f}n^zTYx*^0;ps)nx!Q1Xx_ii?$zuwfOU>@s7d@XSaxr%*YV$N zcdv}_Z`8^soB$aCW!<2s5jZaxF06EpLzV@MMl#t=Xisv$+*1^#6p@;>vwB!6Z5C&; z{k=<-b)lbolote~rC2k;n@KV~<V|~yYH7@pj*pSTDtY~2efd}^eJfqNyT868$^#yJ zwCuZ<6HkH$ipkbi?Raz}nh!{m1Fupg3v<9y8+^a^<ztD39}p=H=JY^*ZyH8TN$A85 zRaeIvJ){CFTHs1Z6GV+2TK;Fm_|y&?>+Eb8VQ;$0H4479Kx89Z<IRVW&V$8V(-JtC zMua8DJ6ee$ajM5sz|svdyW3#k;Q>CLQ=nWrNQMGNJObdQM=^>0iDF{UVkjThJJnYa zxu#p-cM0RzJI_HOp}^17wOOT{Z^{>{Zy9WnjNf%G<{jRwdS;k1aV$ag@1lkm!@6Sj zhbh5T!Tg_SN9`C>jpQ#S=tm6#0HlwEVu)(oa{K8XIF(iu)&<L1-?N(H1ym59-=t6| zr-0ircu?^GglhjBN&oLn+5S;Sxc~qBpWkzi*}UX(Rjwk%7CeQ3oz+##26OMk{{S}* B`E&pP literal 21456 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%0Dd3e(T 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 From 0babade171ee24ed0ce4e82335e0d9194b961ddb Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 11:08:55 +0000 Subject: [PATCH 37/81] Roll Perfetto from b3f455e9edce to bb3b66d48669 (1 revision) https://android.googlesource.com/platform/external/perfetto.git/+log/b3f455e9edce..bb3b66d48669 2021-05-31 ilkos@google.com Do not spam error log for malformed traces If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/perfetto-chromium-autoroll Please CC perfetto-bugs@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chromium.try:linux-perfetto-rel Bug: None Tbr: perfetto-bugs@google.com Change-Id: I0f20f6d5ef1b3911456630e77e7a1b0662a6e5be Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928321 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887914} --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index abefdaa75adbfc..87619293790e70 100644 --- a/DEPS +++ b/DEPS @@ -1349,7 +1349,7 @@ deps = { }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b3f455e9edced2a776ddcb5a2cdf5ddcefa8776f', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'bb3b66d486694c9984e76d38e3bd7ca525edfee2', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', From ff78a9882d2889d541632b62c63a40b199dea3a0 Mon Sep 17 00:00:00 2001 From: Richard Knoll <knollr@chromium.org> Date: Tue, 1 Jun 2021 11:09:05 +0000 Subject: [PATCH 38/81] Move SensorPermissionContext to //components This moves the SensorPermissionContext to //components so we can use it from //weblayer. This fixes a WPT failure and enables sensor APIs to be used in WebLayer. Bug: 1213914 Change-Id: If1f1001b937586e028ec31e82ee1a48057cefaa8 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2920581 Reviewed-by: Colin Blundell <blundell@chromium.org> Reviewed-by: Dominick Ng <dominickn@chromium.org> Commit-Queue: Richard Knoll <knollr@chromium.org> Cr-Commit-Position: refs/heads/master@{#887915} --- chrome/browser/BUILD.gn | 2 -- chrome/browser/generic_sensor/DIR_METADATA | 4 ---- chrome/browser/generic_sensor/OWNERS | 3 --- .../permissions/permission_manager_factory.cc | 4 ++-- components/permissions/BUILD.gn | 2 ++ .../contexts}/sensor_permission_context.cc | 8 +++++--- .../contexts}/sensor_permission_context.h | 20 ++++++++++--------- .../android/WebLayerWPTOverrideExpectations | 1 - .../permissions/permission_manager_factory.cc | 3 +++ 9 files changed, 23 insertions(+), 24 deletions(-) delete mode 100644 chrome/browser/generic_sensor/DIR_METADATA delete mode 100644 chrome/browser/generic_sensor/OWNERS rename {chrome/browser/generic_sensor => components/permissions/contexts}/sensor_permission_context.cc (91%) rename {chrome/browser/generic_sensor => components/permissions/contexts}/sensor_permission_context.h (51%) diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 199407202dfcf4..43fffa4cdaf794 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn @@ -536,8 +536,6 @@ static_library("browser") { "gcm/gcm_profile_service_factory.h", "gcm/instance_id/instance_id_profile_service_factory.cc", "gcm/instance_id/instance_id_profile_service_factory.h", - "generic_sensor/sensor_permission_context.cc", - "generic_sensor/sensor_permission_context.h", "geolocation/geolocation_permission_context_delegate.cc", "geolocation/geolocation_permission_context_delegate.h", "geolocation/geolocation_permission_context_extensions.cc", diff --git a/chrome/browser/generic_sensor/DIR_METADATA b/chrome/browser/generic_sensor/DIR_METADATA deleted file mode 100644 index fd9a3488da45d9..00000000000000 --- a/chrome/browser/generic_sensor/DIR_METADATA +++ /dev/null @@ -1,4 +0,0 @@ -monorail: { - component: "Blink>Sensor" -} -team_email: "device-dev@chromium.org" diff --git a/chrome/browser/generic_sensor/OWNERS b/chrome/browser/generic_sensor/OWNERS deleted file mode 100644 index f301975f4c3270..00000000000000 --- a/chrome/browser/generic_sensor/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -file://services/device/generic_sensor/OWNERS - -per-file *permission_context*=file://components/permissions/PERMISSIONS_OWNERS diff --git a/chrome/browser/permissions/permission_manager_factory.cc b/chrome/browser/permissions/permission_manager_factory.cc index 3811b0d846c91c..80008779e748c7 100644 --- a/chrome/browser/permissions/permission_manager_factory.cc +++ b/chrome/browser/permissions/permission_manager_factory.cc @@ -11,7 +11,6 @@ #include "chrome/browser/background_sync/periodic_background_sync_permission_context.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/display_capture/display_capture_permission_context.h" -#include "chrome/browser/generic_sensor/sensor_permission_context.h" #include "chrome/browser/idle/idle_detection_permission_context.h" #include "chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context.h" #include "chrome/browser/media/webrtc/media_stream_device_permission_context.h" @@ -36,6 +35,7 @@ #include "components/permissions/contexts/midi_permission_context.h" #include "components/permissions/contexts/midi_sysex_permission_context.h" #include "components/permissions/contexts/payment_handler_permission_context.h" +#include "components/permissions/contexts/sensor_permission_context.h" #include "components/permissions/contexts/webxr_permission_context.h" #include "components/permissions/permission_manager.h" #include "ppapi/buildflags/buildflags.h" @@ -92,7 +92,7 @@ permissions::PermissionManager::PermissionContextMap CreatePermissionContexts( permission_contexts[ContentSettingsType::BACKGROUND_SYNC] = std::make_unique<BackgroundSyncPermissionContext>(profile); permission_contexts[ContentSettingsType::SENSORS] = - std::make_unique<SensorPermissionContext>(profile); + std::make_unique<permissions::SensorPermissionContext>(profile); permission_contexts[ContentSettingsType::ACCESSIBILITY_EVENTS] = std::make_unique<AccessibilityPermissionContext>(profile); permission_contexts[ContentSettingsType::CLIPBOARD_READ_WRITE] = diff --git a/components/permissions/BUILD.gn b/components/permissions/BUILD.gn index 8b429a9ced4b83..3545bd19a5c45d 100644 --- a/components/permissions/BUILD.gn +++ b/components/permissions/BUILD.gn @@ -37,6 +37,8 @@ source_set("permissions") { "contexts/nfc_permission_context.h", "contexts/payment_handler_permission_context.cc", "contexts/payment_handler_permission_context.h", + "contexts/sensor_permission_context.cc", + "contexts/sensor_permission_context.h", "contexts/webxr_permission_context.cc", "contexts/webxr_permission_context.h", "object_permission_context_base.cc", diff --git a/chrome/browser/generic_sensor/sensor_permission_context.cc b/components/permissions/contexts/sensor_permission_context.cc similarity index 91% rename from chrome/browser/generic_sensor/sensor_permission_context.cc rename to components/permissions/contexts/sensor_permission_context.cc index 713a96f0ccf72f..960ec4c350778b 100644 --- a/chrome/browser/generic_sensor/sensor_permission_context.cc +++ b/components/permissions/contexts/sensor_permission_context.cc @@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/generic_sensor/sensor_permission_context.h" +#include "components/permissions/contexts/sensor_permission_context.h" -#include "base/feature_list.h" #include "components/content_settings/browser/page_specific_content_settings.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/permissions/permission_request_id.h" -#include "services/device/public/cpp/device_features.h" #include "third_party/blink/public/mojom/permissions_policy/permissions_policy.mojom.h" #include "url/gurl.h" +namespace permissions { + SensorPermissionContext::SensorPermissionContext( content::BrowserContext* browser_context) : PermissionContextBase(browser_context, @@ -45,3 +45,5 @@ bool SensorPermissionContext::IsRestrictedToSecureOrigins() const { // origins and this is enforced by the renderer. return false; } + +} // namespace permissions diff --git a/chrome/browser/generic_sensor/sensor_permission_context.h b/components/permissions/contexts/sensor_permission_context.h similarity index 51% rename from chrome/browser/generic_sensor/sensor_permission_context.h rename to components/permissions/contexts/sensor_permission_context.h index 9ff55cc46b7d8f..d7cd9c3f7e61ee 100644 --- a/chrome/browser/generic_sensor/sensor_permission_context.h +++ b/components/permissions/contexts/sensor_permission_context.h @@ -2,26 +2,28 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_GENERIC_SENSOR_SENSOR_PERMISSION_CONTEXT_H_ -#define CHROME_BROWSER_GENERIC_SENSOR_SENSOR_PERMISSION_CONTEXT_H_ +#ifndef COMPONENTS_PERMISSIONS_CONTEXTS_SENSOR_PERMISSION_CONTEXT_H_ +#define COMPONENTS_PERMISSIONS_CONTEXTS_SENSOR_PERMISSION_CONTEXT_H_ -#include "base/macros.h" #include "components/permissions/permission_context_base.h" -class SensorPermissionContext : public permissions::PermissionContextBase { +namespace permissions { + +class SensorPermissionContext : public PermissionContextBase { public: explicit SensorPermissionContext(content::BrowserContext* browser_context); - + SensorPermissionContext(const SensorPermissionContext&) = delete; + SensorPermissionContext& operator=(const SensorPermissionContext&) = delete; ~SensorPermissionContext() override; private: // PermissionContextBase: - void UpdateTabContext(const permissions::PermissionRequestID& id, + void UpdateTabContext(const PermissionRequestID& id, const GURL& requesting_frame, bool allowed) override; bool IsRestrictedToSecureOrigins() const override; - - DISALLOW_COPY_AND_ASSIGN(SensorPermissionContext); }; -#endif // CHROME_BROWSER_GENERIC_SENSOR_SENSOR_PERMISSION_CONTEXT_H_ +} // namespace permissions + +#endif // COMPONENTS_PERMISSIONS_CONTEXTS_SENSOR_PERMISSION_CONTEXT_H_ diff --git a/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations b/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations index 3678852400054f..7a766ba3a669b2 100644 --- a/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations +++ b/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations @@ -1248,7 +1248,6 @@ crbug.com/1050754 external/wpt/native-io/write_capacity_allocation_async.tentati crbug.com/1050754 external/wpt/native-io/write_capacity_allocation_async.tentative.https.any.worker.html [ Failure Pass ] crbug.com/1050754 external/wpt/native-io/write_getLength_async_basic.tentative.https.any.sharedworker.html [ Failure ] crbug.com/1050754 external/wpt/navigation-timing/test_performance_attributes.sub.html [ Failure Pass ] -crbug.com/1050754 external/wpt/orientation-event/device-orientation-events-unavailable-on-insecure-origins.html [ Failure ] crbug.com/1050754 external/wpt/orientation-sensor/AbsoluteOrientationSensor.https.html [ Failure ] crbug.com/1050754 external/wpt/orientation-sensor/RelativeOrientationSensor.https.html [ Failure ] crbug.com/1050754 external/wpt/paint-timing/fcp-only/fcp-gradient.html [ Pass ] diff --git a/weblayer/browser/permissions/permission_manager_factory.cc b/weblayer/browser/permissions/permission_manager_factory.cc index 10020d717b8e83..2188a8a4072dc5 100644 --- a/weblayer/browser/permissions/permission_manager_factory.cc +++ b/weblayer/browser/permissions/permission_manager_factory.cc @@ -13,6 +13,7 @@ #include "components/permissions/contexts/midi_permission_context.h" #include "components/permissions/contexts/midi_sysex_permission_context.h" #include "components/permissions/contexts/payment_handler_permission_context.h" +#include "components/permissions/contexts/sensor_permission_context.h" #include "components/permissions/permission_context_base.h" #include "components/permissions/permission_manager.h" #include "content/public/browser/permission_type.h" @@ -120,6 +121,8 @@ permissions::PermissionManager::PermissionContextMap CreatePermissionContexts( std::make_unique<BackgroundFetchPermissionContext>(browser_context); permission_contexts[ContentSettingsType::BACKGROUND_SYNC] = std::make_unique<BackgroundSyncPermissionContext>(browser_context); + permission_contexts[ContentSettingsType::SENSORS] = + std::make_unique<permissions::SensorPermissionContext>(browser_context); // For now, all requests are denied. As features are added, their permission // contexts can be added here instead of DeniedPermissionContext. From c57263e40a0736a1ebf488d872a7735464544b91 Mon Sep 17 00:00:00 2001 From: Tony Herre <toprice@chromium.org> Date: Tue, 1 Jun 2021 11:16:07 +0000 Subject: [PATCH 39/81] Propagate Mic Permissions error to getUserMedia Propagate the AudioCapturerSource::ErrorCode received by an audio source to give the correct getUserMedia error. Concretely, throw a NotAllowedError with message "Permission denied by system". Tested locally on a Windows 10 device, webrtc gUM sample page, now throws a NotAllowedError as expected. Bug: 1019163 Change-Id: Ide81b55423a30afd89c588294afc4c31bf73b430 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2917066 Reviewed-by: Olga Sharonova <olka@chromium.org> Reviewed-by: Guido Urdaneta <guidou@chromium.org> Commit-Queue: Tony Herre <toprice@chromium.org> Cr-Commit-Position: refs/heads/master@{#887916} --- .../local_media_stream_audio_source.cc | 2 +- .../processed_local_audio_source.cc | 2 +- .../mediastream/user_media_processor.cc | 31 +++++++++++++------ .../mediastream/media_stream_audio_source.cc | 17 ++++++++-- .../mediastream/media_stream_audio_source.h | 21 ++++++++++++- 5 files changed, 57 insertions(+), 16 deletions(-) diff --git a/third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.cc b/third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.cc index 0bf0c1fd9ecd83..d284b26908e209 100644 --- a/third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.cc +++ b/third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.cc @@ -126,7 +126,7 @@ void LocalMediaStreamAudioSource::OnCaptureError( base::StringPrintf("LocalMediaStreamAudioSource::OnCaptureError: %d, %s", code, why.c_str())); - StopSourceOnError(why); + StopSourceOnError(code, why); } void LocalMediaStreamAudioSource::OnCaptureMuted(bool is_muted) { diff --git a/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc b/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc index 5180df81abbe76..32f4dfc93d1fab 100644 --- a/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc +++ b/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc @@ -488,7 +488,7 @@ void ProcessedLocalAudioSource::OnCaptureError( const std::string& message) { SendLogMessageWithSessionId(base::StringPrintf( "OnCaptureError({code=%d, message=%s})", code, message.c_str())); - StopSourceOnError(message); + StopSourceOnError(code, message); } void ProcessedLocalAudioSource::OnCaptureMuted(bool is_muted) { diff --git a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc index 0c98a5635112f4..1300f8abc7919c 100644 --- a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc +++ b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc @@ -1768,17 +1768,28 @@ bool UserMediaProcessor::RemoveLocalSource(MediaStreamSource* source) { for (auto* device_it = pending_local_sources_.begin(); device_it != pending_local_sources_.end(); ++device_it) { if (IsSameSource(*device_it, source)) { - WebPlatformMediaStreamSource* const source_extra_data = + WebPlatformMediaStreamSource* const platform_source = source->GetPlatformSource(); - const bool is_audio_source = - source->GetType() == MediaStreamSource::kTypeAudio; - NotifyCurrentRequestInfoOfAudioSourceStarted( - source_extra_data, - is_audio_source ? MediaStreamRequestResult::TRACK_START_FAILURE_AUDIO - : MediaStreamRequestResult::TRACK_START_FAILURE_VIDEO, - String::FromUTF8(is_audio_source - ? "Failed to access audio capture device" - : "Failed to access video capture device")); + MediaStreamRequestResult result; + String message; + if (source->GetType() == MediaStreamSource::kTypeAudio) { + auto error = MediaStreamAudioSource::From(source)->ErrorCode(); + if (error.has_value() && + error.value() == + media::AudioCapturerSource::ErrorCode::kSystemPermissions) { + result = MediaStreamRequestResult::SYSTEM_PERMISSION_DENIED; + message = + "System Permssions prevented access to audio capture device"; + } else { + result = MediaStreamRequestResult::TRACK_START_FAILURE_AUDIO; + message = "Failed to access audio capture device"; + } + } else { + result = MediaStreamRequestResult::TRACK_START_FAILURE_VIDEO; + message = "Failed to access video capture device"; + } + NotifyCurrentRequestInfoOfAudioSourceStarted(platform_source, result, + message); pending_local_sources_.erase(device_it); return true; } diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc b/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc index 3472afb17878e1..cbfe7b887c70f1 100644 --- a/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc +++ b/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.cc @@ -251,13 +251,24 @@ void MediaStreamAudioSource::StopAudioDeliveryTo(MediaStreamAudioTrack* track) { } } -void MediaStreamAudioSource::StopSourceOnError(const std::string& why) { +void MediaStreamAudioSource::StopSourceOnError( + media::AudioCapturerSource::ErrorCode code, + const std::string& why) { LogMessage(base::StringPrintf("%s({why=%s})", __func__, why.c_str())); + // Stop source when error occurs. PostCrossThreadTask( *task_runner_, FROM_HERE, - CrossThreadBindOnce(&WebPlatformMediaStreamSource::StopSource, - GetWeakPtr())); + CrossThreadBindOnce( + &MediaStreamAudioSource::StopSourceOnErrorOnTaskRunner, GetWeakPtr(), + code)); +} + +void MediaStreamAudioSource::StopSourceOnErrorOnTaskRunner( + media::AudioCapturerSource::ErrorCode code) { + DCHECK(task_runner_->BelongsToCurrentThread()); + SetErrorCode(code); + StopSource(); } void MediaStreamAudioSource::SetMutedState(bool muted_state) { diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h b/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h index 40ca6019c6a2de..ce0ba7930856c6 100644 --- a/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h +++ b/third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h @@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "media/base/audio_capturer_source.h" #include "media/base/limits.h" #include "third_party/blink/public/platform/modules/mediastream/web_platform_media_stream_source.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_deliverer.h" @@ -127,6 +128,11 @@ class PLATFORM_EXPORT MediaStreamAudioSource return absl::nullopt; } + absl::optional<media::AudioCapturerSource::ErrorCode> ErrorCode() { + DCHECK(task_runner_->BelongsToCurrentThread()); + return error_code_; + } + protected: // Returns a new MediaStreamAudioTrack. |id| is the blink track's ID in UTF-8. // Subclasses may override this to provide an extended implementation. @@ -169,7 +175,8 @@ class PLATFORM_EXPORT MediaStreamAudioSource // Called by subclasses when capture error occurs. // Note: This can be called on any thread, and will post a task to the main // thread to stop the source soon. - void StopSourceOnError(const std::string& why); + void StopSourceOnError(media::AudioCapturerSource::ErrorCode code, + const std::string& why); // Sets muted state and notifies it to all registered tracks. void SetMutedState(bool state); @@ -196,6 +203,15 @@ class PLATFORM_EXPORT MediaStreamAudioSource void LogMessage(const std::string& message); + void SetErrorCode(media::AudioCapturerSource::ErrorCode code) { + DCHECK(task_runner_->BelongsToCurrentThread()); + error_code_ = code; + } + + // The portion of StopSourceOnError processing carried out on the main thread. + void StopSourceOnErrorOnTaskRunner( + media::AudioCapturerSource::ErrorCode code); + // True if the source of audio is a local device. False if the source is // remote (e.g., streamed-in from a server). const bool is_local_source_; @@ -214,6 +230,9 @@ class PLATFORM_EXPORT MediaStreamAudioSource // thread. const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + // Code set if this source was closed due to an error. + absl::optional<media::AudioCapturerSource::ErrorCode> error_code_; + // Provides weak pointers so that MediaStreamAudioTracks won't call // StopAudioDeliveryTo() if this instance dies first. base::WeakPtrFactory<MediaStreamAudioSource> weak_factory_{this}; From 44548ca349dd9dc14bd0c165b4d48dfce2f7b2d0 Mon Sep 17 00:00:00 2001 From: Rayan Kanso <rayankans@chromium.org> Date: Tue, 1 Jun 2021 11:30:10 +0000 Subject: [PATCH 40/81] Add rayankans@ to Background Sync mojo owners Change-Id: If72dc7717716dc0c2b74e6f0bfcdf037ce3e6edc Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928722 Auto-Submit: Rayan Kanso <rayankans@chromium.org> Commit-Queue: Peter Beverloo <peter@chromium.org> Reviewed-by: Peter Beverloo <peter@chromium.org> Cr-Commit-Position: refs/heads/master@{#887917} --- third_party/blink/public/mojom/background_sync/OWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/third_party/blink/public/mojom/background_sync/OWNERS b/third_party/blink/public/mojom/background_sync/OWNERS index 502de83d47110b..212d60ba302b53 100644 --- a/third_party/blink/public/mojom/background_sync/OWNERS +++ b/third_party/blink/public/mojom/background_sync/OWNERS @@ -1,6 +1,7 @@ iclelland@chromium.org jkarlin@chromium.org peter@chromium.org +rayankans@chromium.org per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS From 05e8c144505d0bd90efa428d79886f6e4c7b5486 Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 11:41:20 +0000 Subject: [PATCH 41/81] Roll Chrome Win64 PGO Profile Roll Chrome Win64 PGO profile from chrome-win64-master-1622527178-f7f002d24b6ce32cbf736f0bf14b7211500ab8a5.profdata to chrome-win64-master-1622537940-762b6b3e8d3692381f31254fc3e14d7487d42c28.profdata If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/pgo-win64-chromium Please CC pgo-profile-sheriffs@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chrome.try:win64-chrome Tbr: pgo-profile-sheriffs@google.com Change-Id: I373133095bef39f4741031f747df07d93ee5eab4 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928319 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887918} --- chrome/build/win64.pgo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index a2d677e8a62c07..7543d3170941ef 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt @@ -1 +1 @@ -chrome-win64-master-1622527178-f7f002d24b6ce32cbf736f0bf14b7211500ab8a5.profdata +chrome-win64-master-1622537940-762b6b3e8d3692381f31254fc3e14d7487d42c28.profdata From 0c98b5d74043398791b1c5740d75e45cd920a6c9 Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 11:46:41 +0000 Subject: [PATCH 42/81] Roll Chrome Win32 PGO Profile Roll Chrome Win32 PGO profile from chrome-win32-master-1622527178-9a5352b7412ad6ef11456de74f66a37dcaa3308d.profdata to chrome-win32-master-1622537940-de546d7191135903a2ef665a10feb391e9b45b67.profdata If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/pgo-win32-chromium Please CC pgo-profile-sheriffs@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chrome.try:win-chrome Tbr: pgo-profile-sheriffs@google.com Change-Id: I4e3169c8c2d2d112b8616f0a2093dd4bda3b4dc5 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929898 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887919} --- chrome/build/win32.pgo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 8e2146b4ae6ada..0ef992bc71b1f7 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt @@ -1 +1 @@ -chrome-win32-master-1622527178-9a5352b7412ad6ef11456de74f66a37dcaa3308d.profdata +chrome-win32-master-1622537940-de546d7191135903a2ef665a10feb391e9b45b67.profdata From e0f79c55bdd5a83bd5e28cfb1f0028dabe85bfe8 Mon Sep 17 00:00:00 2001 From: Joel Hockey <joelhockey@chromium.org> Date: Tue, 1 Jun 2021 11:47:11 +0000 Subject: [PATCH 43/81] Reland "Remove clipboard filenames feature flag"" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 58b431e4c6c783d50501d98871fff0d1193797d8. Reason for revert: Tests now runs fine. I think original failure was unrelated to this CL. Original change's description: > sheriff: Revert "Remove clipboard filenames feature flag" > > This reverts commit 6f02a548d6fce0a65d5f7e70540e55b9625d7af6. > > Reason for revert: > Speculative revert, suspecting this could be causing crashes in smoke > tests: > https://ci.chromium.org/ui/p/chromium/builders/ci/ios-simulator-noncq/17930/overview > > There is another CL in the blamelist but it looks unrelated (however > I don't really know a lot about ios smoke tests). > > Original change's description: > > Remove clipboard filenames feature flag > > > > Bug: 1175483 > > Change-Id: Ief8e27eab4ac0f0342984cedabc7e7c29e5f6443 > > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2916702 > > Commit-Queue: Joel Hockey <joelhockey@chromium.org> > > Reviewed-by: Darwin Huang <huangdarwin@chromium.org> > > Reviewed-by: Marijn Kruisselbrink <mek@chromium.org> > > Reviewed-by: Peter Boström <pbos@chromium.org> > > Reviewed-by: Mitsuru Oshima <oshima@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#887620} > > Bug: 1175483 > Change-Id: I158a334c7821cd439083daa0aa34fa7f160e8e0b > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2927305 > Auto-Submit: Pavol Marko <pmarko@chromium.org> > Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> > Commit-Queue: Ella Ge <eirage@chromium.org> > Owners-Override: Pavol Marko <pmarko@chromium.org> > Reviewed-by: Ella Ge <eirage@chromium.org> > Cr-Commit-Position: refs/heads/master@{#887760} Bug: 1175483 Change-Id: I6e44dcc149e4843789078283bb71532f7cfed58a No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928685 Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Commit-Queue: Ramin Halavati <rhalavati@chromium.org> Reviewed-by: Pavol Marko <pmarko@chromium.org> Owners-Override: Ramin Halavati <rhalavati@chromium.org> Cr-Commit-Position: refs/heads/master@{#887920} --- chrome/browser/about_flags.cc | 4 -- .../exo/chrome_data_exchange_delegate.cc | 23 -------- .../exo/chrome_data_exchange_delegate.h | 3 - .../chrome_data_exchange_delegate_unittest.cc | 25 ++++---- chrome/browser/flag-metadata.json | 5 -- chrome/browser/flag_descriptions.cc | 4 -- chrome/browser/flag_descriptions.h | 3 - components/exo/data_exchange_delegate.h | 8 --- components/exo/seat.cc | 17 +----- components/exo/seat_unittest.cc | 32 ---------- .../test/exo_test_data_exchange_delegate.cc | 8 --- .../test/exo_test_data_exchange_delegate.h | 3 - ...ile_system_access_clipboard_browsertest.cc | 58 ------------------- .../renderer_host/clipboard_host_impl.cc | 7 --- .../clipboard_host_impl_browsertest.cc | 6 -- .../renderer/core/clipboard/data_object.cc | 5 +- ui/base/clipboard/clipboard_mac.mm | 26 +-------- ui/base/clipboard/clipboard_non_backed.cc | 5 +- .../clipboard_non_backed_unittest.cc | 4 -- ui/base/clipboard/clipboard_test_template.h | 4 -- ui/base/clipboard/clipboard_win.cc | 6 -- ui/base/ui_base_features.cc | 5 -- ui/base/ui_base_features.h | 2 - ui/base/x/x11_clipboard_helper.cc | 5 +- 24 files changed, 18 insertions(+), 250 deletions(-) diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 9dc3f2deca59ef..18240ea8c99681 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc @@ -6412,10 +6412,6 @@ const FeatureEntry kFeatureEntries[] = { flag_descriptions::kClientStorageAccessContextAuditingDescription, kOsAll, FEATURE_VALUE_TYPE(features::kClientStorageAccessContextAuditing)}, - {"clipboard-filenames", flag_descriptions::kClipboardFilenamesName, - flag_descriptions::kClipboardFilenamesDescription, kOsAll, - FEATURE_VALUE_TYPE(features::kClipboardFilenames)}, - #if defined(OS_WIN) {"safety-check-chrome-cleaner-child", flag_descriptions::kSafetyCheckChromeCleanerChildName, diff --git a/chrome/browser/chromeos/exo/chrome_data_exchange_delegate.cc b/chrome/browser/chromeos/exo/chrome_data_exchange_delegate.cc index c209b94fcba1fd..ea10e4db4dffb4 100644 --- a/chrome/browser/chromeos/exo/chrome_data_exchange_delegate.cc +++ b/chrome/browser/chromeos/exo/chrome_data_exchange_delegate.cc @@ -53,10 +53,7 @@ constexpr char kUriListSeparator[] = "\r\n"; constexpr char kVmFileScheme[] = "vmfile"; // Mime types used in FilesApp to copy/paste files to clipboard. -constexpr char16_t kFilesAppMimeTag[] = u"fs/tag"; -constexpr char16_t kFilesAppTagExo[] = u"exo"; constexpr char16_t kFilesAppMimeSources[] = u"fs/sources"; -constexpr char kFilesAppSeparator[] = "\n"; constexpr char16_t kFilesAppSeparator16[] = u"\n"; storage::FileSystemContext* GetFileSystemContext() { @@ -411,26 +408,6 @@ void ChromeDataExchangeDelegate::SendPickle(ui::EndpointType target, base::BindOnce(&SendAfterShare, target, std::move(callback))); } -base::Pickle ChromeDataExchangeDelegate::CreateClipboardFilenamesPickle( - ui::EndpointType source, - const std::vector<uint8_t>& data) const { - std::vector<std::string> filenames; - std::vector<FileInfo> file_info = TranslateVMToHost( - source, ui::URIListToFileInfos(std::string(data.begin(), data.end()))); - for (const auto& info : file_info) { - if (info.url.is_valid()) - filenames.push_back(info.url.ToGURL().spec()); - } - base::Pickle pickle; - ui::WriteCustomDataToPickle( - std::unordered_map<std::u16string, std::u16string>( - {{kFilesAppMimeTag, kFilesAppTagExo}, - {kFilesAppMimeSources, base::UTF8ToUTF16(base::JoinString( - filenames, kFilesAppSeparator))}}), - &pickle); - return pickle; -} - std::vector<ui::FileInfo> ChromeDataExchangeDelegate::ParseFileSystemSources( const ui::DataTransferEndpoint* source, const base::Pickle& pickle) const { diff --git a/chrome/browser/chromeos/exo/chrome_data_exchange_delegate.h b/chrome/browser/chromeos/exo/chrome_data_exchange_delegate.h index 8c320f94e53642..44dbf68a932c1a 100644 --- a/chrome/browser/chromeos/exo/chrome_data_exchange_delegate.h +++ b/chrome/browser/chromeos/exo/chrome_data_exchange_delegate.h @@ -47,9 +47,6 @@ class ChromeDataExchangeDelegate : public exo::DataExchangeDelegate { void SendPickle(ui::EndpointType target, const base::Pickle& pickle, SendDataCallback callback) override; - base::Pickle CreateClipboardFilenamesPickle( - ui::EndpointType source, - const std::vector<uint8_t>& data) const override; std::vector<ui::FileInfo> ParseFileSystemSources( const ui::DataTransferEndpoint* source, const base::Pickle& pickle) const override; diff --git a/chrome/browser/chromeos/exo/chrome_data_exchange_delegate_unittest.cc b/chrome/browser/chromeos/exo/chrome_data_exchange_delegate_unittest.cc index 8e910ab828d8e4..58a30542491d3e 100644 --- a/chrome/browser/chromeos/exo/chrome_data_exchange_delegate_unittest.cc +++ b/chrome/browser/chromeos/exo/chrome_data_exchange_delegate_unittest.cc @@ -452,21 +452,16 @@ TEST_F(ChromeDataExchangeDelegateTest, ParseFileSystemSources) { guest_os::GuestOsSharePath::GetForProfile(profile()); guest_os_share_path->RegisterSharedPath(crostini::kCrostiniDefaultVmName, shared_path); - base::Pickle pickle = data_exchange_delegate.CreateClipboardFilenamesPickle( - ui::EndpointType::kCrostini, - Data("file:///mnt/chromeos/MyFiles/shared/file1\n" - "file:///mnt/chromeos/MyFiles/shared/file2")); - - std::unordered_map<std::u16string, std::u16string> m; - ui::ReadCustomDataIntoMap(pickle.data(), pickle.size(), &m); - EXPECT_EQ(2, m.size()); - EXPECT_EQ("exo", base::UTF16ToUTF8(m[u"fs/tag"])); - EXPECT_EQ( - "filesystem:chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/external/" - "Downloads-test%2540example.com-hash/shared/file1\n" - "filesystem:chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/external/" - "Downloads-test%2540example.com-hash/shared/file2", - base::UTF16ToUTF8(m[u"fs/sources"])); + std::u16string urls = + u"filesystem:chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/" + "external/Downloads-test%2540example.com-hash/shared/file1\n" + "filesystem:chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/" + "external/Downloads-test%2540example.com-hash/shared/file2"; + base::Pickle pickle; + ui::WriteCustomDataToPickle( + std::unordered_map<std::u16string, std::u16string>( + {{u"fs/tag", u"exo"}, {u"fs/sources", urls}}), + &pickle); ui::DataTransferEndpoint files_app(url::Origin::Create( GURL("chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj"))); diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 2601a2bfb01ef4..2f18f7e98ddc9d 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json @@ -601,11 +601,6 @@ ], "expiry_milestone": 92 }, - { - "name": "clipboard-filenames", - "owners": [ "joelhockey" ], - "expiry_milestone": 96 - }, { "name": "collections-card-presentation-style", "owners": [ "sczs", "bling-flags@google.com" ], diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index fd13fbc1ed240e..e7cf099cc67ea5 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc @@ -432,10 +432,6 @@ const char kClientStorageAccessContextAuditingName[] = const char kClientStorageAccessContextAuditingDescription[] = "Record the first-party contexts in which client-side storage was accessed"; -const char kClipboardFilenamesName[] = "Clipboard filenames"; -const char kClipboardFilenamesDescription[] = - "Support reading files in clipboard DataTransfer"; - const char kClearCrossSiteCrossBrowsingContextGroupWindowNameName[] = "Clear window name in top-level cross-site cross-browsing-context-group " "navigation"; diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index fb8b879deb3f18..6048eec0002ee1 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h @@ -254,9 +254,6 @@ extern const char kClickToOpenPDFDescription[]; extern const char kClientStorageAccessContextAuditingName[]; extern const char kClientStorageAccessContextAuditingDescription[]; -extern const char kClipboardFilenamesName[]; -extern const char kClipboardFilenamesDescription[]; - extern const char kConditionalTabStripAndroidName[]; extern const char kConditionalTabStripAndroidDescription[]; diff --git a/components/exo/data_exchange_delegate.h b/components/exo/data_exchange_delegate.h index 4bbd623d3b81f1..3a70767abd4852 100644 --- a/components/exo/data_exchange_delegate.h +++ b/components/exo/data_exchange_delegate.h @@ -67,14 +67,6 @@ class DataExchangeDelegate { const base::Pickle& pickle, SendDataCallback callback) = 0; - // Reads filenames from text/uri-list |data| which was provided by |source| - // endpoint. Translates paths into filesystem URLs suitable for FilesApp by - // setting custom mime type fs/tag to 'exo' and fs/sources with - // newline-separated filesystem URLs. - virtual base::Pickle CreateClipboardFilenamesPickle( - ui::EndpointType source, - const std::vector<uint8_t>& data) const = 0; - // Reads pickle for FilesApp fs/sources with newline-separated filesystem // URLs. Validates that |source| is FilesApp. virtual std::vector<ui::FileInfo> ParseFileSystemSources( diff --git a/components/exo/seat.cc b/components/exo/seat.cc index 363f07057189fe..dd09411b62e0f4 100644 --- a/components/exo/seat.cc +++ b/components/exo/seat.cc @@ -11,7 +11,6 @@ #include "base/barrier_closure.h" #include "base/bind.h" #include "base/callback_helpers.h" -#include "base/feature_list.h" #include "base/memory/weak_ptr.h" #include "base/pickle.h" #include "base/strings/utf_string_conversions.h" @@ -32,7 +31,6 @@ #include "ui/base/clipboard/clipboard_monitor.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/data_transfer_policy/data_transfer_endpoint.h" -#include "ui/base/ui_base_features.h" #include "ui/events/event_utils.h" #include "ui/events/platform/platform_event_source.h" #include "ui/gfx/geometry/point_f.h" @@ -238,18 +236,9 @@ void Seat::OnFilenamesRead( base::OnceClosure callback, const std::string& mime_type, const std::vector<uint8_t>& data) { - if (base::FeatureList::IsEnabled(features::kClipboardFilenames)) { - std::vector<ui::FileInfo> filenames = - data_exchange_delegate_->GetFilenames(source, data); - writer->WriteFilenames(ui::FileInfosToURIList(filenames)); - } else { - // There is no need for CreateClipboardFilenamesPickle() once - // chrome://flags#clipboard-filenames is permanently enabled. - base::Pickle pickle = - data_exchange_delegate_->CreateClipboardFilenamesPickle(source, data); - writer->WritePickledData(pickle, - ui::ClipboardFormatType::GetWebCustomDataType()); - } + std::vector<ui::FileInfo> filenames = + data_exchange_delegate_->GetFilenames(source, data); + writer->WriteFilenames(ui::FileInfosToURIList(filenames)); std::move(callback).Run(); } diff --git a/components/exo/seat_unittest.cc b/components/exo/seat_unittest.cc index 2942c6ac3941bf..0bee86ac45966e 100644 --- a/components/exo/seat_unittest.cc +++ b/components/exo/seat_unittest.cc @@ -9,7 +9,6 @@ #include "base/pickle.h" #include "base/strings/utf_string_conversions.h" #include "base/task/thread_pool/thread_pool_instance.h" -#include "base/test/scoped_feature_list.h" #include "components/exo/data_source.h" #include "components/exo/data_source_delegate.h" #include "components/exo/seat_observer.h" @@ -21,7 +20,6 @@ #include "ui/base/clipboard/clipboard_format_type.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h" -#include "ui/base/ui_base_features.h" #include "ui/events/event.h" #include "ui/events/event_utils.h" @@ -326,9 +324,6 @@ TEST_F(SeatTest, SetSelectionRTF) { } TEST_F(SeatTest, SetSelectionFilenames) { - base::test::ScopedFeatureList features; - features.InitWithFeatures({features::kClipboardFilenames}, {}); - TestSeat seat; Surface focused_surface; seat.set_focused_surface(&focused_surface); @@ -351,33 +346,6 @@ TEST_F(SeatTest, SetSelectionFilenames) { EXPECT_EQ(ui::FileInfosToURIList(filenames), data); } -TEST_F(SeatTest, SetSelectionFilenamesClipboardFilesDisabled) { - base::test::ScopedFeatureList features; - features.InitWithFeatures({}, {features::kClipboardFilenames}); - - TestSeat seat; - Surface focused_surface; - seat.set_focused_surface(&focused_surface); - - TestDataSourceDelegate delegate; - DataSource source(&delegate); - source.Offer("text/uri-list"); - seat.SetSelection(&source); - - RunReadingTask(); - - std::string data; - ui::Clipboard::GetForCurrentThread()->ReadData( - ui::ClipboardFormatType::GetWebCustomDataType(), - /*data_dst=*/nullptr, &data); - base::Pickle pickle(data.c_str(), data.size()); - std::string clipboard; - base::PickleIterator iter(pickle); - EXPECT_TRUE(iter.ReadString(&clipboard)); - - EXPECT_EQ(clipboard, std::string("TestData")); -} - TEST_F(SeatTest, SetSelection_TwiceSame) { TestSeat seat; Surface focused_surface; diff --git a/components/exo/test/exo_test_data_exchange_delegate.cc b/components/exo/test/exo_test_data_exchange_delegate.cc index 550389e0c55297..56cd01173dc54a 100644 --- a/components/exo/test/exo_test_data_exchange_delegate.cc +++ b/components/exo/test/exo_test_data_exchange_delegate.cc @@ -83,14 +83,6 @@ void TestDataExchangeDelegate::RunSendPickleCallback(std::vector<GURL> urls) { .Run(base::RefCountedString::TakeString(&result)); } -base::Pickle TestDataExchangeDelegate::CreateClipboardFilenamesPickle( - ui::EndpointType source, - const std::vector<uint8_t>& data) const { - base::Pickle result; - result.WriteData(reinterpret_cast<const char*>(data.data()), data.size()); - return result; -} - std::vector<ui::FileInfo> TestDataExchangeDelegate::ParseFileSystemSources( const ui::DataTransferEndpoint* source, const base::Pickle& pickle) const { diff --git a/components/exo/test/exo_test_data_exchange_delegate.h b/components/exo/test/exo_test_data_exchange_delegate.h index 9daeb28399c8cc..a428f2f3da4e04 100644 --- a/components/exo/test/exo_test_data_exchange_delegate.h +++ b/components/exo/test/exo_test_data_exchange_delegate.h @@ -34,9 +34,6 @@ class TestDataExchangeDelegate : public DataExchangeDelegate { void SendPickle(ui::EndpointType target, const base::Pickle& pickle, SendDataCallback callback) override; - base::Pickle CreateClipboardFilenamesPickle( - ui::EndpointType source, - const std::vector<uint8_t>& data) const override; std::vector<ui::FileInfo> ParseFileSystemSources( const ui::DataTransferEndpoint* source, const base::Pickle& pickle) const override; diff --git a/content/browser/file_system_access/file_system_access_clipboard_browsertest.cc b/content/browser/file_system_access/file_system_access_clipboard_browsertest.cc index b65b5b5e3beac4..d560beb05d830b 100644 --- a/content/browser/file_system_access/file_system_access_clipboard_browsertest.cc +++ b/content/browser/file_system_access/file_system_access_clipboard_browsertest.cc @@ -6,7 +6,6 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" -#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -20,7 +19,6 @@ #include "ui/base/clipboard/file_info.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/clipboard/test/test_clipboard.h" -#include "ui/base/ui_base_features.h" namespace content { @@ -32,7 +30,6 @@ class FileSystemAccessClipboardBrowserTest : public ContentBrowserTest { void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); ASSERT_TRUE(embedded_test_server()->Start()); - features_.InitWithFeatures({features::kClipboardFilenames}, {}); ui::TestClipboard::CreateForCurrentThread(); ContentBrowserTest::SetUp(); } @@ -61,7 +58,6 @@ class FileSystemAccessClipboardBrowserTest : public ContentBrowserTest { protected: base::ScopedTempDir temp_dir_; - base::test::ScopedFeatureList features_; }; IN_PROC_BROWSER_TEST_F(FileSystemAccessClipboardBrowserTest, File) { @@ -172,58 +168,4 @@ IN_PROC_BROWSER_TEST_F(FileSystemAccessClipboardBrowserTest, Directory) { EXPECT_EQ(file_inside_dir.BaseName().AsUTF8Unsafe(), EvalJs(shell(), "p")); } -class FileSystemAccessClipboardDisabledBrowserTest : public ContentBrowserTest { - public: - void SetUp() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - ASSERT_TRUE(embedded_test_server()->Start()); - features_.InitWithFeatures({}, {features::kClipboardFilenames}); - ContentBrowserTest::SetUp(); - } - - void TearDown() override { - ContentBrowserTest::TearDown(); - ASSERT_TRUE(temp_dir_.Delete()); - } - - protected: - base::ScopedTempDir temp_dir_; - base::test::ScopedFeatureList features_; -}; - -IN_PROC_BROWSER_TEST_F(FileSystemAccessClipboardDisabledBrowserTest, Disabled) { - ASSERT_TRUE( - NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"))); - - // Create a promise that will reject if clipboard contains any files. - ASSERT_TRUE( - ExecJs(shell(), - "var p = new Promise((resolve, reject) => {" - " window.document.onpaste = async (event) => {" - " if (event.clipboardData.files.length !== 0) {" - " reject('There were ' + event.clipboardData.files.length +" - " ' clipboard files. Expected 0.');" - " }" - " resolve(true);" - " };" - "});")); - - // Create a file and place on the clipboard. - base::FilePath test_file_path; - { - base::ScopedAllowBlockingForTesting allow_blocking; - EXPECT_TRUE( - base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &test_file_path)); - } - { - ui::ScopedClipboardWriter writer(ui::ClipboardBuffer::kCopyPaste); - writer.WriteFilenames(ui::FileInfosToURIList( - {ui::FileInfo(test_file_path, base::FilePath())})); - } - - // Send paste event and wait for JS promise to resolve. - shell()->web_contents()->Paste(); - EXPECT_EQ(true, EvalJs(shell(), "p")); -} - } // namespace content diff --git a/content/browser/renderer_host/clipboard_host_impl.cc b/content/browser/renderer_host/clipboard_host_impl.cc index 3981ffdd7c6c09..61ad2a1f7ad039 100644 --- a/content/browser/renderer_host/clipboard_host_impl.cc +++ b/content/browser/renderer_host/clipboard_host_impl.cc @@ -8,7 +8,6 @@ #include <utility> #include "base/bind.h" -#include "base/feature_list.h" #include "base/location.h" #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -44,7 +43,6 @@ #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/data_transfer_policy/data_transfer_endpoint.h" #include "ui/base/data_transfer_policy/data_transfer_policy_controller.h" -#include "ui/base/ui_base_features.h" #include "url/gurl.h" namespace content { @@ -389,11 +387,6 @@ void ClipboardHostImpl::ReadFiles(ui::ClipboardBuffer clipboard_buffer, return; } - if (!base::FeatureList::IsEnabled(features::kClipboardFilenames)) { - std::move(callback).Run(std::move(result)); - return; - } - std::vector<ui::FileInfo> filenames; auto data_dst = CreateDataEndpoint(); clipboard_->ReadFilenames(clipboard_buffer, data_dst.get(), &filenames); diff --git a/content/browser/renderer_host/clipboard_host_impl_browsertest.cc b/content/browser/renderer_host/clipboard_host_impl_browsertest.cc index 61f79c7e4b759a..bc125469c3ad4c 100644 --- a/content/browser/renderer_host/clipboard_host_impl_browsertest.cc +++ b/content/browser/renderer_host/clipboard_host_impl_browsertest.cc @@ -8,7 +8,6 @@ #include "base/base_paths.h" #include "base/files/file_util.h" #include "base/path_service.h" -#include "base/test/scoped_feature_list.h" #include "base/threading/thread_restrictions.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -20,7 +19,6 @@ #include "ui/base/clipboard/file_info.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/clipboard/test/test_clipboard.h" -#include "ui/base/ui_base_features.h" namespace content { @@ -35,7 +33,6 @@ class ClipboardHostImplBrowserTest : public ContentBrowserTest { void SetUp() override { ASSERT_TRUE(embedded_test_server()->Start()); - features_.InitWithFeatures({features::kClipboardFilenames}, {}); ui::TestClipboard::CreateForCurrentThread(); ContentBrowserTest::SetUp(); } @@ -97,9 +94,6 @@ class ClipboardHostImplBrowserTest : public ContentBrowserTest { shell()->web_contents()->Paste(); EXPECT_EQ(base::JoinString(expected, ","), EvalJs(shell(), "p")); } - - protected: - base::test::ScopedFeatureList features_; }; IN_PROC_BROWSER_TEST_F(ClipboardHostImplBrowserTest, TextFile) { diff --git a/third_party/blink/renderer/core/clipboard/data_object.cc b/third_party/blink/renderer/core/clipboard/data_object.cc index 58d1c47df2c51e..ee6da6d30a9c9e 100644 --- a/third_party/blink/renderer/core/clipboard/data_object.cc +++ b/third_party/blink/renderer/core/clipboard/data_object.cc @@ -30,7 +30,6 @@ #include "third_party/blink/renderer/core/clipboard/data_object.h" -#include "base/feature_list.h" #include "base/notreached.h" #include "third_party/blink/public/platform/file_path_conversion.h" #include "third_party/blink/public/platform/platform.h" @@ -42,7 +41,6 @@ #include "third_party/blink/renderer/core/clipboard/system_clipboard.h" #include "third_party/blink/renderer/platform/file_metadata.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" -#include "ui/base/ui_base_features.h" namespace blink { @@ -58,8 +56,7 @@ DataObject* DataObject::CreateFromClipboard(SystemClipboard* system_clipboard, if (paste_mode == PasteMode::kPlainTextOnly && type != kMimeTypeTextPlain) continue; mojom::blink::ClipboardFilesPtr files; - if (type == kMimeTypeTextURIList && - base::FeatureList::IsEnabled(features::kClipboardFilenames)) { + if (type == kMimeTypeTextURIList) { files = system_clipboard->ReadFiles(); // Ignore ReadFiles() result if clipboard sequence number has changed. if (system_clipboard->SequenceNumber() != sequence_number) { diff --git a/ui/base/clipboard/clipboard_mac.mm b/ui/base/clipboard/clipboard_mac.mm index 360a92aeef0962..77ecc9894e8b89 100644 --- a/ui/base/clipboard/clipboard_mac.mm +++ b/ui/base/clipboard/clipboard_mac.mm @@ -9,7 +9,6 @@ #include <limits> -#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/logging.h" #include "base/mac/foundation_util.h" @@ -32,7 +31,6 @@ #include "ui/base/clipboard/clipboard_util_mac.h" #include "ui/base/clipboard/custom_data_helper.h" #include "ui/base/data_transfer_policy/data_transfer_endpoint.h" -#include "ui/base/ui_base_features.h" #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" @@ -91,12 +89,6 @@ DCHECK(CalledOnValidThread()); DCHECK_EQ(buffer, ClipboardBuffer::kCopyPaste); - // Only support filenames if chrome://flags#clipboard-filenames is enabled. - if (format == ClipboardFormatType::GetFilenamesType() && - !base::FeatureList::IsEnabled(features::kClipboardFilenames)) { - return false; - } - // https://crbug.com/1016740#c21 base::scoped_nsobject<NSArray> types([[GetPasteboard() types] retain]); @@ -493,22 +485,8 @@ // a blank image is better. base::scoped_nsobject<NSImage> image; @try { - // TODO(crbug.com/1175483): remove first branch of this code when - // ClipboardFilenames feature flag is removed. - if ([[pasteboard types] containsObject:NSFilenamesPboardType]) { - // -[NSImage initWithPasteboard:] gets confused with copies of a single - // file from the Finder, so extract the path ourselves. - // http://crbug.com/553686 - NSArray* paths = [pasteboard propertyListForType:NSFilenamesPboardType]; - if ([paths count]) { - // If N number of files are selected from finder, choose the last one. - image.reset([[NSImage alloc] - initWithContentsOfURL:[NSURL fileURLWithPath:[paths lastObject]]]); - } - } else { - if (pasteboard) - image.reset([[NSImage alloc] initWithPasteboard:pasteboard]); - } + if (pasteboard) + image.reset([[NSImage alloc] initWithPasteboard:pasteboard]); } @catch (id exception) { } if (!image) diff --git a/ui/base/clipboard/clipboard_non_backed.cc b/ui/base/clipboard/clipboard_non_backed.cc index dfebf6daba0d47..2cf2dc1c431079 100644 --- a/ui/base/clipboard/clipboard_non_backed.cc +++ b/ui/base/clipboard/clipboard_non_backed.cc @@ -14,7 +14,6 @@ #include "base/check_op.h" #include "base/containers/contains.h" -#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -33,7 +32,6 @@ #include "ui/base/clipboard/custom_data_helper.h" #include "ui/base/data_transfer_policy/data_transfer_endpoint.h" #include "ui/base/data_transfer_policy/data_transfer_policy_controller.h" -#include "ui/base/ui_base_features.h" #include "ui/gfx/geometry/size.h" namespace ui { @@ -452,8 +450,7 @@ bool ClipboardNonBacked::IsFormatAvailable( return clipboard_internal_->IsFormatAvailable( ClipboardInternalFormat::kWeb); // Only support filenames if chrome://flags#clipboard-filenames is enabled. - if (format == ClipboardFormatType::GetFilenamesType() && - base::FeatureList::IsEnabled(features::kClipboardFilenames)) + if (format == ClipboardFormatType::GetFilenamesType()) return clipboard_internal_->IsFormatAvailable( ClipboardInternalFormat::kFilenames); const ClipboardData* data = clipboard_internal_->GetData(); diff --git a/ui/base/clipboard/clipboard_non_backed_unittest.cc b/ui/base/clipboard/clipboard_non_backed_unittest.cc index 963dbc4297f213..02dca6729b19b2 100644 --- a/ui/base/clipboard/clipboard_non_backed_unittest.cc +++ b/ui/base/clipboard/clipboard_non_backed_unittest.cc @@ -10,10 +10,8 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/clipboard/clipboard_data.h" -#include "ui/base/ui_base_features.h" namespace ui { namespace { @@ -92,8 +90,6 @@ TEST_F(ClipboardNonBackedTest, AdminWriteDoesNotRecordHistograms) { // Tests that site bookmark URLs are accessed as text, and // IsFormatAvailable('text/uri-list') is only true for files. TEST_F(ClipboardNonBackedTest, TextURIList) { - base::test::ScopedFeatureList features; - features.InitWithFeatures({features::kClipboardFilenames}, {}); EXPECT_EQ("text/uri-list", ClipboardFormatType::GetFilenamesType().GetName()); auto data = std::make_unique<ClipboardData>(); diff --git a/ui/base/clipboard/clipboard_test_template.h b/ui/base/clipboard/clipboard_test_template.h index 8b4caf8a2dc7b6..9dc28830b916b8 100644 --- a/ui/base/clipboard/clipboard_test_template.h +++ b/ui/base/clipboard/clipboard_test_template.h @@ -28,7 +28,6 @@ #include "base/run_loop.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_feature_list.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "build/chromecast_buildflags.h" @@ -48,7 +47,6 @@ #include "ui/base/clipboard/test/test_clipboard.h" #include "ui/base/data_transfer_policy/data_transfer_endpoint.h" #include "ui/base/data_transfer_policy/data_transfer_policy_controller.h" -#include "ui/base/ui_base_features.h" #include "ui/gfx/codec/png_codec.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/half_float.h" @@ -421,8 +419,6 @@ TYPED_TEST(ClipboardTest, BookmarkTest) { #if !defined(OS_ANDROID) // Filenames is not implemented in ClipboardAndroid. TYPED_TEST(ClipboardTest, FilenamesTest) { - base::test::ScopedFeatureList features; - features.InitWithFeatures({features::kClipboardFilenames}, {}); base::ScopedAllowBlockingForTesting allow_blocking; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); diff --git a/ui/base/clipboard/clipboard_win.cc b/ui/base/clipboard/clipboard_win.cc index 67d0680f1db6c0..c2df77803f30ad 100644 --- a/ui/base/clipboard/clipboard_win.cc +++ b/ui/base/clipboard/clipboard_win.cc @@ -13,7 +13,6 @@ #include "base/bind.h" #include "base/check_op.h" -#include "base/feature_list.h" #include "base/files/file_path.h" #include "base/lazy_instance.h" #include "base/macros.h" @@ -39,7 +38,6 @@ #include "ui/base/clipboard/clipboard_util_win.h" #include "ui/base/clipboard/custom_data_helper.h" #include "ui/base/data_transfer_policy/data_transfer_endpoint.h" -#include "ui/base/ui_base_features.h" #include "ui/gfx/canvas.h" #include "ui/gfx/codec/png_codec.h" #include "ui/gfx/geometry/size.h" @@ -224,10 +222,6 @@ void TrimAfterNull(StringType* result) { } bool ReadFilenamesAvailable() { - // Only support filenames if chrome://flags#clipboard-filenames is enabled. - if (!base::FeatureList::IsEnabled(features::kClipboardFilenames)) - return false; - return ::IsClipboardFormatAvailable( ClipboardFormatType::GetCFHDropType().ToFormatEtc().cfFormat) || ::IsClipboardFormatAvailable( diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc index 7c92a785ba407b..b183e7935ae229 100644 --- a/ui/base/ui_base_features.cc +++ b/ui/base/ui_base_features.cc @@ -32,11 +32,6 @@ const base::Feature kScreenPowerListenerForNativeWinOcclusion{ base::FEATURE_ENABLED_BY_DEFAULT}; #endif // OW_WIN -// Whether or not filenames are supported on the clipboard. -// https://crbug.com/1175483 -const base::Feature kClipboardFilenames{"ClipboardFilenames", - base::FEATURE_ENABLED_BY_DEFAULT}; - // Whether or not to delegate color queries to the color provider. const base::Feature kColorProviderRedirection = { "ColorProviderRedirection", base::FEATURE_DISABLED_BY_DEFAULT}; diff --git a/ui/base/ui_base_features.h b/ui/base/ui_base_features.h index a63d05580cd139..7e2ebc5d74bb6b 100644 --- a/ui/base/ui_base_features.h +++ b/ui/base/ui_base_features.h @@ -15,8 +15,6 @@ namespace features { // Keep sorted! -COMPONENT_EXPORT(UI_BASE_FEATURES) -extern const base::Feature kClipboardFilenames; COMPONENT_EXPORT(UI_BASE_FEATURES) extern const base::Feature kColorProviderRedirection; COMPONENT_EXPORT(UI_BASE_FEATURES) diff --git a/ui/base/x/x11_clipboard_helper.cc b/ui/base/x/x11_clipboard_helper.cc index b04c0188354515..1d10ca88ec406d 100644 --- a/ui/base/x/x11_clipboard_helper.cc +++ b/ui/base/x/x11_clipboard_helper.cc @@ -223,11 +223,8 @@ std::vector<std::string> XClipboardHelper::GetAvailableTypes( available_types.push_back(kMimeTypeRTF); if (target_list.ContainsFormat(ClipboardFormatType::GetBitmapType())) available_types.push_back(kMimeTypePNG); - // Only support filenames if chrome://flags#clipboard-filenames is enabled. - if (target_list.ContainsFormat(ClipboardFormatType::GetFilenamesType()) && - base::FeatureList::IsEnabled(features::kClipboardFilenames)) { + if (target_list.ContainsFormat(ClipboardFormatType::GetFilenamesType())) available_types.push_back(kMimeTypeURIList); - } return available_types; } From 2e80500e250894172348faf57bb181a134bd1c6c Mon Sep 17 00:00:00 2001 From: Ross McIlroy <rmcilroy@chromium.org> Date: Tue, 1 Jun 2021 11:51:51 +0000 Subject: [PATCH 44/81] [gin] Failing to load the V8 startup snapshot is a fatal error. BUG=chromium:1208472 Change-Id: Ib784c85c228980dfb5241496f6bb704c17fd3c3e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2919734 Commit-Queue: Dan Elphick <delphick@chromium.org> Auto-Submit: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Dan Elphick <delphick@chromium.org> Cr-Commit-Position: refs/heads/master@{#887921} --- gin/v8_initializer.cc | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc index f4d6372c79a7e0..8bac97b6809a1f 100644 --- a/gin/v8_initializer.cc +++ b/gin/v8_initializer.cc @@ -185,14 +185,6 @@ base::File OpenV8File(const char* file_name, return file; } -enum LoadV8FileResult { - V8_LOAD_SUCCESS = 0, - V8_LOAD_FAILED_OPEN, - V8_LOAD_FAILED_MAP, - V8_LOAD_FAILED_VERIFY, // Deprecated. - V8_LOAD_MAX_VALUE -}; - #endif // defined(V8_USE_EXTERNAL_STARTUP_DATA) template <int LENGTH> @@ -210,7 +202,6 @@ void SetV8FlagsFormatted(const char* format, ...) { return; } v8::V8::SetFlagsFromString(buffer, length - 1); - ; } } // namespace @@ -379,8 +370,7 @@ void V8Initializer::LoadV8SnapshotFromFile( return; if (!snapshot_file.IsValid()) { - UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", - V8_LOAD_FAILED_OPEN, V8_LOAD_MAX_VALUE); + LOG(FATAL) << "Error loading V8 startup snapshot file"; return; } @@ -390,11 +380,10 @@ void V8Initializer::LoadV8SnapshotFromFile( region = *snapshot_file_region; } - LoadV8FileResult result = V8_LOAD_SUCCESS; - if (!MapV8File(std::move(snapshot_file), region, &g_mapped_snapshot)) - result = V8_LOAD_FAILED_MAP; - UMA_HISTOGRAM_ENUMERATION("V8.Initializer.LoadV8Snapshot.Result", result, - V8_LOAD_MAX_VALUE); + if (!MapV8File(std::move(snapshot_file), region, &g_mapped_snapshot)) { + LOG(FATAL) << "Error mapping V8 startup snapshot file"; + return; + } } #if defined(OS_ANDROID) From 20567925655ca5c47ae13c1e20c18a9b56032306 Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 12:00:52 +0000 Subject: [PATCH 45/81] Roll Perfetto from bb3b66d48669 to 44702c57e7e6 (1 revision) https://android.googlesource.com/platform/external/perfetto.git/+log/bb3b66d48669..44702c57e7e6 2021-06-01 treehugger-gerrit@google.com Merge "Avoid invalid reads parsing begin print events" If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/perfetto-chromium-autoroll Please CC perfetto-bugs@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chromium.try:linux-perfetto-rel Bug: None Tbr: perfetto-bugs@google.com Change-Id: I03a25cd732c0b29d43b3d892e8f5c293e6521b56 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928325 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887922} --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 87619293790e70..a924c9e229206e 100644 --- a/DEPS +++ b/DEPS @@ -1349,7 +1349,7 @@ deps = { }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'bb3b66d486694c9984e76d38e3bd7ca525edfee2', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '44702c57e7e6a294a58b8ea35879fc58842f2995', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', From 634f08a5c2ce827c042db1dfea7da70650b49b12 Mon Sep 17 00:00:00 2001 From: Ioana Pandele <ioanap@chromium.org> Date: Tue, 1 Jun 2021 12:05:11 +0000 Subject: [PATCH 46/81] [PwdEditAndroid] Set the UI action handler last Setting it after the initial binding ensures that it will be active only after the UI has been fully initialized. Before this change, the text change listener could have cause the model to update to the wrong value (empty password) before the change in the model had any chance to propagate to the view. Bug: 1213843 Change-Id: I28cff9e03c7458325b40f67c7214b962a47c8a93 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928524 Reviewed-by: Friedrich [CET] <fhorschig@chromium.org> Commit-Queue: Ioana Pandele <ioanap@chromium.org> Cr-Commit-Position: refs/heads/master@{#887923} --- .../password_entry_edit/CredentialEditCoordinator.java | 2 +- .../browser/password_entry_edit/CredentialEditProperties.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditCoordinator.java b/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditCoordinator.java index cbd234ccefd327..b55928d63a53f4 100644 --- a/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditCoordinator.java +++ b/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditCoordinator.java @@ -68,7 +68,6 @@ interface CredentialActionDelegate { void setCredential(String displayUrlOrAppName, String username, String password, String displayFederationOrigin, boolean isInsecureCredential) { mModel = new PropertyModel.Builder(ALL_KEYS) - .with(UI_ACTION_HANDLER, mMediator) .with(URL_OR_APP, displayUrlOrAppName) .with(FEDERATION_ORIGIN, displayFederationOrigin) .build(); @@ -93,6 +92,7 @@ void handleHelp() { @Override public void onStartFragment() { CredentialEditCoordinator.setupModelChangeProcessor(mModel, mFragmentView); + mModel.set(UI_ACTION_HANDLER, mMediator); } @Override diff --git a/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditProperties.java b/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditProperties.java index 9d60a72d66b794..1f1e7f6781b78e 100644 --- a/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditProperties.java +++ b/chrome/browser/password_entry_edit/android/internal/java/src/org/chromium/chrome/browser/password_entry_edit/CredentialEditProperties.java @@ -12,8 +12,8 @@ * Properties defined here reflect the visible state of the credential edit UI. */ class CredentialEditProperties { - static final PropertyModel.ReadableObjectPropertyKey<UiActionHandler> UI_ACTION_HANDLER = - new PropertyModel.ReadableObjectPropertyKey<>("ui action handler"); + static final PropertyModel.WritableObjectPropertyKey<UiActionHandler> UI_ACTION_HANDLER = + new PropertyModel.WritableObjectPropertyKey<>("ui action handler"); static final PropertyModel.ReadableObjectPropertyKey<String> URL_OR_APP = new PropertyModel.ReadableObjectPropertyKey<>("url or app"); static final PropertyModel.WritableObjectPropertyKey<String> USERNAME = From 460cd161d5acca03c3e4a27f70c7f2843713bdc3 Mon Sep 17 00:00:00 2001 From: Maciek Slusarczyk <mslus@chromium.org> Date: Tue, 1 Jun 2021 12:08:44 +0000 Subject: [PATCH 47/81] Replace references to know_user with the new API calls in SAML tests. This cl updates references to the known_user with the new API format where local state is passed explicitly in all SAML tests. Bug: 1213458 Change-Id: If85442591645a9ca7a7f1e60b3cdf1eab6072ab5 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928759 Reviewed-by: Maksim Ivanov <emaxx@chromium.org> Reviewed-by: Denis Kuznetsov [CET] <antrim@chromium.org> Commit-Queue: Maciek Slusarczyk <mslus@chromium.org> Cr-Commit-Position: refs/heads/master@{#887924} --- ..._session_password_sync_manager_unittest.cc | 13 +++-- .../password_sync_token_verifier_unittest.cc | 39 ++++++-------- .../ash/login/saml/saml_browsertest.cc | 54 ++++++++++--------- 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/chrome/browser/ash/login/saml/in_session_password_sync_manager_unittest.cc b/chrome/browser/ash/login/saml/in_session_password_sync_manager_unittest.cc index 85d93966748c6f..b2731e85af1c56 100644 --- a/chrome/browser/ash/login/saml/in_session_password_sync_manager_unittest.cc +++ b/chrome/browser/ash/login/saml/in_session_password_sync_manager_unittest.cc @@ -89,6 +89,7 @@ class InSessionPasswordSyncManagerTest : public testing::Test { std::unique_ptr<MockLockHandler> lock_handler_; std::unique_ptr<InSessionPasswordSyncManager> manager_; base::test::ScopedFeatureList feature_list_; + std::unique_ptr<user_manager::KnownUser> known_user_; }; InSessionPasswordSyncManagerTest::InSessionPasswordSyncManagerTest() @@ -103,6 +104,8 @@ InSessionPasswordSyncManagerTest::InSessionPasswordSyncManagerTest() user_manager_ = static_cast<FakeChromeUserManager*>(user_manager::UserManager::Get()); + known_user_ = + std::make_unique<user_manager::KnownUser>(user_manager_->GetLocalState()); } InSessionPasswordSyncManagerTest::~InSessionPasswordSyncManagerTest() { @@ -235,9 +238,9 @@ TEST_F(InSessionPasswordSyncManagerTest, AuthenticateWithIncorrectUser) { TEST_F(InSessionPasswordSyncManagerTest, AuthenticateWithCorrectUser) { base::Time now = test_environment_.GetMockClock()->Now(); - user_manager::known_user::SetLastOnlineSignin(saml_login_account_id1_, now); - user_manager::known_user::SetOfflineSigninLimit(saml_login_account_id1_, - kSamlOnlineShortDelay); + known_user_->SetLastOnlineSignin(saml_login_account_id1_, now); + known_user_->SetOfflineSigninLimit(saml_login_account_id1_, + kSamlOnlineShortDelay); base::Time expected_signin_time = now + kSamlOnlineShortDelay; primary_profile_->GetPrefs()->SetBoolean( @@ -261,7 +264,7 @@ TEST_F(InSessionPasswordSyncManagerTest, AuthenticateWithCorrectUser) { manager_->OnAuthSuccess(user_context); EXPECT_EQ(InSessionReauthReason(), InSessionPasswordSyncManager::ReauthenticationReason::kNone); - now = user_manager::known_user::GetLastOnlineSignin(saml_login_account_id1_); + now = known_user_->GetLastOnlineSignin(saml_login_account_id1_); EXPECT_EQ(now, expected_signin_time); } @@ -292,7 +295,7 @@ TEST_F(InSessionPasswordSyncManagerTest, AuthenticateTokenNotInitialized) { InSessionPasswordSyncManager::ReauthenticationReason::kNone); EXPECT_FALSE(IsTokenFetcherCreated()); std::string sync_token = - user_manager::known_user::GetPasswordSyncToken(saml_login_account_id1_); + known_user_->GetPasswordSyncToken(saml_login_account_id1_); EXPECT_EQ(kFakeToken, sync_token); } diff --git a/chrome/browser/ash/login/saml/password_sync_token_verifier_unittest.cc b/chrome/browser/ash/login/saml/password_sync_token_verifier_unittest.cc index 1b906900aed374..4874cc4096b87a 100644 --- a/chrome/browser/ash/login/saml/password_sync_token_verifier_unittest.cc +++ b/chrome/browser/ash/login/saml/password_sync_token_verifier_unittest.cc @@ -77,6 +77,7 @@ class PasswordSyncTokenVerifierTest : public testing::Test { FakeChromeUserManager* user_manager_ = nullptr; std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_; std::unique_ptr<PasswordSyncTokenVerifier> verifier_; + std::unique_ptr<user_manager::KnownUser> known_user_; }; PasswordSyncTokenVerifierTest::PasswordSyncTokenVerifierTest() { @@ -87,6 +88,8 @@ PasswordSyncTokenVerifierTest::PasswordSyncTokenVerifierTest() { user_manager_ = static_cast<FakeChromeUserManager*>(user_manager::UserManager::Get()); + known_user_ = + std::make_unique<user_manager::KnownUser>(user_manager_->GetLocalState()); } PasswordSyncTokenVerifierTest::~PasswordSyncTokenVerifierTest() { @@ -132,8 +135,7 @@ TEST_F(PasswordSyncTokenVerifierTest, EmptySyncToken) { } TEST_F(PasswordSyncTokenVerifierTest, SyncTokenValidationPassed) { - user_manager::known_user::SetPasswordSyncToken(saml_login_account_id_, - kSyncToken); + known_user_->SetPasswordSyncToken(saml_login_account_id_, kSyncToken); CreatePasswordSyncTokenVerifier(); verifier_->CheckForPasswordNotInSync(); OnTokenVerified(true); @@ -141,8 +143,7 @@ TEST_F(PasswordSyncTokenVerifierTest, SyncTokenValidationPassed) { } TEST_F(PasswordSyncTokenVerifierTest, SyncTokenValidationFailed) { - user_manager::known_user::SetPasswordSyncToken(saml_login_account_id_, - kSyncToken); + known_user_->SetPasswordSyncToken(saml_login_account_id_, kSyncToken); CreatePasswordSyncTokenVerifier(); verifier_->CheckForPasswordNotInSync(); OnTokenVerified(false); @@ -150,8 +151,7 @@ TEST_F(PasswordSyncTokenVerifierTest, SyncTokenValidationFailed) { } TEST_F(PasswordSyncTokenVerifierTest, SyncTokenValidationAfterDelay) { - user_manager::known_user::SetPasswordSyncToken(saml_login_account_id_, - kSyncToken); + known_user_->SetPasswordSyncToken(saml_login_account_id_, kSyncToken); CreatePasswordSyncTokenVerifier(); verifier_->CheckForPasswordNotInSync(); OnTokenVerified(true); @@ -162,14 +162,12 @@ TEST_F(PasswordSyncTokenVerifierTest, SyncTokenValidationAfterDelay) { } TEST_F(PasswordSyncTokenVerifierTest, SyncTokenNoRecheckExecuted) { - user_manager::known_user::SetPasswordSyncToken(saml_login_account_id_, - kSyncToken); + known_user_->SetPasswordSyncToken(saml_login_account_id_, kSyncToken); CreatePasswordSyncTokenVerifier(); verifier_->CheckForPasswordNotInSync(); OnTokenVerified(true); EXPECT_FALSE(user_manager_->GetActiveUser()->force_online_signin()); - user_manager::known_user::SetPasswordSyncToken(saml_login_account_id_, - std::string()); + known_user_->SetPasswordSyncToken(saml_login_account_id_, std::string()); test_environment_.FastForwardBy(kSyncTokenCheckBelowInterval); EXPECT_FALSE(user_manager_->GetActiveUser()->force_online_signin()); } @@ -177,13 +175,11 @@ TEST_F(PasswordSyncTokenVerifierTest, SyncTokenNoRecheckExecuted) { TEST_F(PasswordSyncTokenVerifierTest, PasswordChangePolicyNotSet) { primary_profile_->GetPrefs()->SetBoolean( prefs::kSamlInSessionPasswordChangeEnabled, false); - user_manager::known_user::SetPasswordSyncToken(saml_login_account_id_, - kSyncToken); + known_user_->SetPasswordSyncToken(saml_login_account_id_, kSyncToken); CreatePasswordSyncTokenVerifier(); verifier_->CheckForPasswordNotInSync(); OnTokenVerified(true); - user_manager::known_user::SetPasswordSyncToken(saml_login_account_id_, - std::string()); + known_user_->SetPasswordSyncToken(saml_login_account_id_, std::string()); test_environment_.FastForwardBy(kSyncTokenCheckInterval); EXPECT_FALSE(user_manager_->GetActiveUser()->force_online_signin()); } @@ -192,9 +188,8 @@ TEST_F(PasswordSyncTokenVerifierTest, SyncTokenNotSet) { CreatePasswordSyncTokenVerifier(); verifier_->FetchSyncTokenOnReauth(); verifier_->OnTokenFetched(kSyncToken); - EXPECT_EQ( - user_manager::known_user::GetPasswordSyncToken(saml_login_account_id_), - kSyncToken); + EXPECT_EQ(known_user_->GetPasswordSyncToken(saml_login_account_id_), + kSyncToken); EXPECT_EQ( primary_profile_->GetPrefs()->GetString(prefs::kSamlPasswordSyncToken), kSyncToken); @@ -205,9 +200,8 @@ TEST_F(PasswordSyncTokenVerifierTest, InitialSyncTokenListEmpty) { verifier_->FetchSyncTokenOnReauth(); verifier_->OnApiCallFailed(PasswordSyncTokenFetcher::ErrorType::kGetNoList); verifier_->OnTokenCreated(kSyncToken); - EXPECT_EQ( - user_manager::known_user::GetPasswordSyncToken(saml_login_account_id_), - kSyncToken); + EXPECT_EQ(known_user_->GetPasswordSyncToken(saml_login_account_id_), + kSyncToken); EXPECT_EQ( primary_profile_->GetPrefs()->GetString(prefs::kSamlPasswordSyncToken), kSyncToken); @@ -219,9 +213,8 @@ TEST_F(PasswordSyncTokenVerifierTest, SyncTokenInitForUser) { // Token API not initilized for the user - request token creation. verifier_->OnTokenFetched(std::string()); verifier_->OnTokenCreated(kSyncToken); - EXPECT_EQ( - user_manager::known_user::GetPasswordSyncToken(saml_login_account_id_), - kSyncToken); + EXPECT_EQ(known_user_->GetPasswordSyncToken(saml_login_account_id_), + kSyncToken); EXPECT_EQ( primary_profile_->GetPrefs()->GetString(prefs::kSamlPasswordSyncToken), kSyncToken); diff --git a/chrome/browser/ash/login/saml/saml_browsertest.cc b/chrome/browser/ash/login/saml/saml_browsertest.cc index e5d75ebcf569ab..4bec55b82910fe 100644 --- a/chrome/browser/ash/login/saml/saml_browsertest.cc +++ b/chrome/browser/ash/login/saml/saml_browsertest.cc @@ -459,10 +459,11 @@ IN_PROC_BROWSER_TEST_F(SamlTest, CredentialPassingAPI) { FakeCryptohomeMiscClient::GetStubSystemSalt())); EXPECT_EQ(key.GetSecret(), cryptohome_client_->salted_hashed_secret()); - EXPECT_TRUE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI( - AccountId::FromUserEmailGaiaId( - saml_test_users::kFirstUserCorpExampleComEmail, - kFirstSAMLUserGaiaId))); + EXPECT_TRUE( + user_manager::KnownUser(user_manager::UserManager::Get()->GetLocalState()) + .GetIsUsingSAMLPrincipalsAPI(AccountId::FromUserEmailGaiaId( + saml_test_users::kFirstUserCorpExampleComEmail, + kFirstSAMLUserGaiaId))); histogram_tester.ExpectUniqueSample("ChromeOS.SAML.APILogin", 1, 1); histogram_tester.ExpectUniqueSample("ChromeOS.SAML.Provider", 1, 1); @@ -496,10 +497,11 @@ IN_PROC_BROWSER_TEST_F(SamlTest, CredentialPassingAPIWithoutConfirm) { FakeCryptohomeMiscClient::GetStubSystemSalt())); EXPECT_EQ(key.GetSecret(), cryptohome_client_->salted_hashed_secret()); - EXPECT_TRUE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI( - AccountId::FromUserEmailGaiaId( - saml_test_users::kFirstUserCorpExampleComEmail, - kFirstSAMLUserGaiaId))); + EXPECT_TRUE( + user_manager::KnownUser(user_manager::UserManager::Get()->GetLocalState()) + .GetIsUsingSAMLPrincipalsAPI(AccountId::FromUserEmailGaiaId( + saml_test_users::kFirstUserCorpExampleComEmail, + kFirstSAMLUserGaiaId))); histogram_tester.ExpectUniqueSample("ChromeOS.SAML.APILogin", 1, 1); histogram_tester.ExpectUniqueSample("ChromeOS.SAML.Provider", 1, 1); @@ -536,10 +538,11 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedSingle) { test::WaitForPrimaryUserSessionStart(); - EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI( - AccountId::FromUserEmailGaiaId( - saml_test_users::kFirstUserCorpExampleComEmail, - kFirstSAMLUserGaiaId))); + EXPECT_FALSE( + user_manager::KnownUser(user_manager::UserManager::Get()->GetLocalState()) + .GetIsUsingSAMLPrincipalsAPI(AccountId::FromUserEmailGaiaId( + saml_test_users::kFirstUserCorpExampleComEmail, + kFirstSAMLUserGaiaId))); histogram_tester.ExpectUniqueSample("ChromeOS.SAML.APILogin", 2, 1); histogram_tester.ExpectUniqueSample("ChromeOS.SAML.Scraping.PasswordCountAll", @@ -570,10 +573,11 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedDynamic) { SigninFrameJS().TapOn("Submit"); test::WaitForPrimaryUserSessionStart(); - EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI( - AccountId::FromUserEmailGaiaId( - saml_test_users::kFirstUserCorpExampleComEmail, - kFirstSAMLUserGaiaId))); + EXPECT_FALSE( + user_manager::KnownUser(user_manager::UserManager::Get()->GetLocalState()) + .GetIsUsingSAMLPrincipalsAPI(AccountId::FromUserEmailGaiaId( + saml_test_users::kFirstUserCorpExampleComEmail, + kFirstSAMLUserGaiaId))); } // Tests the multiple password scraped flow. @@ -599,10 +603,11 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedMultiple) { SendConfirmPassword("password1"); test::WaitForPrimaryUserSessionStart(); - EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI( - AccountId::FromUserEmailGaiaId( - saml_test_users::kFirstUserCorpExampleComEmail, - kFirstSAMLUserGaiaId))); + EXPECT_FALSE( + user_manager::KnownUser(user_manager::UserManager::Get()->GetLocalState()) + .GetIsUsingSAMLPrincipalsAPI(AccountId::FromUserEmailGaiaId( + saml_test_users::kFirstUserCorpExampleComEmail, + kFirstSAMLUserGaiaId))); histogram_tester.ExpectUniqueSample("ChromeOS.SAML.APILogin", 2, 1); histogram_tester.ExpectUniqueSample("ChromeOS.SAML.Scraping.PasswordCountAll", @@ -634,10 +639,11 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedNone) { SetManualPasswords("Test1", "Test1"); test::WaitForPrimaryUserSessionStart(); - EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI( - AccountId::FromUserEmailGaiaId( - saml_test_users::kFirstUserCorpExampleComEmail, - kFirstSAMLUserGaiaId))); + EXPECT_FALSE( + user_manager::KnownUser(user_manager::UserManager::Get()->GetLocalState()) + .GetIsUsingSAMLPrincipalsAPI(AccountId::FromUserEmailGaiaId( + saml_test_users::kFirstUserCorpExampleComEmail, + kFirstSAMLUserGaiaId))); histogram_tester.ExpectUniqueSample("ChromeOS.SAML.APILogin", 2, 1); histogram_tester.ExpectUniqueSample("ChromeOS.SAML.Scraping.PasswordCountAll", From 383de9c20b7417fef80245327cda39010d6cbdda Mon Sep 17 00:00:00 2001 From: Sam Zackrisson <saza@chromium.org> Date: Tue, 1 Jun 2021 12:10:10 +0000 Subject: [PATCH 48/81] Add metric for concurrent output streams during audio capture Change-Id: If4ba71667f14d3c1e8c98dd3269cb174d3f82369 Bug: chromium:1212676 Change-Id: If4ba71667f14d3c1e8c98dd3269cb174d3f82369 Tested: New unit test + opened video call and Youtube tabs and observed UMA logging events. Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2910112 Reviewed-by: Olga Sharonova <olka@chromium.org> Reviewed-by: Johannes Kron <kron@chromium.org> Commit-Queue: Sam Zackrisson <saza@chromium.org> Cr-Commit-Position: refs/heads/master@{#887925} --- services/audio/BUILD.gn | 2 + .../concurrent_stream_metric_reporter.cc | 44 ++++++ .../audio/concurrent_stream_metric_reporter.h | 51 +++++++ services/audio/input_controller.cc | 22 +-- services/audio/input_controller.h | 6 + services/audio/input_controller_unittest.cc | 35 ++++- services/audio/input_stream.cc | 8 +- services/audio/input_stream.h | 2 + services/audio/output_controller.cc | 46 ++++-- services/audio/output_controller.h | 13 ++ services/audio/output_controller_unittest.cc | 131 +++++++++++++++++- services/audio/output_stream.cc | 8 +- services/audio/output_stream.h | 2 + services/audio/stream_factory.cc | 8 +- services/audio/stream_factory.h | 3 + .../histograms_xml/media/histograms.xml | 14 ++ 16 files changed, 365 insertions(+), 30 deletions(-) create mode 100644 services/audio/concurrent_stream_metric_reporter.cc create mode 100644 services/audio/concurrent_stream_metric_reporter.h diff --git a/services/audio/BUILD.gn b/services/audio/BUILD.gn index 2112adf11fb70b..840aee92d0f456 100644 --- a/services/audio/BUILD.gn +++ b/services/audio/BUILD.gn @@ -8,6 +8,8 @@ import("//testing/test.gni") source_set("audio") { sources = [ + "concurrent_stream_metric_reporter.cc", + "concurrent_stream_metric_reporter.h", "debug_recording.cc", "debug_recording.h", "delay_buffer.cc", diff --git a/services/audio/concurrent_stream_metric_reporter.cc b/services/audio/concurrent_stream_metric_reporter.cc new file mode 100644 index 00000000000000..9dd995bf85e6eb --- /dev/null +++ b/services/audio/concurrent_stream_metric_reporter.cc @@ -0,0 +1,44 @@ +// Copyright 2021 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 "services/audio/concurrent_stream_metric_reporter.h" + +#include "base/metrics/histogram_functions.h" + +namespace audio { + +void ConcurrentStreamMetricReporter::OnInputStreamActive() { + ++active_input_stream_count_; + if (active_input_stream_count_ == 1) { + // Reset metric when recording starts. + max_concurrent_output_streams_metric_ = active_output_stream_count_; + } +} + +void ConcurrentStreamMetricReporter::OnInputStreamInactive() { + DCHECK_GE(active_input_stream_count_, 1); + --active_input_stream_count_; + if (active_input_stream_count_ == 0) { + // Report metric when recording ends. + base::UmaHistogramCustomCounts("Media.Audio.MaxOutputStreamsPerInputStream", + max_concurrent_output_streams_metric_, 1, 50, + 50); + } +} + +void ConcurrentStreamMetricReporter::OnOutputStreamActive() { + ++active_output_stream_count_; + // Report output stream count increases during recording. + if (active_input_stream_count_ >= 1 && + active_output_stream_count_ > max_concurrent_output_streams_metric_) { + max_concurrent_output_streams_metric_ = active_output_stream_count_; + } +} + +void ConcurrentStreamMetricReporter::OnOutputStreamInactive() { + DCHECK_GE(active_output_stream_count_, 1); + --active_output_stream_count_; +} + +} // namespace audio diff --git a/services/audio/concurrent_stream_metric_reporter.h b/services/audio/concurrent_stream_metric_reporter.h new file mode 100644 index 00000000000000..bb5f5e2a9c9a8a --- /dev/null +++ b/services/audio/concurrent_stream_metric_reporter.h @@ -0,0 +1,51 @@ +// Copyright 2021 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 SERVICES_AUDIO_CONCURRENT_STREAM_METRIC_REPORTER_H_ +#define SERVICES_AUDIO_CONCURRENT_STREAM_METRIC_REPORTER_H_ + +namespace audio { + +class InputStreamActivityMonitor { + public: + // Called when an input stream starts recording. + virtual void OnInputStreamActive() = 0; + // Called when an input stream stops recording. + virtual void OnInputStreamInactive() = 0; +}; + +class OutputStreamActivityMonitor { + public: + // Called when an output stream starts playing audio. + virtual void OnOutputStreamActive() = 0; + // Called when an output stream stops playing audio. + virtual void OnOutputStreamInactive() = 0; +}; + +// ConcurrentStreamMetricReporter monitors input and output streams and reports +// the maximum number of concurrent active OutputStreams observed during active +// InputStream recording. This provides an estimate of how many audio streams +// need to be mixed for echo cancellation. +// +// This class is not thread safe. +class ConcurrentStreamMetricReporter final + : public InputStreamActivityMonitor, + public OutputStreamActivityMonitor { + public: + // InputStreamActivityMonitor implementation. + void OnInputStreamActive() override; + void OnInputStreamInactive() override; + + // OutputStreamActivityMonitor implementation. + void OnOutputStreamActive() override; + void OnOutputStreamInactive() override; + + private: + int active_input_stream_count_ = 0; + int active_output_stream_count_ = 0; + int max_concurrent_output_streams_metric_ = 0; +}; +} // namespace audio + +#endif // SERVICES_AUDIO_CONCURRENT_STREAM_METRIC_REPORTER_H_ diff --git a/services/audio/input_controller.cc b/services/audio/input_controller.cc index 56570ab9be15a7..905c60b932fda7 100644 --- a/services/audio/input_controller.cc +++ b/services/audio/input_controller.cc @@ -27,6 +27,7 @@ #include "media/audio/audio_manager.h" #include "media/base/audio_bus.h" #include "media/base/user_input_monitor.h" +#include "services/audio/concurrent_stream_metric_reporter.h" namespace audio { namespace { @@ -130,12 +131,10 @@ float AveragePower(const media::AudioBus& buffer) { class InputController::AudioCallback : public media::AudioInputStream::AudioInputCallback { public: - AudioCallback( - InputController* controller) + explicit AudioCallback(InputController* controller) : task_runner_(base::ThreadTaskRunnerHandle::Get()), controller_(controller), - weak_controller_(controller->weak_ptr_factory_.GetWeakPtr()) { - } + weak_controller_(controller->weak_ptr_factory_.GetWeakPtr()) {} ~AudioCallback() override = default; // These should not be called when the stream is live. @@ -206,16 +205,19 @@ class InputController::AudioCallback InputController::InputController(EventHandler* handler, SyncWriter* sync_writer, media::UserInputMonitor* user_input_monitor, + InputStreamActivityMonitor* activity_monitor, const media::AudioParameters& params, StreamType type) : handler_(handler), stream_(nullptr), sync_writer_(sync_writer), type_(type), - user_input_monitor_(user_input_monitor) { + user_input_monitor_(user_input_monitor), + activity_monitor_(activity_monitor) { DCHECK_CALLED_ON_VALID_THREAD(owning_thread_); DCHECK(handler_); DCHECK(sync_writer_); + DCHECK(activity_monitor_); } InputController::~InputController() { @@ -231,11 +233,13 @@ std::unique_ptr<InputController> InputController::Create( EventHandler* event_handler, SyncWriter* sync_writer, media::UserInputMonitor* user_input_monitor, + InputStreamActivityMonitor* activity_monitor, const media::AudioParameters& params, const std::string& device_id, bool enable_agc) { DCHECK(audio_manager); DCHECK(audio_manager->GetTaskRunner()->BelongsToCurrentThread()); + DCHECK(activity_monitor); DCHECK(sync_writer); DCHECK(event_handler); DCHECK(params.IsValid()); @@ -245,9 +249,9 @@ std::unique_ptr<InputController> InputController::Create( // Create the InputController object and ensure that it runs on // the audio-manager thread. - std::unique_ptr<InputController> controller( - new InputController(event_handler, sync_writer, user_input_monitor, - params, ParamsToStreamType(params))); + std::unique_ptr<InputController> controller(new InputController( + event_handler, sync_writer, user_input_monitor, activity_monitor, params, + ParamsToStreamType(params))); controller->DoCreate(audio_manager, params, device_id, enable_agc); return controller; @@ -271,6 +275,7 @@ void InputController::Record() { audio_callback_ = std::make_unique<AudioCallback>(this); stream_->Start(audio_callback_.get()); + activity_monitor_->OnInputStreamActive(); return; } @@ -289,6 +294,7 @@ void InputController::Close() { // Allow calling unconditionally and bail if we don't have a stream to close. if (audio_callback_) { stream_->Stop(); + activity_monitor_->OnInputStreamInactive(); // Sometimes a stream (and accompanying audio track) is created and // immediately closed or discarded. In this case they are registered as diff --git a/services/audio/input_controller.h b/services/audio/input_controller.h index 4b48f344173482..a0f3b8de3e3dd0 100644 --- a/services/audio/input_controller.h +++ b/services/audio/input_controller.h @@ -33,6 +33,7 @@ class UserInputMonitor; } // namespace media namespace audio { +class InputStreamActivityMonitor; // Only do power monitoring for non-mobile platforms to save resources. #if !defined(OS_ANDROID) && !defined(OS_IOS) @@ -135,6 +136,7 @@ class InputController final : public StreamMonitor { EventHandler* event_handler, SyncWriter* sync_writer, media::UserInputMonitor* user_input_monitor, + InputStreamActivityMonitor* activity_monitor, const media::AudioParameters& params, const std::string& device_id, bool agc_is_enabled); @@ -182,6 +184,7 @@ class InputController final : public StreamMonitor { InputController(EventHandler* handler, SyncWriter* sync_writer, media::UserInputMonitor* user_input_monitor, + InputStreamActivityMonitor* activity_monitor, const media::AudioParameters& params, StreamType type); @@ -252,6 +255,9 @@ class InputController final : public StreamMonitor { media::UserInputMonitor* const user_input_monitor_; + // Notified when the stream starts/stops recording. + InputStreamActivityMonitor* const activity_monitor_; + #if defined(AUDIO_POWER_MONITORING) // Whether the silence state and microphone levels should be checked and sent // as UMA stats. diff --git a/services/audio/input_controller_unittest.cc b/services/audio/input_controller_unittest.cc index b3333bf2211dff..a1a2d2ba9b856c 100644 --- a/services/audio/input_controller_unittest.cc +++ b/services/audio/input_controller_unittest.cc @@ -20,15 +20,17 @@ #include "media/base/user_input_monitor.h" #include "media/webrtc/webrtc_switches.h" #include "mojo/public/cpp/bindings/remote.h" +#include "services/audio/concurrent_stream_metric_reporter.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using base::WaitableEvent; using ::testing::_; using ::testing::AtLeast; using ::testing::Exactly; using ::testing::InvokeWithoutArgs; using ::testing::NotNull; -using base::WaitableEvent; +using ::testing::StrictMock; namespace audio { @@ -83,6 +85,14 @@ class MockUserInputMonitor : public media::UserInputMonitor { MOCK_METHOD0(DisableKeyPressMonitoring, void()); }; +class MockInputStreamActivityMonitor : public InputStreamActivityMonitor { + public: + MockInputStreamActivityMonitor() = default; + + MOCK_METHOD0(OnInputStreamActive, void()); + MOCK_METHOD0(OnInputStreamInactive, void()); +}; + class MockAudioInputStream : public media::AudioInputStream { public: MockAudioInputStream() {} @@ -126,7 +136,7 @@ class TimeSourceInputControllerTest : public ::testing::Test { void CreateAudioController() { controller_ = InputController::Create( audio_manager_.get(), &event_handler_, &sync_writer_, - &user_input_monitor_, params_, + &user_input_monitor_, &mock_stream_activity_monitor_, params_, media::AudioDeviceDescription::kDefaultDeviceId, false); } @@ -138,6 +148,7 @@ class TimeSourceInputControllerTest : public ::testing::Test { MockInputControllerEventHandler event_handler_; MockSyncWriter sync_writer_; MockUserInputMonitor user_input_monitor_; + StrictMock<MockInputStreamActivityMonitor> mock_stream_activity_monitor_; media::AudioParameters params_; MockAudioInputStream stream_; base::test::ScopedFeatureList audio_processing_feature_; @@ -166,6 +177,8 @@ TEST_F(InputControllerTest, CreateAndCloseWithoutRecording) { // that thread, and thus we must use SYSTEM_TIME. TEST_F(SystemTimeInputControllerTest, CreateRecordAndClose) { EXPECT_CALL(event_handler_, OnCreated(_)); + EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1); CreateAudioController(); ASSERT_TRUE(controller_.get()); @@ -193,8 +206,26 @@ TEST_F(SystemTimeInputControllerTest, CreateRecordAndClose) { task_environment_.RunUntilIdle(); } +TEST_F(InputControllerTest, RecordTwice) { + EXPECT_CALL(event_handler_, OnCreated(_)); + EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1); + CreateAudioController(); + ASSERT_TRUE(controller_.get()); + + EXPECT_CALL(user_input_monitor_, EnableKeyPressMonitoring()); + controller_->Record(); + controller_->Record(); + + EXPECT_CALL(user_input_monitor_, DisableKeyPressMonitoring()); + EXPECT_CALL(sync_writer_, Close()); + controller_->Close(); +} + TEST_F(InputControllerTest, CloseTwice) { EXPECT_CALL(event_handler_, OnCreated(_)); + EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnInputStreamInactive()).Times(1); CreateAudioController(); ASSERT_TRUE(controller_.get()); diff --git a/services/audio/input_stream.cc b/services/audio/input_stream.cc index 0e4308bf6d2b3f..59440d5d048656 100644 --- a/services/audio/input_stream.cc +++ b/services/audio/input_stream.cc @@ -65,6 +65,7 @@ InputStream::InputStream( mojo::PendingRemote<media::mojom::AudioLog> log, media::AudioManager* audio_manager, std::unique_ptr<UserInputMonitor> user_input_monitor, + InputStreamActivityMonitor* activity_monitor, const std::string& device_id, const media::AudioParameters& params, uint32_t shared_memory_count, @@ -86,6 +87,7 @@ InputStream::InputStream( &foreign_socket_)), user_input_monitor_(std::move(user_input_monitor)) { DCHECK(audio_manager); + DCHECK(activity_monitor); DCHECK(receiver_.is_bound()); DCHECK(client_); DCHECK(created_callback_); @@ -123,9 +125,9 @@ InputStream::InputStream( return; } - controller_ = InputController::Create(audio_manager, this, writer_.get(), - user_input_monitor_.get(), params, - device_id, enable_agc); + controller_ = InputController::Create( + audio_manager, this, writer_.get(), user_input_monitor_.get(), + activity_monitor, params, device_id, enable_agc); } InputStream::~InputStream() { diff --git a/services/audio/input_stream.h b/services/audio/input_stream.h index 349ed147ce1030..cebb1d2c5c76f9 100644 --- a/services/audio/input_stream.h +++ b/services/audio/input_stream.h @@ -30,6 +30,7 @@ class AudioParameters; namespace audio { +class InputStreamActivityMonitor; class InputSyncWriter; class UserInputMonitor; @@ -51,6 +52,7 @@ class InputStream final : public media::mojom::AudioInputStream, mojo::PendingRemote<media::mojom::AudioLog> log, media::AudioManager* manager, std::unique_ptr<UserInputMonitor> user_input_monitor, + InputStreamActivityMonitor* activity_monitor, const std::string& device_id, const media::AudioParameters& params, uint32_t shared_memory_count, diff --git a/services/audio/output_controller.cc b/services/audio/output_controller.cc index a537d2d120d5e7..bf712c4a3df828 100644 --- a/services/audio/output_controller.cc +++ b/services/audio/output_controller.cc @@ -23,6 +23,7 @@ #include "base/threading/platform_thread.h" #include "base/trace_event/trace_event.h" #include "media/base/audio_timestamp_helper.h" +#include "services/audio/concurrent_stream_metric_reporter.h" #include "services/audio/stream_monitor.h" using base::TimeDelta; @@ -137,14 +138,17 @@ void OutputController::ErrorStatisticsTracker::WedgeCheck() { } } -OutputController::OutputController(media::AudioManager* audio_manager, - EventHandler* handler, - const media::AudioParameters& params, - const std::string& output_device_id, - SyncReader* sync_reader) +OutputController::OutputController( + media::AudioManager* audio_manager, + EventHandler* handler, + OutputStreamActivityMonitor* activity_monitor, + const media::AudioParameters& params, + const std::string& output_device_id, + SyncReader* sync_reader) : audio_manager_(audio_manager), params_(params), handler_(handler), + activity_monitor_(activity_monitor), task_runner_(audio_manager->GetTaskRunner()), construction_time_(base::TimeTicks::Now()), output_device_id_(output_device_id), @@ -158,6 +162,7 @@ OutputController::OutputController(media::AudioManager* audio_manager, TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis)) { DCHECK(audio_manager); DCHECK(handler_); + DCHECK(activity_monitor_); DCHECK(sync_reader_); DCHECK(task_runner_.get()); } @@ -304,6 +309,15 @@ void OutputController::Play() { if (state_ != kCreated && state_ != kPaused) return; + StartStream(); + if (StreamIsActive()) + activity_monitor_->OnOutputStreamActive(); +} + +void OutputController::StartStream() { + DCHECK(task_runner_->BelongsToCurrentThread()); + DCHECK(state_ == kCreated || state_ == kPaused); + // Ask for first packet. sync_reader_->RequestMoreData(base::TimeDelta(), base::TimeTicks(), 0); @@ -346,6 +360,8 @@ void OutputController::Pause() { TRACE_EVENT0("audio", "OutputController::Pause"); SendLogMessage("%s([state=%s])", __func__, StateToString(state_)); + if (StreamIsActive()) + activity_monitor_->OnOutputStreamInactive(); StopStream(); if (state_ != kPaused) @@ -382,6 +398,8 @@ void OutputController::Close() { SendLogMessage("%s([state=%s])", __func__, StateToString(state_)); if (state_ != kClosed) { + if (StreamIsActive()) + activity_monitor_->OnOutputStreamInactive(); StopCloseAndClearStream(); sync_reader_->Close(); state_ = kClosed; @@ -491,6 +509,10 @@ void OutputController::LogAudioPowerLevel(const char* call_name) { power_and_clip.first); } +bool OutputController::StreamIsActive() { + return (state_ == kPlaying) && !disable_local_output_; +} + void OutputController::OnError(ErrorType type) { SendLogMessage("%s({type=%s} [state=%s])", __func__, ErrorTypeToString(type), StateToString(state_)); @@ -570,16 +592,22 @@ void OutputController::StartMuting() { DCHECK(task_runner_->BelongsToCurrentThread()); SendLogMessage("%s([state=%s])", __func__, StateToString(state_)); - if (!disable_local_output_) + if (!disable_local_output_) { + if (StreamIsActive()) + activity_monitor_->OnOutputStreamInactive(); ToggleLocalOutput(); + } } void OutputController::StopMuting() { DCHECK(task_runner_->BelongsToCurrentThread()); SendLogMessage("%s([state=%s])", __func__, StateToString(state_)); - if (disable_local_output_) + if (disable_local_output_) { ToggleLocalOutput(); + if (StreamIsActive()) + activity_monitor_->OnOutputStreamActive(); + } } void OutputController::ToggleLocalOutput() { @@ -597,7 +625,7 @@ void OutputController::ToggleLocalOutput() { const bool restore_playback = (state_ == kPlaying); RecreateStream(RecreateReason::LOCAL_OUTPUT_TOGGLE); if (state_ == kCreated && restore_playback) - Play(); + StartStream(); } } @@ -619,7 +647,7 @@ void OutputController::OnDeviceChange() { // "Media.AudioOutputController.ChangeTime" which maybe is not desired? RecreateStreamWithTimingUMA(RecreateReason::DEVICE_CHANGE); if (state_ == kCreated && restore_playback) - Play(); + StartStream(); } std::pair<float, bool> OutputController::ReadCurrentPowerAndClip() { diff --git a/services/audio/output_controller.h b/services/audio/output_controller.h index 9da59e496734cf..11d1310c1b90ec 100644 --- a/services/audio/output_controller.h +++ b/services/audio/output_controller.h @@ -58,6 +58,7 @@ // it via construction to synchronously fulfill this read request. namespace audio { +class OutputStreamActivityMonitor; class OutputController : public media::AudioOutputStream::AudioSourceCallback, public LoopbackGroupMember, @@ -116,6 +117,7 @@ class OutputController : public media::AudioOutputStream::AudioSourceCallback, // specific hardware device for audio output. OutputController(media::AudioManager* audio_manager, EventHandler* handler, + OutputStreamActivityMonitor* activity_monitor, const media::AudioParameters& params, const std::string& output_device_id, SyncReader* sync_reader); @@ -237,6 +239,10 @@ class OutputController : public media::AudioOutputStream::AudioSourceCallback, // Notifies the EventHandler that an error has occurred. void ReportError(); + // Helper method that starts the physical stream. Must only be called in state + // kCreated or kPaused. + void StartStream(); + // Helper method that stops the physical stream. void StopStream(); @@ -249,6 +255,10 @@ class OutputController : public media::AudioOutputStream::AudioSourceCallback, // Log the current average power level measured by power_monitor_. void LogAudioPowerLevel(const char* call_name); + // Returns whether the output stream is considered active to the + // |activity_monitor_|. + bool StreamIsActive(); + // Helper called by StartMuting() and StopMuting() to execute the stream // change. void ToggleLocalOutput(); @@ -262,6 +272,9 @@ class OutputController : public media::AudioOutputStream::AudioSourceCallback, // the OC object. EventHandler* const handler_; + // Notified when the stream starts/stops playing audio without muting. + OutputStreamActivityMonitor* const activity_monitor_; + // The task runner for the audio manager. All control methods should be called // via tasks run by this TaskRunner. const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; diff --git a/services/audio/output_controller_unittest.cc b/services/audio/output_controller_unittest.cc index e921938a5fc169..e4614e27354e1e 100644 --- a/services/audio/output_controller_unittest.cc +++ b/services/audio/output_controller_unittest.cc @@ -32,6 +32,7 @@ #include "media/audio/test_audio_thread.h" #include "media/base/audio_bus.h" #include "media/base/audio_parameters.h" +#include "services/audio/concurrent_stream_metric_reporter.h" #include "services/audio/loopback_group_member.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -98,6 +99,17 @@ class MockOutputControllerSyncReader : public OutputController::SyncReader { DISALLOW_COPY_AND_ASSIGN(MockOutputControllerSyncReader); }; +class MockOutputStreamActivityMonitor : public OutputStreamActivityMonitor { + public: + MockOutputStreamActivityMonitor() = default; + + MOCK_METHOD0(OnOutputStreamActive, void()); + MOCK_METHOD0(OnOutputStreamInactive, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockOutputStreamActivityMonitor); +}; + // Wraps an AudioOutputStream instance, calling DidXYZ() mock methods for test // verification of controller behavior. If a null AudioOutputStream pointer is // provided to the constructor, a "data pump" thread will be run between the @@ -321,7 +333,8 @@ class OutputControllerTest : public ::testing::Test { ~OutputControllerTest() override { audio_manager_.Shutdown(); } void SetUp() override { - controller_.emplace(&audio_manager_, &mock_event_handler_, GetTestParams(), + controller_.emplace(&audio_manager_, &mock_event_handler_, + &mock_stream_activity_monitor_, GetTestParams(), std::string(), &mock_sync_reader_); controller_->SetVolume(kTestVolume); } @@ -367,6 +380,8 @@ class OutputControllerTest : public ::testing::Test { loop.Run(); } + void PlayWhilePlaying() { controller_->Play(); } + void Pause() { base::RunLoop loop; EXPECT_CALL(mock_event_handler_, OnControllerPaused()) @@ -403,7 +418,9 @@ class OutputControllerTest : public ::testing::Test { Mock::VerifyAndClearExpectations(&mock_event_handler_); } - void StopMuting() { + void StopMutingBeforePlaying() { controller_->StopMuting(); } + + void StopMutingWhilePlaying() { EXPECT_CALL(mock_event_handler_, OnControllerPlaying()); controller_->StopMuting(); Mock::VerifyAndClearExpectations(&mock_event_handler_); @@ -467,6 +484,7 @@ class OutputControllerTest : public ::testing::Test { } StrictMock<MockOutputControllerEventHandler> mock_event_handler_; + StrictMock<MockOutputStreamActivityMonitor> mock_stream_activity_monitor_; private: base::TestMessageLoop message_loop_; @@ -484,12 +502,17 @@ TEST_F(OutputControllerTest, CreateAndClose) { } TEST_F(OutputControllerTest, PlayAndClose) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); Create(); Play(); Close(); } TEST_F(OutputControllerTest, PlayPauseClose) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + Create(); Play(); Pause(); @@ -497,6 +520,9 @@ TEST_F(OutputControllerTest, PlayPauseClose) { } TEST_F(OutputControllerTest, PlayPausePlayClose) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(2); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(2); + Create(); Play(); Pause(); @@ -505,6 +531,9 @@ TEST_F(OutputControllerTest, PlayPausePlayClose) { } TEST_F(OutputControllerTest, PlayDeviceChangeClose) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + Create(); Play(); ChangeDevice(); @@ -512,6 +541,9 @@ TEST_F(OutputControllerTest, PlayDeviceChangeClose) { } TEST_F(OutputControllerTest, PlayDeviceChangeError) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + Create(); Play(); SimulateErrorThenDeviceChange(); @@ -552,6 +584,9 @@ TEST_F(OutputControllerTest, MuteCreatePlayClose) { // Tests that a local playout stream is shut-down and replaced with a "muting // stream" if StartMuting() is called after playback begins. TEST_F(OutputControllerTest, CreatePlayMuteClose) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + Create(); MockAudioOutputStream* const playout_stream = last_created_stream(); ASSERT_TRUE(playout_stream); @@ -576,7 +611,10 @@ TEST_F(OutputControllerTest, CreatePlayMuteClose) { // Tests that the "muting stream" is shut down and replaced with the normal // playout stream after StopMuting() is called. -TEST_F(OutputControllerTest, PlayMuteUnmuteClose) { +TEST_F(OutputControllerTest, MutePlayUnmuteClose) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + StartMutingBeforePlaying(); Create(); Play(); @@ -585,7 +623,7 @@ TEST_F(OutputControllerTest, PlayMuteUnmuteClose) { EXPECT_EQ(nullptr, last_closed_stream()); EXPECT_EQ(AudioParameters::AUDIO_FAKE, mute_stream->format()); - StopMuting(); + StopMutingWhilePlaying(); MockAudioOutputStream* const playout_stream = last_created_stream(); ASSERT_TRUE(playout_stream); EXPECT_EQ(mute_stream, last_closed_stream()); @@ -598,6 +636,9 @@ TEST_F(OutputControllerTest, PlayMuteUnmuteClose) { } TEST_F(OutputControllerTest, SnoopCreatePlayStopClose) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + NiceMock<MockSnooper> snooper; StartSnooping(&snooper); Create(); @@ -608,6 +649,9 @@ TEST_F(OutputControllerTest, SnoopCreatePlayStopClose) { } TEST_F(OutputControllerTest, CreatePlaySnoopStopClose) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + NiceMock<MockSnooper> snooper; Create(); Play(); @@ -618,6 +662,9 @@ TEST_F(OutputControllerTest, CreatePlaySnoopStopClose) { } TEST_F(OutputControllerTest, CreatePlaySnoopCloseStop) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + NiceMock<MockSnooper> snooper; Create(); Play(); @@ -628,6 +675,9 @@ TEST_F(OutputControllerTest, CreatePlaySnoopCloseStop) { } TEST_F(OutputControllerTest, TwoSnoopers_StartAtDifferentTimes) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + NiceMock<MockSnooper> snooper1; NiceMock<MockSnooper> snooper2; StartSnooping(&snooper1); @@ -644,6 +694,9 @@ TEST_F(OutputControllerTest, TwoSnoopers_StartAtDifferentTimes) { } TEST_F(OutputControllerTest, TwoSnoopers_StopAtDifferentTimes) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + NiceMock<MockSnooper> snooper1; NiceMock<MockSnooper> snooper2; Create(); @@ -692,6 +745,9 @@ TEST_F(OutputControllerTest, SnoopWhileMuting) { } TEST_F(OutputControllerTest, FlushWhenStreamIsPlayingTriggersError) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + Create(); Play(); @@ -704,6 +760,9 @@ TEST_F(OutputControllerTest, FlushWhenStreamIsPlayingTriggersError) { } TEST_F(OutputControllerTest, FlushesWhenStreamIsNotPlaying) { + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + Create(); Play(); Pause(); @@ -715,5 +774,69 @@ TEST_F(OutputControllerTest, FlushesWhenStreamIsNotPlaying) { Close(); } +// Tests that stream activity (play/pause, taking muting into account) is +// correctly signalled to the OutputStreamActivityMonitor. +TEST_F(OutputControllerTest, ReportActivity) { + Create(); + + // The stream is expected to only report state changes once. This variable + // tracks this throughout the test. + bool stream_active_state = false; + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()) + .WillRepeatedly([&stream_active_state]() { + EXPECT_FALSE(stream_active_state); + stream_active_state = true; + }); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()) + .WillRepeatedly([&stream_active_state]() { + EXPECT_TRUE(stream_active_state); + stream_active_state = false; + }); + + // Playing -> active. + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(0); + Play(); + + // Pausing -> inactive. + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(0); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + Pause(); + + // Repeated Play()/Pause() calls do not change active state. + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + Play(); + PlayWhilePlaying(); + Pause(); + Pause(); + + // Playing during muting -> stream is never active. + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(0); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(0); + StartMutingBeforePlaying(); + Play(); + Pause(); + StopMutingBeforePlaying(); + + // Muting while playing -> stream becomes inactive. + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + Play(); + StartMutingWhilePlaying(); + + // Unmuting while playing -> stream becomes active. + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(1); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(0); + StopMutingWhilePlaying(); + + // Closing a playing stream triggers a final inactivation. + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamActive()).Times(0); + EXPECT_CALL(mock_stream_activity_monitor_, OnOutputStreamInactive()).Times(1); + Close(); + + EXPECT_FALSE(stream_active_state); +} + } // namespace } // namespace audio diff --git a/services/audio/output_stream.cc b/services/audio/output_stream.cc index 0a99fd4e8e7357..055f69d6b3cc0f 100644 --- a/services/audio/output_stream.cc +++ b/services/audio/output_stream.cc @@ -38,6 +38,7 @@ OutputStream::OutputStream( observer, mojo::PendingRemote<media::mojom::AudioLog> log, media::AudioManager* audio_manager, + OutputStreamActivityMonitor* activity_monitor, const std::string& output_device_id, const media::AudioParameters& params, LoopbackCoordinator* coordinator, @@ -54,7 +55,12 @@ OutputStream::OutputStream( : base::DoNothing(), params, &foreign_socket_), - controller_(audio_manager, this, params, output_device_id, &reader_), + controller_(audio_manager, + this, + activity_monitor, + params, + output_device_id, + &reader_), loopback_group_id_(loopback_group_id) { DCHECK(receiver_.is_bound()); DCHECK(created_callback); diff --git a/services/audio/output_stream.h b/services/audio/output_stream.h index 9058eb0c2e7186..efb3a2f23965bb 100644 --- a/services/audio/output_stream.h +++ b/services/audio/output_stream.h @@ -40,6 +40,7 @@ class AudioParameters; } // namespace media namespace audio { +class OutputStreamActivityMonitor; class OutputStream final : public media::mojom::AudioOutputStream, public OutputController::EventHandler { @@ -56,6 +57,7 @@ class OutputStream final : public media::mojom::AudioOutputStream, observer, mojo::PendingRemote<media::mojom::AudioLog> log, media::AudioManager* audio_manager, + OutputStreamActivityMonitor* activity_monitor, const std::string& output_device_id, const media::AudioParameters& params, LoopbackCoordinator* coordinator, diff --git a/services/audio/stream_factory.cc b/services/audio/stream_factory.cc index c811753360f0b1..0a4810f980fd3b 100644 --- a/services/audio/stream_factory.cc +++ b/services/audio/stream_factory.cc @@ -58,8 +58,9 @@ void StreamFactory::CreateInputStream( std::move(created_callback), std::move(deleter_callback), std::move(stream_receiver), std::move(client), std::move(observer), std::move(pending_log), audio_manager_, - UserInputMonitor::Create(std::move(key_press_count_buffer)), device_id, - params, shared_memory_count, enable_agc)); + UserInputMonitor::Create(std::move(key_press_count_buffer)), + &stream_count_metric_reporter_, device_id, params, shared_memory_count, + enable_agc)); } void StreamFactory::AssociateInputAndOutputForAec( @@ -108,7 +109,8 @@ void StreamFactory::CreateOutputStream( output_streams_.insert(std::make_unique<OutputStream>( std::move(created_callback), std::move(deleter_callback), std::move(stream_receiver), std::move(observer), std::move(log), - audio_manager_, device_id_or_group_id, params, &coordinator_, group_id)); + audio_manager_, &stream_count_metric_reporter_, device_id_or_group_id, + params, &coordinator_, group_id)); } void StreamFactory::BindMuter( diff --git a/services/audio/stream_factory.h b/services/audio/stream_factory.h index fccd05208b81af..37a373d234f267 100644 --- a/services/audio/stream_factory.h +++ b/services/audio/stream_factory.h @@ -20,6 +20,7 @@ #include "media/mojo/mojom/audio_output_stream.mojom.h" #include "media/mojo/mojom/audio_stream_factory.mojom.h" #include "mojo/public/cpp/bindings/receiver_set.h" +#include "services/audio/concurrent_stream_metric_reporter.h" #include "services/audio/loopback_coordinator.h" namespace base { @@ -104,6 +105,8 @@ class StreamFactory final : public media::mojom::AudioStreamFactory { mojo::ReceiverSet<media::mojom::AudioStreamFactory> receivers_; + ConcurrentStreamMetricReporter stream_count_metric_reporter_; + // Order of the following members is important for a clean shutdown. LoopbackCoordinator coordinator_; std::vector<std::unique_ptr<LocalMuter>> muters_; diff --git a/tools/metrics/histograms/histograms_xml/media/histograms.xml b/tools/metrics/histograms/histograms_xml/media/histograms.xml index 80042d25268eac..8ae628e4c89eda 100644 --- a/tools/metrics/histograms/histograms_xml/media/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/media/histograms.xml @@ -562,6 +562,20 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. </summary> </histogram> +<histogram name="Media.Audio.MaxOutputStreamsPerInputStream" units="streams" + expires_after="M99"> + <owner>saza@chromium.org</owner> + <owner>olka@chromium.org</owner> + <summary> + The maximum number of concurrently active (playing and not muting by + diverting to a fake AudioOutputStream) OutputStreams observed when at least + one InputStream is recording. The metric is reported each time the number of + actively recording input streams drops to 0. The metric provides an estimate + of the number of output streams that may need to be mixed for echo + cancellation. + </summary> +</histogram> + <histogram name="Media.Audio.Output.Win.{AudioOutputMethod}Error" enum="Hresult" expires_after="M98"> <owner>dalecurtis@chromium.org</owner> From b33d0d507ecfe08a27da3dc930cb0e7b62e7fe1f Mon Sep 17 00:00:00 2001 From: Miyoung Shin <myid.shin@igalia.com> Date: Tue, 1 Jun 2021 12:18:07 +0000 Subject: [PATCH 49/81] Prerendering Restriction: block the Alert/Confirm/Prompt APIs This CL adds a web tests to ensure that the access of the alert(), confirm() and prompt() APIs are quietly blocked during prerendering so that prerendering keeps ongoing. Bug: 1213763 Change-Id: I7c46b004cc78ea1ff8f848ea71f04f012210e750 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2925415 Commit-Queue: Miyoung Shin <myid.shin@igalia.com> Reviewed-by: Takashi Toyoshima <toyoshim@chromium.org> Reviewed-by: Lingqi Chi <lingqi@chromium.org> Cr-Commit-Position: refs/heads/master@{#887926} --- .../prerender/resources/message-boxes.html | 34 ++++++++++++ .../prerender/restriction-message-boxes.html | 53 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 third_party/blink/web_tests/wpt_internal/prerender/resources/message-boxes.html create mode 100644 third_party/blink/web_tests/wpt_internal/prerender/restriction-message-boxes.html diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/message-boxes.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/message-boxes.html new file mode 100644 index 00000000000000..4ff0584ebf5402 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/message-boxes.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + +function runAlertTest() { + window.alert('Hello! Preprendering!'); + bc.postMessage('no block'); +} + +function runConfirmTest() { + const result = window.confirm('Are you preprendering page?'); + bc.postMessage('the return value is ' + (result === true ? 'yes' : 'no')); +} + +function runPromptTest() { + const result = window.prompt('Are you preprendering page?', 'the default value'); + bc.postMessage('the return value is ' + + (result === '' ? 'the empty string' : result)); +} + +const bc = new BroadcastChannel('prerender-channel'); +assert_true(document.prerendering); +const params = new URLSearchParams(location.search); + +if (params.has('alert')) + runAlertTest(); +else if (params.has('confirm')) + runConfirmTest(); +else if (params.has('prompt')) + runPromptTest(); + +bc.close(); +</script> diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-message-boxes.html b/third_party/blink/web_tests/wpt_internal/prerender/restriction-message-boxes.html new file mode 100644 index 00000000000000..106d8cd7fa4faa --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/prerender/restriction-message-boxes.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<!-- +This file cannot be upstreamed to WPT until: +* startPrerendering() usage is replaced with a WebDriver API +* window.confirm() silently returns the default values `false`. +--> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/utils.js"></script> +<body> +<script> +function runTest(test_file, expectation, description) { + promise_test(async t => { + const bc = new BroadcastChannel('prerender-channel'); + t.add_cleanup(_ => bc.close()); + + const gotMessage = new Promise(resolve => { + bc.addEventListener('message', e => { + resolve(e.data); + }, { + once: true + }); + }); + + startPrerendering(test_file); + + // Wait for the message from the prerendering page. + assert_equals(await gotMessage, expectation); + }, description); +} + +// Test that a page invokes the alert modal during prerendering. +runTest( + 'resources/message-boxes.html?alert', + 'no block', + 'alert() does not display the modal and returns immediately'); + +// Test that a page invokes the comfirm modal during prerendering. +// TODO(crbug.com/1214768) : window.confirm() should silently return +// the default values `false`. +// https://github.com/jeremyroman/alternate-loading-modes/blob/main/browsing-context.md +runTest( + 'resources/message-boxes.html?confirm', + 'the return value is yes', + 'comfirm() does not display the modal and returns immediately'); + +// Test that a page invokes the prompt modal during prerendering. +runTest( + 'resources/message-boxes.html?prompt', + 'the return value is the empty string', + 'prompt() does not display the modal and returns immediately'); +</script> +</body> From 9ad9d1d83d0644adca50a234b77b2015662d4847 Mon Sep 17 00:00:00 2001 From: v8-ci-autoroll-builder <v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 12:26:58 +0000 Subject: [PATCH 50/81] Update V8 to version 9.3.40. Summary of changes available at: https://chromium.googlesource.com/v8/v8/+log/fe7a5763..5ecef708 Please follow these instructions for assigning/CC'ing issues: https://v8.dev/docs/triage-issues Please close rolling in case of a roll revert: https://v8-roll.appspot.com/ This only works with a Google account. CQ_INCLUDE_TRYBOTS=luci.chromium.try:linux-blink-rel CQ_INCLUDE_TRYBOTS=luci.chromium.try:linux_optional_gpu_tests_rel CQ_INCLUDE_TRYBOTS=luci.chromium.try:mac_optional_gpu_tests_rel CQ_INCLUDE_TRYBOTS=luci.chromium.try:win_optional_gpu_tests_rel CQ_INCLUDE_TRYBOTS=luci.chromium.try:android_optional_gpu_tests_rel R=hablich@chromium.org,vahl@chromium.org,v8-waterfall-sheriff@grotations.appspotmail.com Change-Id: Iabb9939a0884e2399d522d83f161909769e101ba Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2930116 Bot-Commit: v8-ci-autoroll-builder <v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com> Commit-Queue: v8-ci-autoroll-builder <v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887927} --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index a924c9e229206e..35c2688e3b724a 100644 --- a/DEPS +++ b/DEPS @@ -213,7 +213,7 @@ vars = { # 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': 'fe7a5763a6a008e2c6744390db949308acd5602f', + 'v8_revision': '5ecef708595c72e5b4d798fc336a0a64e764aeff', # 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. From d46a754ba0efe29ba7f3a1d793e1167cc1d45f40 Mon Sep 17 00:00:00 2001 From: Xida Chen <xidachen@chromium.org> Date: Tue, 1 Jun 2021 12:37:53 +0000 Subject: [PATCH 51/81] [composite-bgcolor-animation] Remove an invalid DCHECK The DCHECK is to ensure that the progress of the background color animation is always in the range of [0,1]. However, this is not always true, for example: "cubic-bezier(0.5, 1.5, 0.5, 1.5)" This CL removes the DCHECK. Bug: 1097045 Change-Id: I65b141d8a647109661667300ab7a15952e729f09 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929196 Reviewed-by: Kevin Ellis <kevers@chromium.org> Commit-Queue: Xida Chen <xidachen@chromium.org> Cr-Commit-Position: refs/heads/master@{#887928} --- .../modules/csspaint/background_color_paint_worklet.cc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/third_party/blink/renderer/modules/csspaint/background_color_paint_worklet.cc b/third_party/blink/renderer/modules/csspaint/background_color_paint_worklet.cc index 6cc4aab9868c66..086bb6fb55c1f5 100644 --- a/third_party/blink/renderer/modules/csspaint/background_color_paint_worklet.cc +++ b/third_party/blink/renderer/modules/csspaint/background_color_paint_worklet.cc @@ -24,8 +24,6 @@ namespace blink { namespace { -const float kProgressBoundsTolerance = 0.000001f; - // This class includes information that is required by the compositor thread // when painting background color. class BackgroundColorPaintWorkletInput : public PaintWorkletInput { @@ -100,11 +98,8 @@ class BackgroundColorPaintWorkletProxyClient // Get the start and end color based on the progress and offsets. unsigned result_index = offsets.size() - 1; - // The progress of the animation might outside of [0, 1] by - // kProgressBoundsTolerance. if (progress <= 0) { result_index = 0; - DCHECK_GE(progress, -kProgressBoundsTolerance); } else if (progress > 0 && progress < 1) { for (unsigned i = 0; i < offsets.size() - 1; i++) { if (progress <= offsets[i + 1]) { @@ -113,10 +108,8 @@ class BackgroundColorPaintWorkletProxyClient } } } - if (result_index == offsets.size() - 1) { - DCHECK_LE(std::fabs(progress - 1), kProgressBoundsTolerance); + if (result_index == offsets.size() - 1) result_index = offsets.size() - 2; - } // Because the progress is a global one, we need to adjust it with offsets. float adjusted_progress = (progress - offsets[result_index]) / From f6a887348e05ec37ae268ca0289b251afc7ebcd0 Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 13:09:30 +0000 Subject: [PATCH 52/81] Roll Perfetto Trace Processor Linux from b3f455e9edce to bb3b66d48669 https://android.googlesource.com/platform/external/perfetto.git/+log/b3f455e9edce..bb3b66d48669 If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/perfetto-trace-processor-linux-chromium Please CC perfetto-bugs@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Tbr: perfetto-bugs@google.com Change-Id: I7c02ead9599d3d5a505eec4578f1a2cebe0f0fd7 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928907 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887929} --- tools/perf/core/perfetto_binary_roller/binary_deps.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 65870d38071d43..68b43781a06178 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json @@ -9,8 +9,8 @@ "remote_path": "perfetto_binaries/trace_processor_shell/mac/bae8193de6c017394901163b7817157342914679/trace_processor_shell" }, "linux": { - "hash": "46ee9624f529202741eaa0126a9fb42641b0ea1f", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/b3f455e9edced2a776ddcb5a2cdf5ddcefa8776f/trace_processor_shell" + "hash": "5908e1b3ac1c0c11089af3576e84be429b556d93", + "remote_path": "perfetto_binaries/trace_processor_shell/linux/bb3b66d486694c9984e76d38e3bd7ca525edfee2/trace_processor_shell" } }, "power_profile.sql": { From f9136ce6df5df1827f128015cd4e349af52a0cfd Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 13:09:58 +0000 Subject: [PATCH 53/81] Roll RTS model from D1etRzwhV... to qgWjqhDC-... If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/rts-mac-amd64-chromium-autoroll Please CC nodir@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Tbr: nodir@google.com Change-Id: I05565bb1e7bb2eeab31fa3526c644879c1e25152 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928324 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887930} --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 35c2688e3b724a..f9b3fd135b2c87 100644 --- a/DEPS +++ b/DEPS @@ -654,7 +654,7 @@ deps = { 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'D1etRzwhVwI7QGbv0PFp2QrQ73HzOVZjex_mrRU2obsC', + 'version': 'qgWjqhDC-d3maWRs-3dh4uTjXicdxi88EYI4HoaVGcgC', }, ], 'dep_type': 'cipd', From d626877408671d4ccd27ece50e40226fdb82bd02 Mon Sep 17 00:00:00 2001 From: Ali Juma <ajuma@chromium.org> Date: Tue, 1 Jun 2021 13:11:36 +0000 Subject: [PATCH 54/81] [iOS] Target 10.15 when building WebKit for macOS on macOS 11 The builder bots are now on macOS 11. In order to continue building with Xcode 11.4 (which is needed since the fuzzer bots are still on 10.15.7), target 10.15.7 explicitly. This is similar to workaround that we used last year, to build on 10.15 but target 10.14. Bug: 1214907 Change-Id: I41b5442f6b30b21469c46f73be89349097732243 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929236 Reviewed-by: Rohit Rao <rohitrao@chromium.org> Commit-Queue: Ali Juma <ajuma@chromium.org> Cr-Commit-Position: refs/heads/master@{#887931} --- ios/third_party/webkit/BUILD.gn | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ios/third_party/webkit/BUILD.gn b/ios/third_party/webkit/BUILD.gn index 75c27d7fd75ef7..7d9f967242046b 100644 --- a/ios/third_party/webkit/BUILD.gn +++ b/ios/third_party/webkit/BUILD.gn @@ -144,6 +144,14 @@ if (_build_mac_webkit) { "--clean", "--output_dir", rebase_path("$_webkit_mac_out_base_dir"), + + # The arguments below allow building with Xcode 11.4 on macOS 11. + "MACOSX_DEPLOYMENT_TARGET=10.15", + "TARGET_MAC_OS_X_VERSION_MAJOR=101500", + "MAC_OS_X_VERSION_ACTUAL=101507", + "MAC_OS_X_VERSION_MAJOR=101500", + "MAC_OS_X_VERSION_MINOR=1507", + "MAC_OS_X_PRODUCT_BUILD_VERSION=19H2", ] } From 8a9e0646700552c9c5cc1f4819410cb05c2b4a60 Mon Sep 17 00:00:00 2001 From: Miyoung Shin <myid.shin@igalia.com> Date: Tue, 1 Jun 2021 13:15:59 +0000 Subject: [PATCH 55/81] Prerender: Cancel prerendering upon a download This CL adds a web tests to ensure that the prerendering page is canceled when accessing the Download API or downloading the content by a http header during prerendering. Bug: 1205359 Change-Id: Iae11629a56a306f000d8958ec56bb0506503fcab Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2871027 Commit-Queue: Miyoung Shin <myid.shin@igalia.com> Reviewed-by: Matt Falkenhagen <falken@chromium.org> Reviewed-by: Lingqi Chi <lingqi@chromium.org> Reviewed-by: Jeremy Roman <jbroman@chromium.org> Cr-Commit-Position: refs/heads/master@{#887932} --- .../prerender/prerender_browsertest.cc | 51 ++++++++++++++++++- content/browser/prerender/prerender_host.h | 3 +- .../prerender_navigation_throttle.cc | 21 ++++++++ .../prerender/prerender_navigation_throttle.h | 1 + .../prerender_subframe_navigation_throttle.cc | 20 ++++++++ .../prerender_subframe_navigation_throttle.h | 1 + .../renderer_host/render_frame_host_impl.cc | 9 ++++ .../prerender/resources/download.html | 49 ++++++++++++++++++ .../prerender/restriction-download.html | 37 ++++++++++++++ tools/metrics/histograms/enums.xml | 1 + 10 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 third_party/blink/web_tests/wpt_internal/prerender/resources/download.html create mode 100644 third_party/blink/web_tests/wpt_internal/prerender/restriction-download.html diff --git a/content/browser/prerender/prerender_browsertest.cc b/content/browser/prerender/prerender_browsertest.cc index 82ec72b29378d6..4aea0963e503ac 100644 --- a/content/browser/prerender/prerender_browsertest.cc +++ b/content/browser/prerender/prerender_browsertest.cc @@ -1767,7 +1767,6 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ClipboardByExecCommandFail) { EvalJsOptions::EXECUTE_SCRIPT_NO_USER_GESTURE)); } -#if !defined(OS_ANDROID) || BUILDFLAG(ENABLE_PLUGINS) void LoadAndWaitForPrerenderDestroyed(WebContents* const web_contents, const GURL prerendering_url, test::PrerenderTestHelper* helper) { @@ -1780,7 +1779,6 @@ void LoadAndWaitForPrerenderDestroyed(WebContents* const web_contents, EXPECT_EQ(helper->GetHostForUrl(prerendering_url), RenderFrameHost::kNoFrameTreeNodeId); } -#endif // !defined(OS_ANDROID) || BUILDFLAG(ENABLE_PLUGINS) #if BUILDFLAG(ENABLE_PLUGINS) // Tests that we will cancel the prerendering if the prerendering page attempts @@ -1861,6 +1859,55 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, NotificationConstructor) { } #endif // defined(OS_ANDROID) +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DownloadInMainFrame) { + base::HistogramTester histogram_tester; + const GURL kInitialUrl = GetUrl("/empty.html"); + + // Navigate to an initial page. + ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); + + // TODO(crbug.com/1215073): Make a WPT for the content-disposition WPT test. + const GURL download_url = + GetUrl("/set-header?Content-Disposition: attachment"); + + LoadAndWaitForPrerenderDestroyed(web_contents(), download_url, + prerender_helper()); + + histogram_tester.ExpectUniqueSample( + "Prerender.Experimental.PrerenderHostFinalStatus", + PrerenderHost::FinalStatus::kDownload, 1); +} + +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DownloadInSubframe) { + base::HistogramTester histogram_tester; + const GURL kInitialUrl = GetUrl("/empty.html"); + const GURL kPrerenderingUrl = GetUrl("/empty.html?prerendering"); + + // Navigate to an initial page. + ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); + + // Make a prerendered page. + const int host_id = AddPrerender(kPrerenderingUrl); + ASSERT_NE(host_id, RenderFrameHost::kNoFrameTreeNodeId); + auto* prerender_host = GetPrerenderedMainFrameHost(host_id); + EXPECT_TRUE(AddTestUtilJS(prerender_host)); + + // TODO(crbug.com/1215073): Make a WPT for the content-disposition WPT test. + const GURL download_url = + GetUrl("/set-header?Content-Disposition: attachment"); + ExecuteScriptAsync(prerender_host, + JsReplace("add_iframe_async($1)", download_url)); + + test::PrerenderHostObserver host_observer(*web_contents(), host_id); + host_observer.WaitForDestroyed(); + EXPECT_EQ(GetHostForUrl(kPrerenderingUrl), + RenderFrameHost::kNoFrameTreeNodeId); + + histogram_tester.ExpectUniqueSample( + "Prerender.Experimental.PrerenderHostFinalStatus", + PrerenderHost::FinalStatus::kDownload, 1); +} + // End: Tests for feature restrictions in prerendered pages ==================== // Tests that prerendering doesn't run for low-end devices. diff --git a/content/browser/prerender/prerender_host.h b/content/browser/prerender/prerender_host.h index d394b4e6635447..7da69d4fd143a3 100644 --- a/content/browser/prerender/prerender_host.h +++ b/content/browser/prerender/prerender_host.h @@ -65,7 +65,8 @@ class CONTENT_EXPORT PrerenderHost : public WebContentsObserver { kPlugin = 12, kRendererProcessCrashed = 13, kRendererProcessKilled = 14, - kMaxValue = kRendererProcessKilled + kDownload = 15, + kMaxValue = kDownload }; PrerenderHost(blink::mojom::PrerenderAttributesPtr attributes, diff --git a/content/browser/prerender/prerender_navigation_throttle.cc b/content/browser/prerender/prerender_navigation_throttle.cc index f233fa53eaea83..2eba9601fbdefc 100644 --- a/content/browser/prerender/prerender_navigation_throttle.cc +++ b/content/browser/prerender/prerender_navigation_throttle.cc @@ -129,4 +129,25 @@ PrerenderNavigationThrottle::WillStartOrRedirectRequest(bool is_redirection) { return PROCEED; } +NavigationThrottle::ThrottleCheckResult +PrerenderNavigationThrottle::WillProcessResponse() { + // Disallow downloads during prerendering and cancel the prerender. + if (navigation_handle()->IsDownload()) { + auto* navigation_request = NavigationRequest::From(navigation_handle()); + FrameTreeNode* frame_tree_node = navigation_request->frame_tree_node(); + DCHECK(frame_tree_node->frame_tree()->is_prerendering()); + + PrerenderHostRegistry* prerender_host_registry = + frame_tree_node->current_frame_host() + ->delegate() + ->GetPrerenderHostRegistry(); + + prerender_host_registry->AbandonHostAsync( + frame_tree_node->frame_tree_node_id(), + PrerenderHost::FinalStatus::kDownload); + return CANCEL; + } + return PROCEED; +} + } // namespace content diff --git a/content/browser/prerender/prerender_navigation_throttle.h b/content/browser/prerender/prerender_navigation_throttle.h index 127e85993e32de..c307d86b1d6191 100644 --- a/content/browser/prerender/prerender_navigation_throttle.h +++ b/content/browser/prerender/prerender_navigation_throttle.h @@ -27,6 +27,7 @@ class PrerenderNavigationThrottle : public NavigationThrottle { const char* GetNameForLogging() override; ThrottleCheckResult WillStartRequest() override; ThrottleCheckResult WillRedirectRequest() override; + ThrottleCheckResult WillProcessResponse() override; private: explicit PrerenderNavigationThrottle(NavigationHandle* navigation_handle); diff --git a/content/browser/prerender/prerender_subframe_navigation_throttle.cc b/content/browser/prerender/prerender_subframe_navigation_throttle.cc index 31afa82cf9b3e1..a11dc4eff4a35d 100644 --- a/content/browser/prerender/prerender_subframe_navigation_throttle.cc +++ b/content/browser/prerender/prerender_subframe_navigation_throttle.cc @@ -54,6 +54,26 @@ PrerenderSubframeNavigationThrottle::WillRedirectRequest() { return WillStartOrRedirectRequest(); } +NavigationThrottle::ThrottleCheckResult +PrerenderSubframeNavigationThrottle::WillProcessResponse() { + auto* navigation_request = NavigationRequest::From(navigation_handle()); + FrameTreeNode* frame_tree_node = navigation_request->frame_tree_node(); + // Disallow downloads during prerendering and cancel the prerender. + if (navigation_handle()->IsDownload() && + frame_tree_node->frame_tree()->is_prerendering()) { + PrerenderHostRegistry* prerender_host_registry = + frame_tree_node->current_frame_host() + ->delegate() + ->GetPrerenderHostRegistry(); + + prerender_host_registry->AbandonHostAsync( + frame_tree_node->frame_tree()->root()->frame_tree_node_id(), + PrerenderHost::FinalStatus::kDownload); + return CANCEL; + } + return PROCEED; +} + void PrerenderSubframeNavigationThrottle::OnActivated() { DCHECK(!NavigationRequest::From(navigation_handle()) ->frame_tree_node() diff --git a/content/browser/prerender/prerender_subframe_navigation_throttle.h b/content/browser/prerender/prerender_subframe_navigation_throttle.h index 5e733e993a1996..4eed6d7d652b86 100644 --- a/content/browser/prerender/prerender_subframe_navigation_throttle.h +++ b/content/browser/prerender/prerender_subframe_navigation_throttle.h @@ -29,6 +29,7 @@ class PrerenderSubframeNavigationThrottle : public NavigationThrottle, const char* GetNameForLogging() override; ThrottleCheckResult WillStartRequest() override; ThrottleCheckResult WillRedirectRequest() override; + ThrottleCheckResult WillProcessResponse() override; // PrerenderHost::Observer void OnActivated() override; diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index c07e061af9c8c5..555ff4f301d96a 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc @@ -4388,6 +4388,15 @@ void RenderFrameHostImpl::UpdateManifestURL( void RenderFrameHostImpl::DownloadURL( blink::mojom::DownloadURLParamsPtr blink_parameters) { + // TODO(crbug.com/1205359): We should defer the download until the + // prerendering page is activated, and it will comply with the prerendering + // spec. + if (blink::features::IsPrerender2Enabled() && + frame_tree()->is_prerendering()) { + CancelPrerendering(PrerenderHost::FinalStatus::kDownload); + return; + } + if (!VerifyDownloadUrlParams(GetSiteInstance(), *blink_parameters)) return; diff --git a/third_party/blink/web_tests/wpt_internal/prerender/resources/download.html b/third_party/blink/web_tests/wpt_internal/prerender/resources/download.html new file mode 100644 index 00000000000000..b4fc8525aa23fb --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/prerender/resources/download.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<script src="utils.js"></script> +<a id="target" download="download-link" href="cache.txt">here</a> +<script> + +const params = new URLSearchParams(location.search); + +// The main test page (restriction-download.html) loads the initiator page, +// then the initiator page will prerender itself with the `prerendering` +// parameter. +const isPrerenderingTarget = params.has('prerendering'); + +if (!isPrerenderingTarget) { + loadInitiatorPage(); +} else { + window.addEventListener('load', () => { + if (document.prerendering) { + // If prerendering, tell the initiator that this page finished + // loading, so it can attempt activation. + + // Used to communicate with the initiator page. + const prerenderChannel = new BroadcastChannel('prerender-channel'); + + document.getElementById('target').click(); + + // Inform the initiator page that this page was loaded. + prerenderChannel.postMessage('readyToActivate'); + prerenderChannel.close(); + } else { + // If not prerendering, and `load` was fired with the `prerendering` + // parameter, we know this page was not prerendered and it was loaded by + // a new navigation. This means the prerender was cancelled. + + // Used to communicate with the main test page. + const testChannel = new BroadcastChannel('test-channel'); + testChannel.postMessage('prerendering is canceled'); + testChannel.close(); + } + }); + + document.addEventListener('prerenderingchange', () => { + // Used to communicate with the main test page. + const testChannel = new BroadcastChannel('test-channel'); + testChannel.postMessage('unexpectedly activated'); + testChannel.close(); + }); +} + +</script> diff --git a/third_party/blink/web_tests/wpt_internal/prerender/restriction-download.html b/third_party/blink/web_tests/wpt_internal/prerender/restriction-download.html new file mode 100644 index 00000000000000..2709127ba163aa --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/prerender/restriction-download.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<!-- +This file cannot be upstreamed to WPT until: +* startPrerendering() usage is replaced with a WebDriver API +* The test changes to expect the deferring behavior described at + https://jeremyroman.github.io/alternate-loading-modes/#patch-downloading + instead of expecting that prerender is cancelled. +--> +<title> +Prerending is canceled upon the `download the hyperlink` algorithm +</title> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<script> + +promise_test(async t => { + const bc = new BroadcastChannel('test-channel'); + t.add_cleanup(_ => bc.close()); + + const gotMessage = new Promise(resolve => { + bc.addEventListener('message', e => { + resolve(e.data); + }, { + once: true + }); + }); + const url = `resources/download.html`; + window.open(url, '_blank', 'noopener'); + + const result = await gotMessage; + assert_equals(result, 'prerendering is canceled'); +}, `attempting a download should cause prerendering to be cancelled`); + +</script> +</body> diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index b8929673243e45..dd4adb05235c34 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml @@ -64027,6 +64027,7 @@ Called by update_net_trust_anchors.py.--> <int value="12" label="kPlugin"/> <int value="13" label="kRendererProcessCrashed"/> <int value="14" label="kRendererProcessKilled"/> + <int value="15" label="kDownload"/> </enum> <enum name="PrerenderHoverEvent"> From 6f02a9cb2589ebded071902b7e1af7fdbc74182c Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 13:17:09 +0000 Subject: [PATCH 56/81] Roll RTS model from KEqicFtFO... to M668EbK0T... If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/rts-windows-amd64-chromium-autoroll Please CC nodir@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Tbr: nodir@google.com Change-Id: I429d179bf218306e7b7db185e9f9f1bbc66d851a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929899 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887933} --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index f9b3fd135b2c87..6fae90f06b1035 100644 --- a/DEPS +++ b/DEPS @@ -665,7 +665,7 @@ deps = { 'packages': [ { 'package': 'chromium/rts/model/windows-amd64', - 'version': 'KEqicFtFOQ7QG3MH4ZNilLLBf6T_i6PHqx4O0j-ADVYC', + 'version': 'M668EbK0TLr4XWelPNWUCwz-8fDE1RMeO0xvXR4Y4rsC', }, ], 'dep_type': 'cipd', From 395c854fda79e0aaa2aca5ba4f9ee11f8802b4c5 Mon Sep 17 00:00:00 2001 From: "3su6n15k.default@developer.gserviceaccount.com" <3su6n15k.default@developer.gserviceaccount.com> Date: Tue, 1 Jun 2021 13:25:02 +0000 Subject: [PATCH 57/81] Automated Commit: LKGM 14006.0.0 for chromeos. CQ_INCLUDE_TRYBOTS=luci.chrome.try:chromeos-betty-pi-arc-chrome CQ_INCLUDE_TRYBOTS=luci.chrome.try:chromeos-eve-chrome CQ_INCLUDE_TRYBOTS=luci.chrome.try:chromeos-kevin-chrome CQ_INCLUDE_TRYBOTS=luci.chrome.try:lacros-amd64-generic-chrome R=chrome-os-gardeners+review@google.com Change-Id: I886956c496f67fc507c6e4b5f1d015fee0508030 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2927987 Commit-Queue: ChromeOS bot <3su6n15k.default@developer.gserviceaccount.com> Bot-Commit: ChromeOS bot <3su6n15k.default@developer.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887934} --- chromeos/CHROMEOS_LKGM | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 4dea8125aa04fb..facdcb3f44021a 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM @@ -1 +1 @@ -14005.0.0 \ No newline at end of file +14006.0.0 \ No newline at end of file From d07fdeafc49f54aee76e9d753c02c5fdad5e9d35 Mon Sep 17 00:00:00 2001 From: Maksim Sisov <msisov@igalia.com> Date: Tue, 1 Jun 2021 13:28:15 +0000 Subject: [PATCH 58/81] ozone/wayland: do not create wl_buffers for staging pixmaps. 1/* https://crrev.com/c/1837614 introduced a concept of anonymous images, which SkiaRenderer might have created and committed. It was unknown which surface a pixmap belongs to. However, this was changed at some point and buffers that are to be committed (scheduled as overlays) seem to always be created for a specific widget (I checked out the old code when the above mentioned patch was submitted and verified that buffers that were created to be committed were created without a widget specified, but now they are always created for a specific widget). Thus, do not create buffers unnecessarily. This reduces the number of IPCs and also the memory footprint. And also make it possible for my next CL to take a scale factor of a surface that a buffer is created for. Change-Id: Ifc490c4ac298c0c423ad9c5e8d36b6b22f10e5ee Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2910203 Commit-Queue: Maksim Sisov <msisov@igalia.com> Reviewed-by: Robert Kroeger <rjkroege@chromium.org> Reviewed-by: Kramer Ge <fangzhoug@chromium.org> Cr-Commit-Position: refs/heads/master@{#887935} --- .../platform/wayland/gpu/gbm_pixmap_wayland.cc | 14 ++++++-------- ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h | 10 +++++----- .../wayland/gpu/wayland_surface_factory.cc | 5 +---- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc index f334a2b27e0df3..12b8aa22fd60ea 100644 --- a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc +++ b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc @@ -33,11 +33,12 @@ GbmPixmapWayland::GbmPixmapWayland(WaylandBufferManagerGpu* buffer_manager) buffer_id_(buffer_manager->AllocateBufferID()) {} GbmPixmapWayland::~GbmPixmapWayland() { - if (gbm_bo_) + if (gbm_bo_ && widget_ != gfx::kNullAcceleratedWidget) buffer_manager_->DestroyBuffer(widget_, buffer_id_); } bool GbmPixmapWayland::InitializeBuffer( + gfx::AcceleratedWidget widget, gfx::Size size, gfx::BufferFormat format, gfx::BufferUsage usage, @@ -47,6 +48,8 @@ bool GbmPixmapWayland::InitializeBuffer( (visible_area_size.value().height() <= size.height()))); TRACE_EVENT0("wayland", "GbmPixmapWayland::InitializeBuffer"); + widget_ = widget; + if (!buffer_manager_->gbm_device()) return false; @@ -80,16 +83,11 @@ bool GbmPixmapWayland::InitializeBuffer( << " usage=" << gfx::BufferUsageToString(usage); visible_area_size_ = visible_area_size ? visible_area_size.value() : size; - CreateDmabufBasedBuffer(); + if (widget_ != gfx::kNullAcceleratedWidget) + CreateDmabufBasedBuffer(); return true; } -void GbmPixmapWayland::SetAcceleratedWiget(gfx::AcceleratedWidget widget) { - DCHECK(widget != gfx::kNullAcceleratedWidget); - DCHECK(widget_ == gfx::kNullAcceleratedWidget); - widget_ = widget; -} - bool GbmPixmapWayland::AreDmaBufFdsValid() const { return gbm_bo_->AreFdsValid(); } diff --git a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h index 6bb1f674faede1..af9d927b34171e 100644 --- a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h +++ b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h @@ -14,6 +14,7 @@ #include "ui/gfx/geometry/size.h" #include "ui/gfx/linux/gbm_buffer.h" #include "ui/gfx/native_pixmap.h" +#include "ui/gfx/native_widget_types.h" namespace ui { @@ -27,17 +28,16 @@ class GbmPixmapWayland : public gfx::NativePixmap { // |visible_area_size| represents a 'visible size', i.e., a buffer // of size |size| may actually contain visible data only in the // subregion of size |visible_area_size|. If |visible_area_size| is - // not provided, |size| is used. + // not provided, |size| is used. If |widget| is provided, browser + // side wl_buffer is also created. Otherwise, this pixmap + // behaves as a staging pixmap and mustn't be scheduled as an overlay. bool InitializeBuffer( + gfx::AcceleratedWidget widget, gfx::Size size, gfx::BufferFormat format, gfx::BufferUsage usage, absl::optional<gfx::Size> visible_area_size = absl::nullopt); - // The widget that this pixmap backs can be assigned later. Can be assigned - // only once. - void SetAcceleratedWiget(gfx::AcceleratedWidget widget); - // gfx::NativePixmap overrides: bool AreDmaBufFdsValid() const override; int GetDmaBufFd(size_t plane) const override; diff --git a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc index a2ca45477200b6..7d11962cf201ac 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc +++ b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc @@ -186,10 +186,7 @@ scoped_refptr<gfx::NativePixmap> WaylandSurfaceFactory::CreateNativePixmap( scoped_refptr<GbmPixmapWayland> pixmap = base::MakeRefCounted<GbmPixmapWayland>(buffer_manager_); - if (widget != gfx::kNullAcceleratedWidget) - pixmap->SetAcceleratedWiget(widget); - - if (!pixmap->InitializeBuffer(size, format, usage, framebuffer_size)) + if (!pixmap->InitializeBuffer(widget, size, format, usage, framebuffer_size)) return nullptr; return pixmap; #else From 9b5bc72e9fdec1b854b5ac6da21912604177e750 Mon Sep 17 00:00:00 2001 From: Kent Tamura <tkent@chromium.org> Date: Tue, 1 Jun 2021 13:29:44 +0000 Subject: [PATCH 59/81] SVG Text NG: Cleanup of NGInlineBoxState Set |style|, |is_svg_text|, and update font information in a single function. This CL has no behavior changes, and is just for code health. Bug: 1179585 Change-Id: Ic081d92c54ea1a7ccb7810f5b174fb09ddba9120 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929639 Reviewed-by: Koji Ishii <kojii@chromium.org> Reviewed-by: Yoshifumi Inoue <yosin@chromium.org> Commit-Queue: Kent Tamura <tkent@chromium.org> Cr-Commit-Position: refs/heads/master@{#887936} --- .../core/layout/ng/inline/ng_inline_box_state.cc | 15 ++++++++------- .../core/layout/ng/inline/ng_inline_box_state.h | 7 ++++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc index 85a0e8fd82012f..1c7764a6f28712 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.cc @@ -63,7 +63,11 @@ NGInlineBoxState::NGInlineBoxState(const NGInlineBoxState&& state) font = state.font; } -void NGInlineBoxState::InitializeFont(const LayoutObject& layout_object) { +void NGInlineBoxState::ResetStyle(const ComputedStyle& style_ref, + bool is_svg, + const LayoutObject& layout_object) { + style = &style_ref; + is_svg_text = is_svg; if (!is_svg_text) { scaling_factor = 1.0f; font = &style->GetFont(); @@ -194,9 +198,8 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnBeginPlaceItems( // Initialize the box state for the line box. NGInlineBoxState& line_box_state = LineBoxState(); if (line_box_state.style != &line_style) { - line_box_state.style = &line_style; - line_box_state.is_svg_text = node.IsSvgText(); - line_box_state.InitializeFont(*node.GetLayoutBox()); + line_box_state.ResetStyle(line_style, node.IsSvgText(), + *node.GetLayoutBox()); // Use a "strut" (a zero-width inline box with the element's font and // line height properties) as the initial metrics for the line box. @@ -233,9 +236,7 @@ NGInlineBoxState* NGInlineLayoutStateStack::OnOpenTag( stack_.resize(stack_.size() + 1); NGInlineBoxState* box = &stack_.back(); box->fragment_start = line_box.size(); - box->style = &style; - box->is_svg_text = is_svg_text_; - box->InitializeFont(*item.GetLayoutObject()); + box->ResetStyle(style, is_svg_text_, *item.GetLayoutObject()); box->item = &item; box->has_start_edge = item_result.has_edge; box->margin_inline_start = item_result.margins.inline_start; diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h index a2174d8387cc4f..109ead58b0a3a9 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_box_state.h @@ -91,9 +91,10 @@ struct NGInlineBoxState { NGInlineBoxState(const NGInlineBoxState&) = delete; NGInlineBoxState& operator=(const NGInlineBoxState&) = delete; - // Initialize |font| and |scaled_font|. This should be called after setting - // |style| and |is_svg_text|. - void InitializeFont(const LayoutObject& layout_object); + // Reset |style|, |is_svg_text|, |font|, |scaled_font|, and |scaling_factor|. + void ResetStyle(const ComputedStyle& style_ref, + bool is_svg, + const LayoutObject& layout_object); // True if this box has a metrics, including pending ones. Pending metrics // will be activated in |EndBoxState()|. From a3ef7993efaaea0dc745839ddf9cd2411ec4be80 Mon Sep 17 00:00:00 2001 From: Steve Kobes <skobes@chromium.org> Date: Tue, 1 Jun 2021 13:29:47 +0000 Subject: [PATCH 60/81] Disable a test for smooth scroll interruption. Bug: 1116647,1086625 Change-Id: I0fdd53eb6283842b7ae91dd41a2d50a6c0e03441 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928477 Reviewed-by: David Bokan <bokan@chromium.org> Commit-Queue: Steve Kobes <skobes@chromium.org> Cr-Commit-Position: refs/heads/master@{#887937} --- .../renderer_host/input/scroll_behavior_browsertest.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/browser/renderer_host/input/scroll_behavior_browsertest.cc b/content/browser/renderer_host/input/scroll_behavior_browsertest.cc index af7534ae0e604f..f9e24afb8b9e9c 100644 --- a/content/browser/renderer_host/input/scroll_behavior_browsertest.cc +++ b/content/browser/renderer_host/input/scroll_behavior_browsertest.cc @@ -302,8 +302,10 @@ IN_PROC_BROWSER_TEST_P(ScrollBehaviorBrowserTest, // This tests that a in-progress smooth scroll on an overflow:scroll element // stops when interrupted by a touch scroll. +// Currently only pre-Scroll-Unification main-thread input-handling gets this +// right (crbug.com/1116647#c5). IN_PROC_BROWSER_TEST_P(ScrollBehaviorBrowserTest, - OverflowScrollInterruptedByTouchScroll) { + DISABLED_OverflowScrollInterruptedByTouchScroll) { // TODO(crbug.com/1116647): compositing scroll should be able to cancel a // running programmatic scroll. if (!disable_threaded_scrolling_) From 7978569bae60e6095bf7e15253d990834d82f9cb Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 13:31:11 +0000 Subject: [PATCH 61/81] Roll RTS model from riSig3Jqa... to oALhDKVke... If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/rts-linux-amd64-chromium-autoroll Please CC nodir@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Tbr: nodir@google.com Change-Id: Ibd65e88ed12ff024e4814d3da608701cba2382fe Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928801 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887938} --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 6fae90f06b1035..f67c40d40ee631 100644 --- a/DEPS +++ b/DEPS @@ -643,7 +643,7 @@ deps = { 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': 'riSig3JqaTPXRJyArMbQCNmMd2MM4C5qAkr7enZF5f8C', + 'version': 'oALhDKVkeAzkGeq7XrFKM1mUTH2TaYJGQkXwM7RytDYC', }, ], 'dep_type': 'cipd', From 07f7d526d148e2c3336d97ab830a198bfa3065c1 Mon Sep 17 00:00:00 2001 From: Gayane Petrosyan <gayane@chromium.org> Date: Tue, 1 Jun 2021 13:31:41 +0000 Subject: [PATCH 62/81] Separate SharedHighlighting config from Sharing hub Change-Id: I74f474adec4e024a2ca525c491013694d7619a92 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929038 Reviewed-by: Robert Kaplow <rkaplow@chromium.org> Commit-Queue: Gayane Petrosyan <gayane@chromium.org> Cr-Commit-Position: refs/heads/master@{#887939} --- .../variations/fieldtrial_testing_config.json | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 7774cdf64beb7b..8269ddfee08464 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json @@ -1798,8 +1798,7 @@ { "name": "Enabled", "enable_features": [ - "ChromeShareScreenshot", - "PreemptiveLinkToTextGeneration" + "ChromeShareScreenshot" ], "min_os_version": "5.1" } @@ -7084,6 +7083,21 @@ ] } ], + "SharedHighlightingClank": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PreemptiveLinkToTextGeneration" + ] + } + ] + } + ], "SharedHighlightingIOS": [ { "platforms": [ From 6b371ba186d0845cc8125cd39ad3f289ec80cc73 Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 13:34:51 +0000 Subject: [PATCH 63/81] Roll Fuchsia SDK from 4.20210531.3.1 to 4.20210601.1.1 If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/fuchsia-sdk-chromium-autoroll Please CC chrome-fuchsia-gardener@grotations.appspotmail.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chromium.try:fuchsia-arm64-cast;luci.chromium.try:fuchsia-deterministic-dbg;luci.chromium.try:fuchsia-x64-cast Tbr: chrome-fuchsia-gardener@grotations.appspotmail.com Disable-Retries: true Change-Id: Ie29f444ba3be2b55dda456f424345b6604f5de72 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928327 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887940} --- build/fuchsia/linux.sdk.sha1 | 2 +- build/fuchsia/mac.sdk.sha1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 00ff4fa55b86da..711d54018b3dc9 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1 @@ -1 +1 @@ -4.20210531.3.1 +4.20210601.1.1 diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 00ff4fa55b86da..711d54018b3dc9 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1 @@ -1 +1 @@ -4.20210531.3.1 +4.20210601.1.1 From 96918f3b28ca2cc68fb28f459ac8f342bc375cae Mon Sep 17 00:00:00 2001 From: Ioana Pandele <ioanap@chromium.org> Date: Tue, 1 Jun 2021 13:35:51 +0000 Subject: [PATCH 64/81] [PwdEditAndroid] Don't call GetUsernamesForRealm for blocked credentials The blocked credentials UI doesn't have/need usernames. The method searches for usernames that match the signon realm for the saved password form corresponding to the given index. For blocked credentials, the given index didn't correspond to a saved password form, but to a blocked one. Bug: 1214043 Change-Id: I323134a5de582b62bc04980ba12a0db1d42e47bf Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929193 Reviewed-by: Friedrich [CET] <fhorschig@chromium.org> Commit-Queue: Ioana Pandele <ioanap@chromium.org> Cr-Commit-Position: refs/heads/master@{#887941} --- .../password_manager/android/password_ui_view_android.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/chrome/browser/password_manager/android/password_ui_view_android.cc b/chrome/browser/password_manager/android/password_ui_view_android.cc index a63fceaf701b0a..35c1e40c92ff5c 100644 --- a/chrome/browser/password_manager/android/password_ui_view_android.cc +++ b/chrome/browser/password_manager/android/password_ui_view_android.cc @@ -235,8 +235,7 @@ void PasswordUIViewAndroid::HandleShowBlockedCredentialView( password_manager_presenter_.GetPasswordException(index); if (form && !credential_edit_bridge_) { credential_edit_bridge_ = CredentialEditBridge::MaybeCreate( - *form, IsInsecureCredential(false), - password_manager_presenter_.GetUsernamesForRealm(index), + *form, IsInsecureCredential(false), std::vector<std::u16string>(), &saved_passwords_presenter_, &password_manager_presenter_, base::BindOnce(&PasswordUIViewAndroid::OnEditUIDismissed, base::Unretained(this)), From 22e41c37d741bd0b77057538a0c97461a99e2133 Mon Sep 17 00:00:00 2001 From: Eriko Kurimoto <elkurin@chromium.org> Date: Tue, 1 Jun 2021 13:37:51 +0000 Subject: [PATCH 65/81] Set use_custom_libcxx to false for Chrome OS Lacros build This CL changes the parameter use_custom_libcxx for ChromeOS Lacros build. This is a part of Lacros args.gn simplification (go/simplelacros). This CL changes the behavior only when IS_CHROMEOS_LACROS && default_toolchain != "//build/toolchain/cros:target" In this case, |use_custom_libcxx| is changed from true to false. Bug: 1203201 Change-Id: Ieb37e7cf7b55c29edac3e1b29d27ebde10fed712 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2902159 Reviewed-by: Hidehiko Abe <hidehiko@chromium.org> Reviewed-by: Nico Weber <thakis@chromium.org> Commit-Queue: Nico Weber <thakis@chromium.org> Cr-Commit-Position: refs/heads/master@{#887942} --- build/config/c++/c++.gni | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/build/config/c++/c++.gni b/build/config/c++/c++.gni index a7448f3a0a6a3a..8a29edefcc4b28 100644 --- a/build/config/c++/c++.gni +++ b/build/config/c++/c++.gni @@ -11,11 +11,12 @@ declare_args() { # standard library support. # Don't check in changes that set this to false for more platforms; doing so # is not supported. - use_custom_libcxx = is_fuchsia || is_android || is_mac || - (is_ios && !use_xcode_clang) || (is_win && is_clang) || - ((is_linux || is_chromeos) && - (!is_chromeos_ash || - default_toolchain != "//build/toolchain/cros:target")) + # We always use system installed libc++ on building chrome (incl. both Ash + # and Lacros Chrome) running on Chrome OS devices with cros-toolchain. + use_custom_libcxx = + is_fuchsia || is_android || is_mac || is_linux || + (is_ios && !use_xcode_clang) || (is_win && is_clang) || + (is_chromeos && default_toolchain != "//build/toolchain/cros:target") # Use libc++ instead of stdlibc++ when using the host_cpu toolchain, even if # use_custom_libcxx is false. This is useful for cross-compiles where a custom From b908188ce235957fbddc9056f42279fc04bce6c4 Mon Sep 17 00:00:00 2001 From: Samuel Huang <huangs@chromium.org> Date: Tue, 1 Jun 2021 13:41:14 +0000 Subject: [PATCH 66/81] [Lacros] Add Lacros PowerSaveBlocker that calls Ash's impl via crosapi. On ChromeOS, power management / wake lock ultimately uses D-Bus API. This CL brings the feature to Lacros by having Lacros call Ash's impl via crosapi. The layer chosen to interface with crosapi is device::PowerSaveBlocker because it admits architecture specific impls, and sits below device::WakeLock, which is used by extension API (chrome.power) and non-extension features such as video / audio playback and download. Details: * Add Lacros PowerSaveBlocker impl. * Lacros PowerSaveBlocker calls new crosapi.mojom.Power function AddPowerSaveBlocker() and pass its main params. * To maintain an RAII interface like PowerSaveBlocker, a mojom::Remote is also passed, and disconnection (purposeful or due to Lacros exit / crash) is used to release lock. * On Ash side, crosapi.mojom.Power maintains ChromeOS PowerSaveBlocker instances. Bug: 1210957 Change-Id: I0c7b31c7f919c2e695788395d32670fead6c4457 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2906374 Commit-Queue: Samuel Huang <huangs@chromium.org> Reviewed-by: Emily Stark <estark@chromium.org> Reviewed-by: Colin Blundell <blundell@chromium.org> Reviewed-by: Calder Kitagawa <ckitagawa@chromium.org> Reviewed-by: Erik Chen <erikchen@chromium.org> Cr-Commit-Position: refs/heads/master@{#887943} --- chrome/browser/ash/crosapi/BUILD.gn | 3 + chrome/browser/ash/crosapi/DEPS | 3 + chrome/browser/ash/crosapi/browser_util.cc | 4 +- chrome/browser/ash/crosapi/crosapi_ash.cc | 6 ++ chrome/browser/ash/crosapi/crosapi_ash.h | 3 + chrome/browser/ash/crosapi/power_ash.cc | 45 ++++++++++ chrome/browser/ash/crosapi/power_ash.h | 74 +++++++++++++++ chromeos/crosapi/mojom/BUILD.gn | 1 + chromeos/crosapi/mojom/crosapi.mojom | 12 ++- chromeos/crosapi/mojom/power.mojom | 23 +++++ chromeos/lacros/lacros_chrome_service_impl.cc | 3 + components/paint_preview/browser/BUILD.gn | 6 ++ components/paint_preview/browser/DEPS | 1 + .../paint_preview_base_service_unittest.cc | 9 ++ services/device/public/mojom/wake_lock.mojom | 2 + .../wake_lock/power_save_blocker/BUILD.gn | 15 +++- ..._chromeos.cc => power_save_blocker_ash.cc} | 6 +- .../power_save_blocker_lacros.cc | 89 +++++++++++++++++++ 18 files changed, 296 insertions(+), 9 deletions(-) create mode 100644 chrome/browser/ash/crosapi/power_ash.cc create mode 100644 chrome/browser/ash/crosapi/power_ash.h create mode 100644 chromeos/crosapi/mojom/power.mojom rename services/device/wake_lock/power_save_blocker/{power_save_blocker_chromeos.cc => power_save_blocker_ash.cc} (97%) create mode 100644 services/device/wake_lock/power_save_blocker/power_save_blocker_lacros.cc diff --git a/chrome/browser/ash/crosapi/BUILD.gn b/chrome/browser/ash/crosapi/BUILD.gn index b6b63495afe32b..69aa355611b035 100644 --- a/chrome/browser/ash/crosapi/BUILD.gn +++ b/chrome/browser/ash/crosapi/BUILD.gn @@ -63,6 +63,8 @@ source_set("crosapi") { "message_center_ash.h", "metrics_reporting_ash.cc", "metrics_reporting_ash.h", + "power_ash.cc", + "power_ash.h", "prefs_ash.cc", "prefs_ash.h", "screen_manager_ash.cc", @@ -129,6 +131,7 @@ source_set("crosapi") { "//extensions/common", "//printing:printing", "//printing:printing_base", + "//services/device/wake_lock/power_save_blocker", "//ui/message_center", "//ui/message_center/public/cpp", "//ui/shell_dialogs", diff --git a/chrome/browser/ash/crosapi/DEPS b/chrome/browser/ash/crosapi/DEPS index 37178cbcd6078d..47c672ef1c248b 100644 --- a/chrome/browser/ash/crosapi/DEPS +++ b/chrome/browser/ash/crosapi/DEPS @@ -6,6 +6,9 @@ specific_include_rules = { "+chrome/browser/ash/crosapi", "+ui/message_center/message_center.h", ], + "power_ash\.cc": [ + "+services/device/wake_lock/power_save_blocker/power_save_blocker.h", + ], "screen_manager_ash\.cc": [ # For window parenting. "+ash/shell.h", diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc index 72b4dd290fe58c..7ed7b4ed5272b0 100644 --- a/chrome/browser/ash/crosapi/browser_util.cc +++ b/chrome/browser/ash/crosapi/browser_util.cc @@ -54,6 +54,7 @@ #include "chromeos/crosapi/mojom/local_printer.mojom.h" #include "chromeos/crosapi/mojom/message_center.mojom.h" #include "chromeos/crosapi/mojom/metrics_reporting.mojom.h" +#include "chromeos/crosapi/mojom/power.mojom.h" #include "chromeos/crosapi/mojom/prefs.mojom.h" #include "chromeos/crosapi/mojom/screen_manager.mojom.h" #include "chromeos/crosapi/mojom/system_display.mojom.h" @@ -232,6 +233,7 @@ constexpr InterfaceVersionEntry kInterfaceVersionEntries[] = { chromeos::machine_learning::mojom::MachineLearningService>(), MakeInterfaceVersionEntry<crosapi::mojom::MessageCenter>(), MakeInterfaceVersionEntry<crosapi::mojom::MetricsReporting>(), + MakeInterfaceVersionEntry<crosapi::mojom::Power>(), MakeInterfaceVersionEntry<crosapi::mojom::Prefs>(), MakeInterfaceVersionEntry<crosapi::mojom::ScreenManager>(), MakeInterfaceVersionEntry<crosapi::mojom::SnapshotCapturer>(), @@ -261,7 +263,7 @@ constexpr bool HasDuplicatedUuid() { } static_assert( - crosapi::mojom::Crosapi::Version_ == 29, + crosapi::mojom::Crosapi::Version_ == 30, "if you add a new crosapi, please add it to kInterfaceVersionEntries"); static_assert(!HasDuplicatedUuid(), "Each Crosapi Mojom interface should have unique UUID."); diff --git a/chrome/browser/ash/crosapi/crosapi_ash.cc b/chrome/browser/ash/crosapi/crosapi_ash.cc index 68c8843756c9fb..cee01cd1650366 100644 --- a/chrome/browser/ash/crosapi/crosapi_ash.cc +++ b/chrome/browser/ash/crosapi/crosapi_ash.cc @@ -31,6 +31,7 @@ #include "chrome/browser/ash/crosapi/local_printer_ash.h" #include "chrome/browser/ash/crosapi/message_center_ash.h" #include "chrome/browser/ash/crosapi/metrics_reporting_ash.h" +#include "chrome/browser/ash/crosapi/power_ash.h" #include "chrome/browser/ash/crosapi/prefs_ash.h" #include "chrome/browser/ash/crosapi/screen_manager_ash.h" #include "chrome/browser/ash/crosapi/select_file_ash.h" @@ -103,6 +104,7 @@ CrosapiAsh::CrosapiAsh() message_center_ash_(std::make_unique<MessageCenterAsh>()), metrics_reporting_ash_(std::make_unique<MetricsReportingAsh>( g_browser_process->local_state())), + power_ash_(std::make_unique<PowerAsh>()), prefs_ash_( std::make_unique<PrefsAsh>(g_browser_process->profile_manager(), g_browser_process->local_state())), @@ -293,6 +295,10 @@ void CrosapiAsh::BindSensorHalClient( std::move(remote)); } +void CrosapiAsh::BindPower(mojo::PendingReceiver<mojom::Power> receiver) { + power_ash_->BindReceiver(std::move(receiver)); +} + void CrosapiAsh::BindPrefs(mojo::PendingReceiver<mojom::Prefs> receiver) { prefs_ash_->BindReceiver(std::move(receiver)); } diff --git a/chrome/browser/ash/crosapi/crosapi_ash.h b/chrome/browser/ash/crosapi/crosapi_ash.h index 2b29d8dc473033..bbf7af537de15c 100644 --- a/chrome/browser/ash/crosapi/crosapi_ash.h +++ b/chrome/browser/ash/crosapi/crosapi_ash.h @@ -34,6 +34,7 @@ class KeystoreServiceAsh; class LocalPrinterAsh; class MessageCenterAsh; class MetricsReportingAsh; +class PowerAsh; class PrefsAsh; class ScreenManagerAsh; class SelectFileAsh; @@ -92,6 +93,7 @@ class CrosapiAsh : public mojom::Crosapi { mojo::PendingReceiver<mojom::MessageCenter> receiver) override; void BindMetricsReporting( mojo::PendingReceiver<mojom::MetricsReporting> receiver) override; + void BindPower(mojo::PendingReceiver<mojom::Power> receiver) override; void BindPrefs(mojo::PendingReceiver<mojom::Prefs> receiver) override; void BindScreenManager( mojo::PendingReceiver<mojom::ScreenManager> receiver) override; @@ -167,6 +169,7 @@ class CrosapiAsh : public mojom::Crosapi { std::unique_ptr<LocalPrinterAsh> local_printer_ash_; std::unique_ptr<MessageCenterAsh> message_center_ash_; std::unique_ptr<MetricsReportingAsh> metrics_reporting_ash_; + std::unique_ptr<PowerAsh> power_ash_; std::unique_ptr<PrefsAsh> prefs_ash_; std::unique_ptr<ScreenManagerAsh> screen_manager_ash_; std::unique_ptr<SelectFileAsh> select_file_ash_; diff --git a/chrome/browser/ash/crosapi/power_ash.cc b/chrome/browser/ash/crosapi/power_ash.cc new file mode 100644 index 00000000000000..263f81d0aa0923 --- /dev/null +++ b/chrome/browser/ash/crosapi/power_ash.cc @@ -0,0 +1,45 @@ +// Copyright 2021 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/ash/crosapi/power_ash.h" + +#include <utility> + +#include "base/bind.h" +#include "base/sequenced_task_runner.h" +#include "base/single_thread_task_runner.h" +#include "base/task/thread_pool.h" +#include "services/device/wake_lock/power_save_blocker/power_save_blocker.h" + +namespace crosapi { + +PowerAsh::PowerAsh() + : main_task_runner_(base::ThreadTaskRunnerHandle::Get()), + file_task_runner_(base::ThreadPool::CreateSingleThreadTaskRunner( + {base::MayBlock(), base::TaskPriority::BEST_EFFORT})) { + lock_set_.set_disconnect_handler(base::BindRepeating( + &PowerAsh::OnLockDisconnect, weak_ptr_factory_.GetWeakPtr())); +} + +PowerAsh::~PowerAsh() = default; + +void PowerAsh::BindReceiver(mojo::PendingReceiver<mojom::Power> receiver) { + receivers_.Add(this, std::move(receiver)); +} + +void PowerAsh::AddPowerSaveBlocker( + mojo::PendingRemote<mojom::PowerWakeLock> lock, + device::mojom::WakeLockType type, + device::mojom::WakeLockReason reason, + const std::string& description) { + mojo::RemoteSetElementId id = lock_set_.Add(std::move(lock)); + power_save_blockers_[id] = std::make_unique<device::PowerSaveBlocker>( + type, reason, description, main_task_runner_, file_task_runner_); +} + +void PowerAsh::OnLockDisconnect(mojo::RemoteSetElementId id) { + power_save_blockers_.erase(id); +} + +} // namespace crosapi diff --git a/chrome/browser/ash/crosapi/power_ash.h b/chrome/browser/ash/crosapi/power_ash.h new file mode 100644 index 00000000000000..6090be6f08b680 --- /dev/null +++ b/chrome/browser/ash/crosapi/power_ash.h @@ -0,0 +1,74 @@ +// Copyright 2021 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_ASH_CROSAPI_POWER_ASH_H_ +#define CHROME_BROWSER_ASH_CROSAPI_POWER_ASH_H_ + +#include <stdint.h> + +#include <map> +#include <memory> +#include <string> + +#include "base/memory/weak_ptr.h" +#include "chromeos/crosapi/mojom/power.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/bindings/remote_set.h" +#include "services/device/public/mojom/wake_lock.mojom.h" + +namespace base { +class SequencedTaskRunner; +class SingleThreadTaskRunner; +} // namespace base + +namespace device { +class PowerSaveBlocker; +} // namespace device + +namespace crosapi { + +// The ash-chrome implementation of the Power crosapi interface. +class PowerAsh : public mojom::Power { + public: + PowerAsh(); + PowerAsh(const PowerAsh&) = delete; + PowerAsh& operator=(const PowerAsh&) = delete; + ~PowerAsh() override; + + void BindReceiver(mojo::PendingReceiver<mojom::Power> receiver); + + // crosapi::mojom::Power: + void AddPowerSaveBlocker(mojo::PendingRemote<mojom::PowerWakeLock> lock, + device::mojom::WakeLockType type, + device::mojom::WakeLockReason reason, + const std::string& description) override; + + private: + // Handlers for disconnection of |lock| from AddPowerSaveBlocker(), + void OnLockDisconnect(mojo::RemoteSetElementId id); + + // Support any number of connections. + mojo::ReceiverSet<mojom::Power> receivers_; + + // Keeps track of |lock| passed by AddPowerSaveBlocker(), allowing + // disconnection to be detected. + mojo::RemoteSet<mojom::PowerWakeLock> lock_set_; + + // Storage of device::PowerSaveBlocker instances, keyed by + // mojo::RemoteSetElementId in |lock_set_|. + std::map<mojo::RemoteSetElementId, std::unique_ptr<device::PowerSaveBlocker>> + power_save_blockers_; + + // Task runners needed by device::PowerSaveBlocker. + scoped_refptr<base::SequencedTaskRunner> main_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; + + base::WeakPtrFactory<PowerAsh> weak_ptr_factory_{this}; +}; + +} // namespace crosapi + +#endif // CHROME_BROWSER_ASH_CROSAPI_POWER_ASH_H_ diff --git a/chromeos/crosapi/mojom/BUILD.gn b/chromeos/crosapi/mojom/BUILD.gn index b0c010d784256f..1ce489f182762f 100644 --- a/chromeos/crosapi/mojom/BUILD.gn +++ b/chromeos/crosapi/mojom/BUILD.gn @@ -29,6 +29,7 @@ mojom("mojom") { "message_center.mojom", "metrics_reporting.mojom", "notification.mojom", + "power.mojom", "prefs.mojom", "screen_manager.mojom", "select_file.mojom", diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom index a499f39f415ee5..98eaf5002f363c 100644 --- a/chromeos/crosapi/mojom/crosapi.mojom +++ b/chromeos/crosapi/mojom/crosapi.mojom @@ -23,6 +23,7 @@ import "chromeos/crosapi/mojom/keystore_service.mojom"; import "chromeos/crosapi/mojom/local_printer.mojom"; import "chromeos/crosapi/mojom/message_center.mojom"; import "chromeos/crosapi/mojom/metrics_reporting.mojom"; +import "chromeos/crosapi/mojom/power.mojom"; import "chromeos/crosapi/mojom/prefs.mojom"; import "chromeos/crosapi/mojom/screen_manager.mojom"; import "chromeos/crosapi/mojom/select_file.mojom"; @@ -60,8 +61,8 @@ struct BrowserInfo { // please note the milestone when you added it, to help us reason about // compatibility between the client applications and older ash-chrome binaries. // -// Next version: 30 -// Next method id: 35 +// Next version: 31 +// Next method id: 36 [Stable, Uuid="8b79c34f-2bf8-4499-979a-b17cac522c1e", RenamedFrom="crosapi.mojom.AshChromeService"] interface Crosapi { @@ -126,7 +127,8 @@ interface Crosapi { // Binds the DriveIntegrationService interface for getting information about // the local Google Drive mount. // Added in M93. - [MinVersion=29] BindDriveIntegrationService@34(pending_receiver<DriveIntegrationService> receiver); + [MinVersion=29] BindDriveIntegrationService@34( + pending_receiver<DriveIntegrationService> receiver); // Binds the FileManager interface for showing files, folders, etc. // Added in M88. @@ -210,6 +212,10 @@ interface Crosapi { [MinVersion=6] BindMediaSessionAudioFocusDebug@11( pending_receiver<media_session.mojom.AudioFocusManagerDebug> receiver); + // Binds the Power interface for power management. + // Added in M92. + [MinVersion=30] BindPower@35(pending_receiver<Power> receiver); + // Binds the System Display interface for querying display info. // Added in M92. [MinVersion=24] BindSystemDisplay@29( diff --git a/chromeos/crosapi/mojom/power.mojom b/chromeos/crosapi/mojom/power.mojom new file mode 100644 index 00000000000000..87dd3dc253f7ac --- /dev/null +++ b/chromeos/crosapi/mojom/power.mojom @@ -0,0 +1,23 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module crosapi.mojom; + +import "services/device/public/mojom/wake_lock.mojom"; + +// An empty interface to enable Power.AddPowerSaveBlocker() to maintain a +// connection to its caller, and free resources on disconnect. +[Stable, Uuid="742bde40-5689-44bb-807e-6252ff54d635"] +interface PowerWakeLock { +}; + +// Crosapi support for chrome.system.display extensions API. +[Stable, Uuid="878f8be2-ad59-4cc6-84ef-abc5102da696"] +interface Power { + // Creates a PowerSaveBlocker that lasts until |lock| disconnects. + AddPowerSaveBlocker@0(pending_remote<PowerWakeLock> lock, + device.mojom.WakeLockType type, + device.mojom.WakeLockReason reason, + string description); +}; diff --git a/chromeos/lacros/lacros_chrome_service_impl.cc b/chromeos/lacros/lacros_chrome_service_impl.cc index f40de44601e27f..eb1414c5a03784 100644 --- a/chromeos/lacros/lacros_chrome_service_impl.cc +++ b/chromeos/lacros/lacros_chrome_service_impl.cc @@ -31,6 +31,7 @@ #include "chromeos/crosapi/mojom/local_printer.mojom.h" #include "chromeos/crosapi/mojom/message_center.mojom.h" #include "chromeos/crosapi/mojom/metrics_reporting.mojom.h" +#include "chromeos/crosapi/mojom/power.mojom.h" #include "chromeos/crosapi/mojom/prefs.mojom.h" #include "chromeos/crosapi/mojom/screen_manager.mojom.h" #include "chromeos/crosapi/mojom/select_file.mojom.h" @@ -238,6 +239,8 @@ LacrosChromeServiceImpl::LacrosChromeServiceImpl( ConstructRemote<crosapi::mojom::MessageCenter, &crosapi::mojom::Crosapi::BindMessageCenter, Crosapi::MethodMinVersions::kBindMessageCenterMinVersion>(); + ConstructRemote<crosapi::mojom::Power, &crosapi::mojom::Crosapi::BindPower, + Crosapi::MethodMinVersions::kBindPowerMinVersion>(); ConstructRemote<crosapi::mojom::Prefs, &crosapi::mojom::Crosapi::BindPrefs, Crosapi::MethodMinVersions::kBindPrefsMinVersion>(); ConstructRemote<crosapi::mojom::SelectFile, diff --git a/components/paint_preview/browser/BUILD.gn b/components/paint_preview/browser/BUILD.gn index 41d74474d50f6d..7dc28043c38df2 100644 --- a/components/paint_preview/browser/BUILD.gn +++ b/components/paint_preview/browser/BUILD.gn @@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//build/util/version.gni") import("//testing/test.gni") @@ -103,6 +104,7 @@ source_set("unit_tests") { ":test_support", "//base", "//base/test:test_support", + "//build:chromeos_buildflags", "//components/paint_preview/common:test_utils", "//content/public/browser", "//content/test:test_support", @@ -112,6 +114,10 @@ source_set("unit_tests") { "//url", ] + if (is_chromeos_lacros) { + deps += [ "//chromeos/lacros:test_support" ] + } + defines = [ "CHROME_VERSION_MAJOR=" + chrome_version_major, "CHROME_VERSION_MINOR=" + chrome_version_minor, diff --git a/components/paint_preview/browser/DEPS b/components/paint_preview/browser/DEPS index fea23bd726784e..e6e5c8e734191b 100644 --- a/components/paint_preview/browser/DEPS +++ b/components/paint_preview/browser/DEPS @@ -1,5 +1,6 @@ include_rules = [ "+cc/base", + "+chromeos/lacros", "+components/discardable_memory/service", "+components/keyed_service/core", "+components/services/paint_preview_compositor/public/mojom", diff --git a/components/paint_preview/browser/paint_preview_base_service_unittest.cc b/components/paint_preview/browser/paint_preview_base_service_unittest.cc index dcbde0b22ed4f6..79f06b56dc43b9 100644 --- a/components/paint_preview/browser/paint_preview_base_service_unittest.cc +++ b/components/paint_preview/browser/paint_preview_base_service_unittest.cc @@ -13,6 +13,7 @@ #include "base/strings/strcat.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "components/paint_preview/browser/paint_preview_base_service_test_factory.h" #include "components/paint_preview/browser/paint_preview_file_mixin.h" #include "components/paint_preview/common/mojom/paint_preview_recorder.mojom.h" @@ -26,6 +27,10 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chromeos/lacros/lacros_test_helper.h" +#endif + namespace paint_preview { namespace { @@ -192,6 +197,10 @@ class PaintPreviewBaseServiceTest } private: +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // Instantiate LacrosService for WakeLock support during capturing. + chromeos::ScopedLacrosServiceTestHelper scoped_lacros_service_test_helper_; +#endif std::unique_ptr<SimpleFactoryKey> key_; std::unique_ptr<SimpleFactoryKey> rejection_policy_key_; }; diff --git a/services/device/public/mojom/wake_lock.mojom b/services/device/public/mojom/wake_lock.mojom index 18e1377f57269a..57b8eb13227594 100644 --- a/services/device/public/mojom/wake_lock.mojom +++ b/services/device/public/mojom/wake_lock.mojom @@ -4,6 +4,7 @@ module device.mojom; +[Stable, Extensible] enum WakeLockType { // Prevent the application from being suspended. On some platforms, apps may // be suspended when they are not visible to the user. This type of block @@ -24,6 +25,7 @@ enum WakeLockType { kPreventDisplaySleepAllowDimming = 2, }; +[Stable, Extensible] enum WakeLockReason { // Audio is being played. kAudioPlayback = 0, diff --git a/services/device/wake_lock/power_save_blocker/BUILD.gn b/services/device/wake_lock/power_save_blocker/BUILD.gn index 8ca1d4da121f8c..5bc4ea649e9733 100644 --- a/services/device/wake_lock/power_save_blocker/BUILD.gn +++ b/services/device/wake_lock/power_save_blocker/BUILD.gn @@ -12,6 +12,9 @@ if (is_android) { source_set("power_save_blocker") { visibility = [ + # Crosapi power API needs to directly use the Ash PowerBlocker . + "//chrome/browser/ash/crosapi", + # //remoting runs in a separate process which is outside of the context of # the ServiceManager-based world. Instead of embedding a Service Manager # environment and Device Service in it, we allow the power save blocker to @@ -36,13 +39,21 @@ source_set("power_save_blocker") { deps += [ ":jni_headers" ] public_deps += [ "//ui/android" ] } else if (is_chromeos_ash) { - sources += [ "power_save_blocker_chromeos.cc" ] + sources += [ "power_save_blocker_ash.cc" ] deps += [ "//chromeos/dbus/power", "//chromeos/dbus/power:power_manager_proto", ] } else if ((is_linux || is_chromeos) && use_dbus) { - sources += [ "power_save_blocker_linux.cc" ] + if (is_chromeos_lacros) { + sources += [ "power_save_blocker_lacros.cc" ] + deps += [ + "//chromeos/crosapi/mojom", + "//chromeos/lacros", + ] + } else { + sources += [ "power_save_blocker_linux.cc" ] + } deps += [ "//dbus", "//ui/gfx", diff --git a/services/device/wake_lock/power_save_blocker/power_save_blocker_chromeos.cc b/services/device/wake_lock/power_save_blocker/power_save_blocker_ash.cc similarity index 97% rename from services/device/wake_lock/power_save_blocker/power_save_blocker_chromeos.cc rename to services/device/wake_lock/power_save_blocker/power_save_blocker_ash.cc index 6be8cab21ef05f..f5c867badece0a 100644 --- a/services/device/wake_lock/power_save_blocker/power_save_blocker_chromeos.cc +++ b/services/device/wake_lock/power_save_blocker/power_save_blocker_ash.cc @@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/check.h" #include "base/location.h" -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/notreached.h" #include "base/sequenced_task_runner.h" @@ -49,6 +48,9 @@ class PowerSaveBlocker::Delegate block_id_(0), ui_task_runner_(ui_task_runner) {} + Delegate(const Delegate&) = delete; + const Delegate& operator=(const Delegate&) = delete; + void ApplyBlock() { DCHECK(ui_task_runner_->RunsTasksInCurrentSequence()); if (!chromeos::PowerPolicyController::IsInitialized()) @@ -93,8 +95,6 @@ class PowerSaveBlocker::Delegate int block_id_; scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; - - DISALLOW_COPY_AND_ASSIGN(Delegate); }; PowerSaveBlocker::PowerSaveBlocker( diff --git a/services/device/wake_lock/power_save_blocker/power_save_blocker_lacros.cc b/services/device/wake_lock/power_save_blocker/power_save_blocker_lacros.cc new file mode 100644 index 00000000000000..99cf56c7a993a9 --- /dev/null +++ b/services/device/wake_lock/power_save_blocker/power_save_blocker_lacros.cc @@ -0,0 +1,89 @@ +// Copyright 2021 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 "services/device/wake_lock/power_save_blocker/power_save_blocker.h" + +#include <string> + +#include "base/memory/ref_counted.h" +#include "chromeos/crosapi/mojom/power.mojom.h" +#include "chromeos/lacros/lacros_service.h" +#include "mojo/public/cpp/bindings/receiver.h" + +namespace device { + +/******** PowerSaveBlocker::Delegate ********/ + +// Lacros-chrome PowerSaveBlocker uses ash-chrome ProwerSaveBlocker via crosapi. +// RAII style is maintained by keeping a crosapi::mojom::PowerWakeLock Mojo +// connection, whose disconnection triggers resource release in ash-chrome. + +class PowerSaveBlocker::Delegate + : public base::RefCountedThreadSafe<PowerSaveBlocker::Delegate> { + public: + Delegate(mojom::WakeLockType type, + mojom::WakeLockReason reason, + const std::string& description, + scoped_refptr<base::SequencedTaskRunner> ui_task_runner) + : type_(type), + reason_(reason), + description_(description), + ui_task_runner_(ui_task_runner) {} + Delegate(const Delegate&) = delete; + Delegate& operator=(const Delegate&) = delete; + + void ApplyBlock() { + DCHECK(ui_task_runner_->RunsTasksInCurrentSequence()); + auto* lacros_service = chromeos::LacrosService::Get(); + if (lacros_service->IsAvailable<crosapi::mojom::Power>()) { + lacros_service->GetRemote<crosapi::mojom::Power>()->AddPowerSaveBlocker( + receiver_.BindNewPipeAndPassRemote(), type_, reason_, description_); + } + } + + void RemoveBlock() { + DCHECK(ui_task_runner_->RunsTasksInCurrentSequence()); + // Disconnect to make ash-chrome release its PowerSaveBlocker. + receiver_.reset(); + } + + private: + friend class base::RefCountedThreadSafe<Delegate>; + virtual ~Delegate() {} + + // Connection to ash-chrome via crosapi. Disconnection from RemoveBlock() or + // Lacros termination triggers resource release in ash-chrome. + crosapi::mojom::PowerWakeLock lock_; + mojo::Receiver<crosapi::mojom::PowerWakeLock> receiver_{&lock_}; + + mojom::WakeLockType type_; + mojom::WakeLockReason reason_; + std::string description_; + scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; +}; + +/******** PowerSaveBlocker ********/ + +PowerSaveBlocker::PowerSaveBlocker( + mojom::WakeLockType type, + mojom::WakeLockReason reason, + const std::string& description, + scoped_refptr<base::SequencedTaskRunner> ui_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner) + : delegate_(base::MakeRefCounted<Delegate>(type, + reason, + description, + ui_task_runner)), + ui_task_runner_(ui_task_runner), + blocking_task_runner_(blocking_task_runner) { + ui_task_runner_->PostTask(FROM_HERE, + base::BindOnce(&Delegate::ApplyBlock, delegate_)); +} + +PowerSaveBlocker::~PowerSaveBlocker() { + ui_task_runner_->PostTask(FROM_HERE, + base::BindOnce(&Delegate::RemoveBlock, delegate_)); +} + +} // namespace device From dcad83b34948bc757f0454098887dcd0ff59e447 Mon Sep 17 00:00:00 2001 From: Alice Wang <aliceywang@chromium.org> Date: Tue, 1 Jun 2021 13:46:38 +0000 Subject: [PATCH 67/81] [Android] Migrate tryGetGoogleAccounts() usage in AccountManagementFragment This CL migrates the usage of the blocking method tryGetGoogleAccounts() to a non-blocking version in AccountManagementFragment. Bug: 1211294 Change-Id: I291cbf17de388754fb982b2b2b5684393bf575e3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2919991 Reviewed-by: Victor Vianna <victorvianna@google.com> Commit-Queue: Alice Wang <aliceywang@chromium.org> Cr-Commit-Position: refs/heads/master@{#887944} --- .../browser/sync/settings/AccountManagementFragment.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java index f02beac0649a15..28c73ee1c60247 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java @@ -175,7 +175,7 @@ public void update() { configureSignOutSwitch(); configureChildAccountPreferences(); - updateAccountsList(); + AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts(this::updateAccountsList); } private boolean canAddAccounts() { @@ -271,7 +271,7 @@ private void configureChildAccountPreferences() { } } - private void updateAccountsList() { + private void updateAccountsList(List<Account> accounts) { PreferenceCategory accountsCategory = (PreferenceCategory) findPreference(PREF_ACCOUNTS_CATEGORY); if (accountsCategory == null) return; @@ -285,7 +285,6 @@ private void updateAccountsList() { accountsCategory.addPreference(createManageYourGoogleAccountPreference()); accountsCategory.addPreference(createDividerPreference(R.layout.divider_preference)); - List<Account> accounts = AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts(); for (Account account : accounts) { if (!mSignedInAccountName.equals(account.name)) { accountsCategory.addPreference(createAccountPreference(account)); @@ -372,7 +371,7 @@ private Context getStyledContext() { // ProfileDataCache.Observer implementation: @Override public void onProfileDataUpdated(String accountEmail) { - updateAccountsList(); + AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts(this::updateAccountsList); } // SignOutDialogListener implementation: From 3afc4cc3c1292d30b2b584b8a43d9c9e26a80c87 Mon Sep 17 00:00:00 2001 From: Takuto Ikuta <tikuta@chromium.org> Date: Tue, 1 Jun 2021 13:56:05 +0000 Subject: [PATCH 68/81] mb: remove code for old client Bug: 984869 Change-Id: I3ad4d440e34cd10f7b88b248819da0daa733c827 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928688 Auto-Submit: Takuto Ikuta <tikuta@chromium.org> Reviewed-by: Yoshisato Yanagisawa <yyanagisawa@google.com> Commit-Queue: Takuto Ikuta <tikuta@chromium.org> Cr-Commit-Position: refs/heads/master@{#887945} --- tools/mb/mb.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tools/mb/mb.py b/tools/mb/mb.py index e5bd2a3bf76151..f210d90925b79e 100755 --- a/tools/mb/mb.py +++ b/tools/mb/mb.py @@ -686,19 +686,11 @@ def _RunUnderSwarming(self, build_dir, target, isolate_cmd): # We trap the command explicitly and rewrite the error output so that # the error message is actually correct for a Chromium check out. self.PrintCmd(cmd) - ret, out, err = self.Run(cmd, force_verbose=False) + ret, out, _ = self.Run(cmd, force_verbose=False) if ret: self.Print(' -> returned %d' % ret) if out: self.Print(out, end='') - if err: - # The swarming client will return an exit code of 2 (via - # argparse.ArgumentParser.error()) and print a message to indicate - # that auth failed, so we have to parse the message to check. - if (ret == 2 and 'Please login to' in err): - err = err.replace(' auth.py', ' tools/swarming_client/auth.py') - self.Print(err, end='', file=sys.stderr) - return ret try: From 05d95e1e321f2477aba73dab9b0f9fa7ec2acb7d Mon Sep 17 00:00:00 2001 From: Alexander Hendrich <hendrich@chromium.org> Date: Tue, 1 Jun 2021 13:57:46 +0000 Subject: [PATCH 69/81] Remove CrosSettings from policy pref mapping test This turns out to be more difficult than expected. The policy pref mapping browser test constructs a PolicyMap and applies that to verify certain prefs are set. However, CrosSettings from policy are not constructed from a PolicyMap, but from the actual device policy proto using device_settings_provider.cc [1]. Therefore, the given browser test is not really suitable to test CrosSettings mappings because 1) test can not construct & apply a device policy proto from just the policy name given in the json 2) test method is in //components/policy and is not aware of concepts like CrosSettings from //chrome/browser/ash Therefore, we should strive to improve test coverage of device_settings_provider_unittest.cc [2] and remove the CrosSettings part from the policy pref mapping test. Bug: 1151251, 809991 Change-Id: If3feb7f7c4ad30e49bf32dbcf55ccd83c7c269af Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2919849 Commit-Queue: Alexander Hendrich <hendrich@chromium.org> Reviewed-by: Pavol Marko <pmarko@chromium.org> Cr-Commit-Position: refs/heads/master@{#887946} --- .../test/data/policy/policy_test_cases.json | 489 ++---------------- .../core/browser/policy_pref_mapping_test.cc | 6 - 2 files changed, 34 insertions(+), 461 deletions(-) diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 122e504ef78c7d..45c24d54cb8c9d 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json @@ -33,7 +33,7 @@ "${pref}": { "value": "The value that |pref| should take on.", "expect_default": "Whether or not the pref value should be the default one (i.e. unmanaged and user-modifiable). Defaults to false if not specified.", - "location": "The location where the pref is registered, possible values are ['user_profile', 'signin_profile', 'local_state', 'cros_setting']. Defaults to 'user_profile' if not specified.", + "location": "The location where the pref is registered, possible values are ['user_profile', 'signin_profile', 'local_state']. Defaults to 'user_profile' if not specified.", "check_for_mandatory": "Should the preference be tested when a mandatory value is set for the policy? Defaults to |true| if not specified. See |can_be_recommended|.", "check_for_recommended": "Should the preference be tested when a recommended value is set for the policy? Defaults to |true| if not specified. See |can_be_recommended|." } @@ -5576,19 +5576,7 @@ "DevicePciPeripheralDataAccessEnabled": {}, "DeviceMetricsReportingEnabled": { - "os": ["chromeos"], - "official_only": true, - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceMetricsReportingEnabled": true - }, - "prefs": { "cros.metrics.reportingEnabled": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceEphemeralUsersEnabled": {}, @@ -5730,20 +5718,7 @@ "ExtensionCacheSize": {}, "DeviceShowLowDiskSpaceNotification": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "ShowLowDiskSpaceNotification": false - }, - "prefs": { - "cros.device.show_low_disk_space_notification": { - "value": false, - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceLoginScreenDomainAutoComplete": {}, @@ -5751,19 +5726,7 @@ "AllowKioskAppControlChromeVersion": {}, "LoginAuthenticationBehavior": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "LoginAuthenticationBehavior": 1 - }, - "prefs": { - "cros.device.login_authentication_behavior": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "UsbDetachableWhitelist": {}, @@ -5773,51 +5736,15 @@ "DeviceAllowBluetooth": {}, "DeviceWiFiAllowed": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceWiFiAllowed": false - }, - "prefs": { - "cros.device.device_wifi_allowed": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceQuirksDownloadEnabled": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceQuirksDownloadEnabled": true - }, - "prefs": { - "cros.device.quirks_download_enabled": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "SystemTimezoneAutomaticDetection": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "SystemTimezoneAutomaticDetection": 1 - }, - "prefs": { - "cros.device.system_timezone_automatic_detection": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "WebRestrictionsAuthority": {}, @@ -5863,21 +5790,7 @@ }, "LoginVideoCaptureAllowedUrls": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "LoginVideoCaptureAllowedUrls": [ - "https://example.com" - ] - }, - "prefs": { - "cros.device.login_video_capture_allowed_urls": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceLoginScreenExtensions": { @@ -5908,22 +5821,7 @@ }, "DeviceWallpaperImage": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceWallpaperImage": { - "url": "http://localhost/", - "hash": "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" - } - }, - "prefs": { - "cros.device_wallpaper_image": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "BrowserNetworkTimeQueriesEnabled": { @@ -5986,19 +5884,7 @@ }, "CastReceiverName": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "CastReceiverName": "Hallway" - }, - "prefs": { - "cros.device.cast_receiver.name": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceNativePrinters": { @@ -6016,51 +5902,15 @@ }, "DeviceNativePrintersAccessMode": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceNativePrintersAccessMode": 1 - }, - "prefs": { - "cros.device.native_printers_access_mode": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceNativePrintersBlacklist": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceNativePrintersBlacklist": ["id4", "id7", "id10"] - }, - "prefs": { - "cros.device.native_printers_blacklist": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceNativePrintersWhitelist": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceNativePrintersWhitelist": ["id4", "id7", "id10"] - }, - "prefs": { - "cros.device.native_printers_whitelist": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceExternalPrintServers": { @@ -6107,68 +5957,19 @@ }, "DevicePrintersAccessMode": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DevicePrintersAccessMode": 1 - }, - "prefs": { - "cros.device.native_printers_access_mode": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DevicePrintersBlocklist": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DevicePrintersBlocklist": ["id4", "id7", "id10"] - }, - "prefs": { - "cros.device.native_printers_blacklist": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DevicePrintersAllowlist": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DevicePrintersAllowlist": ["id4", "id7", "id10"] - }, - "prefs": { - "cros.device.native_printers_whitelist": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "TPMFirmwareUpdateSettings": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "allow-user-initiated-powerwash": true, - "auto-update-mode": 2 - }, - "prefs": { - "cros.tpm_firmware_update_settings": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "MinimumRequiredChromeVersion": { @@ -6176,81 +5977,21 @@ }, "DeviceMinimumVersion": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceMinimumVersion": { - "requirements": [ - {"chromeos_version" : "13121.0.0", "warning_period" : 0, "aue_warning_period" : 14} - ], - "unmanaged_user_restricted": true - } - }, - "prefs": { - "cros.device.min_version": { - "value": { - "requirements": [ - {"chromeos_version" : "13121.0.0", "warning_period" : 0, "aue_warning_period" : 14} - ], - "unmanaged_user_restricted": true - }, - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceMinimumVersionAueMessage": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceMinimumVersionAueMessage": "Please return your device." - }, - "prefs": { - "cros.device.min_version_aue_message": { - "value": "Please return this device.", - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceLoginScreenAutoSelectCertificateForUrls": {}, "UnaffiliatedArcAllowed": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "unaffiliated_arc_allowed": false - }, - "prefs": { - "cros.unaffiliated_arc_allowed": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceHostnameTemplate": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceHostnameTemplate": "chromebook-${ASSET_ID}" - }, - "prefs": { - "cros.network.hostname_template": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "ContextAwareAccessSignalsAllowlist": { @@ -6379,19 +6120,7 @@ }, "VirtualMachinesAllowed": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "virtual_machines_allowed": true - }, - "prefs": { - "cros.device.virtual_machines_allowed": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "CrostiniAllowed": { @@ -6407,19 +6136,7 @@ }, "DeviceUnaffiliatedCrostiniAllowed": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "device_unaffiliated_crostini_allowed": false - }, - "prefs": { - "cros.device.unaffiliated_crostini_allowed": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "CrostiniExportImportUIAllowed": { @@ -6828,35 +6545,11 @@ }, "PluginVmAllowed": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "PluginVmAllowed": true - }, - "prefs": { - "cros.device.plugin_vm_allowed": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "PluginVmLicenseKey": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "PluginVmLicenseKey": "LICENSE_KEY" - }, - "prefs": { - "cros.device.plugin_vm_license_key": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "ParentAccessCodeConfig": { @@ -6946,19 +6639,7 @@ }, "DeviceRebootOnUserSignout": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceRebootOnUserSignout": 0 - }, - "prefs": { - "cros.device.reboot_on_user_signout": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "ForceNetworkInProcess": { @@ -6966,19 +6647,7 @@ }, "DeviceWilcoDtcAllowed": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceWilcoDtcAllowed": true - }, - "prefs": { - "cros.device.wilco_dtc_allowed": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceWilcoDtcConfiguration": { @@ -7077,19 +6746,7 @@ }, "DeviceDockMacAddressSource": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceDockMacAddressSource": 2 - }, - "prefs": { - "cros.device.device_dock_mac_address_source": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceAdvancedBatteryChargeModeEnabled": { @@ -7190,37 +6847,11 @@ }, "DevicePowerwashAllowed": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DevicePowerwashAllowed": true - }, - "prefs": { - "cros.device.device_powerwash_allowed": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceWebBasedAttestationAllowedUrls": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceWebBasedAttestationAllowedUrls": [ - "[*.]example.com" - ] - }, - "prefs": { - "cros.device.web_based_attestation_allowed_urls": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "EmojiSuggestionEnabled": { @@ -7470,36 +7101,11 @@ }, "DeviceBorealisAllowed": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceBorealisAllowed": false - }, - "prefs": { - "cros.device.borealis_allowed": { - "value": false, - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceAllowedBluetoothServices": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "DeviceAllowedBluetoothServices": ["1124","180A","180F","1812"] - }, - "prefs": { - "cros.device.allowed_bluetooth_services": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "DeviceDebugPacketCaptureAllowed": {}, @@ -8150,24 +7756,7 @@ ] }, "SystemProxySettings": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { - "SystemProxySettings": { - "system_proxy_enabled": "true", - "system_services_username": "test_user", - "system_services_password": "0000", - "policy_credentials_auth_schemes": ["basic","digest"] - } - }, - "prefs": { - "cros.system_proxy_settings": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "NativeWindowOcclusionEnabled": { "os": ["win"], @@ -8282,17 +7871,7 @@ ] }, "DeviceChannelDowngradeBehavior": { - "os": ["chromeos"], - "policy_pref_mapping_tests": [ - { - "policies": { "DeviceChannelDowngradeBehavior": 0 }, - "prefs": { - "cros.system.channelDowngradeBehavior": { - "location": "cros_setting" - } - } - } - ] + "reason_for_missing_test": "Maps into CrosSettings" }, "BackForwardCacheEnabled": { "os": ["android"], diff --git a/components/policy/core/browser/policy_pref_mapping_test.cc b/components/policy/core/browser/policy_pref_mapping_test.cc index 9d7ee81593c153..c86efe1f792be2 100644 --- a/components/policy/core/browser/policy_pref_mapping_test.cc +++ b/components/policy/core/browser/policy_pref_mapping_test.cc @@ -41,7 +41,6 @@ enum class PrefLocation { kUserProfile, kSigninProfile, kLocalState, - kCrosSetting, }; PrefLocation GetPrefLocation(const base::Value& settings) { @@ -52,8 +51,6 @@ PrefLocation GetPrefLocation(const base::Value& settings) { return PrefLocation::kLocalState; if (*location == "signin_profile") return PrefLocation::kSigninProfile; - if (*location == "cros_setting") - return PrefLocation::kCrosSetting; NOTREACHED() << "Unknown pref location: " << *location; return PrefLocation::kUserProfile; } @@ -534,9 +531,6 @@ void VerifyPolicyToPrefMappings(const base::FilePath& test_case_path, case PrefLocation::kLocalState: prefs = local_state; break; - case PrefLocation::kCrosSetting: - // TODO(https://crbug.com/809991) Verify CrosSettings mappings - continue; default: NOTREACHED() << "Unhandled pref location: " << static_cast<int>(pref_case->location()); From a89e197bac4ce24e586b92ee4d6a58846ff8b387 Mon Sep 17 00:00:00 2001 From: sandromaggi <sandromaggi@google.com> Date: Tue, 1 Jun 2021 13:58:17 +0000 Subject: [PATCH 70/81] [Autofill Assistant] CUD validity for Shipping Address This implements CollectUserData validity for shipping addresses based on the new rules being sent from backend. It keeps the "editor" validation in place. The reasoning is, that we still want that minimum validity, in case the user opens the address for editing. This also changes the way Java gets errors by sending them from the UI controller instead of Java asking for them. Bug: b/180705720 Change-Id: Ib20403158a6c965b8265a647f1fdb6ddd2b7c9a2 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2919809 Reviewed-by: Luca Hunkeler <hluca@google.com> Commit-Queue: Sandro Maggi <sandromaggi@google.com> Cr-Commit-Position: refs/heads/master@{#887947} --- .../autofill_assistant_address_full.xml | 3 - .../autofill_assistant_contact_full.xml | 1 - .../AssistantCollectUserDataBinder.java | 13 +- .../AssistantCollectUserDataDelegate.java | 6 - .../AssistantCollectUserDataModel.java | 45 ++++-- ...ssistantCollectUserDataNativeDelegate.java | 15 -- .../AssistantShippingAddressSection.java | 70 +++++---- ...illAssistantCollectUserDataTestHelper.java | 5 - ...utofillAssistantCollectUserDataUiTest.java | 8 +- ...ofillAssistantPersonalDataManagerTest.java | 41 ++++- .../assistant_collect_user_data_delegate.cc | 15 -- .../assistant_collect_user_data_delegate.h | 5 - .../ui_controller_android.cc | 68 +++++---- .../ui_controller_android.h | 1 - .../actions/collect_user_data_action.cc | 29 ++-- .../collect_user_data_action_unittest.cc | 17 ++- .../autofill_assistant/browser/service.proto | 4 +- .../autofill_assistant/browser/user_data.h | 1 + .../browser/user_data_util.cc | 144 +++++++++++------- .../browser/user_data_util.h | 20 +-- .../browser/user_data_util_unittest.cc | 101 ++++++++++-- components/autofill_assistant_strings.grdp | 3 + ...STANT_PAYMENT_INFORMATION_MISSING.png.sha1 | 1 + 23 files changed, 388 insertions(+), 228 deletions(-) create mode 100644 components/autofill_assistant_strings_grdp/IDS_AUTOFILL_ASSISTANT_PAYMENT_INFORMATION_MISSING.png.sha1 diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_address_full.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_address_full.xml index 7a0febd51143aa..21fed249f85585 100644 --- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_address_full.xml +++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_address_full.xml @@ -24,9 +24,6 @@ android:id="@+id/incomplete_error" android:layout_width="match_parent" android:layout_height="wrap_content" - android:ellipsize="end" - android:maxLines="1" - android:text="@string/autofill_assistant_payment_information_missing" android:textAppearance="@style/TextAppearance.ErrorCaption" android:visibility="gone"/> </LinearLayout> \ No newline at end of file diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_contact_full.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_contact_full.xml index 18973b4c76a919..910f7231b63499 100644 --- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_contact_full.xml +++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_contact_full.xml @@ -18,7 +18,6 @@ android:id="@+id/incomplete_error" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/autofill_assistant_payment_information_missing" android:textAppearance="@style/TextAppearance.ErrorCaption" android:visibility="gone"/> </LinearLayout> \ No newline at end of file diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataBinder.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataBinder.java index 4dc22f94ecd845..d22b7fcf4a3dba 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataBinder.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataBinder.java @@ -15,10 +15,10 @@ import org.chromium.chrome.browser.autofill.settings.AddressEditor; import org.chromium.chrome.browser.autofill.settings.CardEditor; import org.chromium.chrome.browser.autofill_assistant.generic_ui.AssistantValue; +import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantCollectUserDataModel.AddressModel; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantCollectUserDataModel.ContactModel; import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantAdditionalSection.Delegate; import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantAdditionalSectionContainer; -import org.chromium.chrome.browser.payments.AutofillAddress; import org.chromium.chrome.browser.payments.AutofillPaymentInstrument; import org.chromium.chrome.browser.payments.ContactEditor; import org.chromium.chrome.browser.profiles.Profile; @@ -180,12 +180,9 @@ public void onTimeSlotChanged(@Nullable Integer index) { view.mPaymentMethodSection.setCompletenessDelegate(collectUserDataDelegate != null ? collectUserDataDelegate::isPaymentInstrumentComplete : null); - view.mShippingAddressSection.setListener(collectUserDataDelegate != null - ? collectUserDataDelegate::onShippingAddressChanged - : null); - view.mShippingAddressSection.setCompletenessDelegate(collectUserDataDelegate != null - ? collectUserDataDelegate::isShippingAddressComplete - : null); + view.mShippingAddressSection.setListener(collectUserDataDelegate == null + ? null + : m -> collectUserDataDelegate.onShippingAddressChanged(m.mOption)); view.mLoginSection.setListener(collectUserDataDelegate != null ? collectUserDataDelegate::onLoginChoiceChanged : null); @@ -478,7 +475,7 @@ private boolean updateSectionSelectedItem( // This prevents creating a loop. if (propertyKey == AssistantCollectUserDataModel.SELECTED_SHIPPING_ADDRESS) { if (model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS)) { - AutofillAddress shippingAddress = + AddressModel shippingAddress = model.get(AssistantCollectUserDataModel.SELECTED_SHIPPING_ADDRESS); if (shippingAddress != null) { view.mShippingAddressSection.addOrUpdateItem( diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataDelegate.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataDelegate.java index 97b6741cbbe4ab..ea8f37c3fd8d0e 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataDelegate.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataDelegate.java @@ -54,12 +54,6 @@ public interface AssistantCollectUserDataDelegate { /** The focus on an input text field has changed */ void onInputTextFocusChanged(boolean isFocused); - /** - * Returns true if the shipping address is complete. - * TODO(b/154068342): Remove this method and send the error message from |Controller|. - */ - boolean isShippingAddressComplete(@Nullable AutofillAddress address); - /** * Returns true if the payment instrument is complete. * TODO(b/154068342): Remove this method and send the error message from |Controller|. diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java index c6b8069b0910bf..cf2b693e96b4d8 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java @@ -90,6 +90,17 @@ public ContactModel(AutofillContact contact) { } } + /** Model wrapper for an {@code AutofillAddress}. */ + public static class AddressModel extends OptionModel<AutofillAddress> { + public AddressModel(AutofillAddress address, List<String> errors) { + super(address, errors); + } + + public AddressModel(AutofillAddress address) { + super(address); + } + } + public static final WritableObjectPropertyKey<AssistantCollectUserDataDelegate> DELEGATE = new WritableObjectPropertyKey<>(); @@ -100,7 +111,7 @@ public ContactModel(AutofillContact contact) { public static final WritableBooleanPropertyKey VISIBLE = new WritableBooleanPropertyKey(); /** The chosen shipping address. */ - public static final WritableObjectPropertyKey<AutofillAddress> SELECTED_SHIPPING_ADDRESS = + public static final WritableObjectPropertyKey<AddressModel> SELECTED_SHIPPING_ADDRESS = new WritableObjectPropertyKey<>(); /** The chosen payment method (including billing address). */ @@ -150,8 +161,8 @@ public ContactModel(AutofillContact contact) { public static final WritableObjectPropertyKey<List<ContactModel>> AVAILABLE_CONTACTS = new WritableObjectPropertyKey<>(); - public static final WritableObjectPropertyKey<List<AutofillAddress>> - AVAILABLE_SHIPPING_ADDRESSES = new WritableObjectPropertyKey<>(); + public static final WritableObjectPropertyKey<List<AddressModel>> AVAILABLE_SHIPPING_ADDRESSES = + new WritableObjectPropertyKey<>(); public static final WritableObjectPropertyKey<List<AutofillPaymentInstrument>> AVAILABLE_PAYMENT_INSTRUMENTS = new WritableObjectPropertyKey<>(); @@ -388,8 +399,11 @@ private void setSelectedContactDetails(@Nullable AutofillContact contact, String } @CalledByNative - private void setSelectedShippingAddress(@Nullable AutofillAddress shippingAddress) { - set(SELECTED_SHIPPING_ADDRESS, shippingAddress); + private void setSelectedShippingAddress( + @Nullable AutofillAddress shippingAddress, String[] errors) { + set(SELECTED_SHIPPING_ADDRESS, + shippingAddress == null ? null + : new AddressModel(shippingAddress, Arrays.asList(errors))); } @CalledByNative @@ -621,14 +635,14 @@ private void setAvailableContacts(List<ContactModel> contacts) { } @CalledByNative - private static List<AutofillAddress> createAutofillAddressList() { + private static List<AddressModel> createShippingAddressList() { return new ArrayList<>(); } @CalledByNative - private static void addAutofillAddress( - List<AutofillAddress> addresses, AutofillAddress address) { - addresses.add(address); + private static void addShippingAddress( + List<AddressModel> addresses, AutofillAddress address, String[] errors) { + addresses.add(new AddressModel(address, Arrays.asList(errors))); } @VisibleForTesting @@ -643,10 +657,21 @@ public static AutofillAddress createAutofillAddress( } @CalledByNative - private void setAvailableShippingAddresses(List<AutofillAddress> addresses) { + private void setAvailableShippingAddresses(List<AddressModel> addresses) { set(AVAILABLE_SHIPPING_ADDRESSES, addresses); } + @CalledByNative + private static List<AutofillAddress> createBillingAddressList() { + return new ArrayList<>(); + } + + @CalledByNative + private static void addBillingAddress( + List<AutofillAddress> addresses, AutofillAddress address) { + addresses.add(address); + } + @CalledByNative private void setAvailableBillingAddresses(List<AutofillAddress> addresses) { set(AVAILABLE_BILLING_ADDRESSES, addresses); diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataNativeDelegate.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataNativeDelegate.java index 082c92bc851f9b..9495afc7ff5242 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataNativeDelegate.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataNativeDelegate.java @@ -169,18 +169,6 @@ public void onInputTextFocusChanged(boolean isFocused) { } } - @Override - public boolean isShippingAddressComplete(@Nullable AutofillAddress address) { - if (mNativeAssistantCollectUserDataDelegate != 0) { - return AssistantCollectUserDataNativeDelegateJni.get().isShippingAddressComplete( - mNativeAssistantCollectUserDataDelegate, - AssistantCollectUserDataNativeDelegate.this, - address != null ? address.getProfile() : null); - } - - return false; - } - @Override public boolean isPaymentInstrumentComplete( @Nullable AutofillPaymentInstrument paymentInstrument) { @@ -238,9 +226,6 @@ void onKeyValueChanged(long nativeAssistantCollectUserDataDelegate, AssistantCollectUserDataNativeDelegate caller, String key, AssistantValue value); void onInputTextFocusChanged(long nativeAssistantCollectUserDataDelegate, AssistantCollectUserDataNativeDelegate caller, boolean isFocused); - boolean isShippingAddressComplete(long nativeAssistantCollectUserDataDelegate, - AssistantCollectUserDataNativeDelegate caller, - @Nullable PersonalDataManager.AutofillProfile address); boolean isPaymentInstrumentComplete(long nativeAssistantCollectUserDataDelegate, AssistantCollectUserDataNativeDelegate caller, @Nullable PersonalDataManager.CreditCard card, diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantShippingAddressSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantShippingAddressSection.java index 199d565995524a..c1e51c928823a2 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantShippingAddressSection.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantShippingAddressSection.java @@ -16,15 +16,15 @@ import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.autofill.PersonalDataManager; import org.chromium.chrome.browser.autofill.settings.AddressEditor; +import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantCollectUserDataModel.AddressModel; import org.chromium.chrome.browser.payments.AutofillAddress; import java.util.List; /** - * The payment method section of the Autofill Assistant payment request. + * The shipping address section of the Autofill Assistant payment request. */ -public class AssistantShippingAddressSection - extends AssistantCollectUserDataSection<AutofillAddress> { +public class AssistantShippingAddressSection extends AssistantCollectUserDataSection<AddressModel> { private AddressEditor mEditor; private boolean mIgnoreProfileChangeNotifications; @@ -42,76 +42,84 @@ public void setEditor(AddressEditor editor) { } @Override - protected void createOrEditItem(@Nullable AutofillAddress oldItem) { + protected void createOrEditItem(@Nullable AddressModel oldItem) { if (mEditor == null) { return; } - mEditor.edit(oldItem, newItem -> { - assert (newItem != null && newItem.isComplete()); + mEditor.edit(oldItem == null ? null : oldItem.mOption, address -> { + assert (address != null && address.isComplete()); mIgnoreProfileChangeNotifications = true; - addOrUpdateItem(newItem, /* select= */ true, /* notify= */ true); + addOrUpdateItem(new AddressModel(address), /* select= */ true, /* notify= */ true); mIgnoreProfileChangeNotifications = false; }, cancel -> {}); } @Override - protected void updateFullView(View fullView, AutofillAddress address) { - if (address == null) { + protected void updateFullView(View fullView, @Nullable AddressModel model) { + if (model == null) { return; } TextView fullNameView = fullView.findViewById(R.id.full_name); - fullNameView.setText(address.getProfile().getFullName()); + fullNameView.setText(model.mOption.getProfile().getFullName()); hideIfEmpty(fullNameView); TextView fullAddressView = fullView.findViewById(R.id.full_address); - fullAddressView.setText( - PersonalDataManager.getInstance() - .getShippingAddressLabelWithCountryForPaymentRequest(address.getProfile())); + fullAddressView.setText(PersonalDataManager.getInstance() + .getShippingAddressLabelWithCountryForPaymentRequest( + model.mOption.getProfile())); hideIfEmpty(fullAddressView); - TextView methodIncompleteView = fullView.findViewById(R.id.incomplete_error); - methodIncompleteView.setVisibility(isComplete(address) ? View.GONE : View.VISIBLE); + TextView errorView = fullView.findViewById(R.id.incomplete_error); + if (model.mErrors.isEmpty()) { + errorView.setText(""); + errorView.setVisibility(View.GONE); + } else { + errorView.setText(TextUtils.join("\n", model.mErrors)); + errorView.setVisibility(View.VISIBLE); + } } @Override - protected void updateSummaryView(View summaryView, AutofillAddress address) { - if (address == null) { + protected void updateSummaryView(View summaryView, @Nullable AddressModel model) { + if (model == null) { return; } TextView fullNameView = summaryView.findViewById(R.id.full_name); - fullNameView.setText(address.getProfile().getFullName()); + fullNameView.setText(model.mOption.getProfile().getFullName()); hideIfEmpty(fullNameView); TextView shortAddressView = summaryView.findViewById(R.id.short_address); shortAddressView.setText(PersonalDataManager.getInstance() .getShippingAddressLabelWithoutCountryForPaymentRequest( - address.getProfile())); + model.mOption.getProfile())); hideIfEmpty(shortAddressView); - TextView methodIncompleteView = summaryView.findViewById(R.id.incomplete_error); - methodIncompleteView.setVisibility(isComplete(address) ? View.GONE : View.VISIBLE); + TextView errorView = summaryView.findViewById(R.id.incomplete_error); + errorView.setVisibility(model.mErrors.isEmpty() ? View.GONE : View.VISIBLE); } @Override - protected boolean canEditOption(AutofillAddress address) { + protected boolean canEditOption(AddressModel model) { return true; } @Override - protected @DrawableRes int getEditButtonDrawable(AutofillAddress address) { + protected @DrawableRes int getEditButtonDrawable(AddressModel model) { return R.drawable.ic_edit_24dp; } @Override - protected String getEditButtonContentDescription(AutofillAddress address) { + protected String getEditButtonContentDescription(AddressModel model) { return mContext.getString(R.string.payments_edit_address); } @Override - protected boolean areEqual(AutofillAddress optionA, AutofillAddress optionB) { - if (optionA == null || optionB == null) { - return optionA == optionB; + protected boolean areEqual(AddressModel modelA, AddressModel modelB) { + if (modelA == null || modelB == null) { + return modelA == modelB; } + AutofillAddress optionA = modelA.mOption; + AutofillAddress optionB = modelB.mOption; if (TextUtils.equals(optionA.getIdentifier(), optionB.getIdentifier())) { return true; } @@ -127,7 +135,7 @@ protected boolean areEqual(AutofillAddress optionA, AutofillAddress optionB) { * The Chrome profiles have changed externally. This will rebuild the UI with the new/changed * set of addresses derived from the profiles, while keeping the selected item if possible. */ - void onAddressesChanged(List<AutofillAddress> addresses) { + void onAddressesChanged(List<AddressModel> addresses) { if (mIgnoreProfileChangeNotifications) { return; } @@ -147,13 +155,13 @@ void onAddressesChanged(List<AutofillAddress> addresses) { } @Override - protected void addOrUpdateItem(AutofillAddress address, boolean select, boolean notify) { - super.addOrUpdateItem(address, select, notify); + protected void addOrUpdateItem(AddressModel model, boolean select, boolean notify) { + super.addOrUpdateItem(model, select, notify); // Update autocomplete information in the editor. if (mEditor == null) { return; } - mEditor.addPhoneNumberIfValid(address.getProfile().getPhoneNumber()); + mEditor.addPhoneNumberIfValid(model.mOption.getProfile().getPhoneNumber()); } } \ No newline at end of file diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java index f63b94786bed7b..a9eb47eac47189 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java @@ -179,11 +179,6 @@ public void onKeyValueChanged(String key, AssistantValue value) { @Override public void onInputTextFocusChanged(boolean isFocused) {} - @Override - public boolean isShippingAddressComplete(@Nullable AutofillAddress address) { - return address != null && address.isComplete(); - } - @Override public boolean isPaymentInstrumentComplete( @Nullable AutofillPaymentInstrument paymentInstrument) { diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java index 79ba7e76807dc5..7e192515a49371 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java @@ -59,6 +59,7 @@ import org.chromium.chrome.browser.autofill_assistant.generic_ui.AssistantValue; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantCollectUserDataCoordinator; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantCollectUserDataModel; +import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantCollectUserDataModel.AddressModel; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantCollectUserDataModel.ContactModel; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantContactField; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantDateChoiceOptions; @@ -661,8 +662,9 @@ public void testNonEmptyPaymentRequest() throws Exception { AutofillAddress address = AssistantCollectUserDataModel.createAutofillAddress( mTestRule.getActivity(), profile); model.set(AssistantCollectUserDataModel.AVAILABLE_SHIPPING_ADDRESSES, - Collections.singletonList(address)); - model.set(AssistantCollectUserDataModel.SELECTED_SHIPPING_ADDRESS, address); + Collections.singletonList(new AddressModel(address))); + model.set(AssistantCollectUserDataModel.SELECTED_SHIPPING_ADDRESS, + new AddressModel(address)); AutofillPaymentInstrument paymentInstrument = AssistantCollectUserDataModel.createAutofillPaymentInstrument( mTestRule.getWebContents(), creditCard, profile); @@ -744,7 +746,7 @@ public void testNonEmptyPaymentRequest() throws Exception { AutofillAddress address = AssistantCollectUserDataModel.createAutofillAddress( mTestRule.getActivity(), profile); model.set(AssistantCollectUserDataModel.AVAILABLE_SHIPPING_ADDRESSES, - Collections.singletonList(address)); + Collections.singletonList(new AddressModel(address))); AutofillPaymentInstrument paymentInstrument = AssistantCollectUserDataModel.createAutofillPaymentInstrument( mTestRule.getWebContents(), creditCard, profile); diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java index 45f28c0cc80b6f..abca6589de9d03 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPersonalDataManagerTest.java @@ -986,12 +986,15 @@ private boolean hasAddress() { */ @Test @MediumTest - public void testCreateAndEnterAddress() throws Exception { + public void testCreateAndEnterShippingAddress() throws Exception { ArrayList<ActionProto> list = new ArrayList<>(); list.add((ActionProto) ActionProto.newBuilder() - .setCollectUserData(CollectUserDataProto.newBuilder() - .setShippingAddressName("shipping") - .setRequestTermsAndConditions(false)) + .setCollectUserData( + CollectUserDataProto.newBuilder() + .setShippingAddressName("shipping") + .addRequiredShippingAddressDataPiece( + buildRequiredDataPiece("Requires valid state", 34)) + .setRequestTermsAndConditions(false)) .build()); list.add((ActionProto) ActionProto.newBuilder() .setUseAddress( @@ -1026,17 +1029,39 @@ public void testCreateAndEnterAddress() throws Exception { onView(withContentDescription("Street address*")) .perform(scrollTo(), typeText("123 Main St")); onView(withContentDescription("City*")).perform(scrollTo(), typeText("Mountain View")); - onView(withContentDescription("State*")).perform(scrollTo(), typeText("California")); + onView(withContentDescription("State*")).perform(scrollTo(), typeText("Invalid")); onView(withContentDescription("ZIP code*")).perform(scrollTo(), typeText("1234")); onView(withContentDescription("Phone*")).perform(scrollTo(), typeText("8008080808")); Espresso.closeSoftKeyboard(); onView(withId(org.chromium.chrome.R.id.editor_dialog_done_button)) .perform(scrollTo(), click()); - waitUntilViewMatchesCondition(withContentDescription("Continue"), isEnabled()); + // First round: Invalid state. waitUntilViewMatchesCondition( - allOf(withParent(withId(R.id.address_summary)), withId(R.id.full_name)), + withContentDescription("Continue"), allOf(isDisplayed(), not(isEnabled()))); + onView(allOf(withParent(withId(R.id.address_summary)), withId(R.id.incomplete_error))) + .check(matches( + allOf(withText(mTestRule.getActivity().getString( + R.string.autofill_assistant_payment_information_missing)), + isDisplayed()))); + onView(withText("Shipping address")).perform(click()); + waitUntilViewMatchesCondition(withId(R.id.address_full), isDisplayed()); + onView(allOf(withParent(withId(R.id.address_full)), withId(R.id.incomplete_error))) + .check(matches(allOf(withText("Requires valid state"), isDisplayed()))); + onView(withContentDescription("Edit address")).perform(click()); + waitUntilViewMatchesCondition( + withContentDescription("Name*"), allOf(isDisplayed(), isEnabled())); + onView(withContentDescription("State*")) + .perform(scrollTo(), clearText(), typeText("California")); + Espresso.closeSoftKeyboard(); + onView(withId(org.chromium.chrome.R.id.editor_dialog_done_button)) + .perform(scrollTo(), click()); + // Second round: Complete. + waitUntilViewMatchesCondition( + withContentDescription("Continue"), allOf(isDisplayed(), isEnabled())); + waitUntilViewMatchesCondition( + allOf(withParent(withId(R.id.address_full)), withId(R.id.full_name)), allOf(withText("John Doe"), isCompletelyDisplayed())); - onView(withText("Continue")).perform(click()); + onView(withContentDescription("Continue")).perform(click()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); assertThat(getElementValue(getWebContents(), "address_name"), is("John Doe")); assertThat(getElementValue(getWebContents(), "street"), is("123 Main St")); diff --git a/chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.cc b/chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.cc index 1ef62c74ba9922..d2c11b457a1289 100644 --- a/chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.cc +++ b/chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.cc @@ -192,21 +192,6 @@ AssistantCollectUserDataDelegate::GetJavaObject() { return java_assistant_collect_user_data_delegate_; } -bool AssistantCollectUserDataDelegate::IsShippingAddressComplete( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& jcaller, - const base::android::JavaParamRef<jobject>& jaddress) { - if (!jaddress) { - return ui_controller_->IsShippingAddressComplete(nullptr); - } - - autofill::AutofillProfile address; - autofill::PersonalDataManagerAndroid::PopulateNativeProfileFromJava( - jaddress, env, &address); - - return ui_controller_->IsShippingAddressComplete(&address); -} - bool AssistantCollectUserDataDelegate::IsPaymentInstrumentComplete( JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller, diff --git a/chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.h b/chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.h index 522b5de9acd94b..2a92a2ab4d85d5 100644 --- a/chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.h +++ b/chrome/browser/android/autofill_assistant/assistant_collect_user_data_delegate.h @@ -95,11 +95,6 @@ class AssistantCollectUserDataDelegate { const base::android::JavaParamRef<jobject>& jcaller, jboolean jis_focused); - bool IsShippingAddressComplete( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& jcaller, - const base::android::JavaParamRef<jobject>& jaddress); - bool IsPaymentInstrumentComplete( JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller, diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index efa4840b14a465..a8ec539ebe9654 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc @@ -1199,15 +1199,6 @@ void UiControllerAndroid::OnInputTextFocusChanged(bool is_text_focused) { base::TimeDelta::FromMilliseconds(50)); } -bool UiControllerAndroid::IsShippingAddressComplete( - autofill::AutofillProfile* address) { - auto* options = ui_delegate_->GetCollectUserDataOptions(); - if (options == nullptr) { - return false; - } - return IsCompleteShippingAddress(address, *options); -} - bool UiControllerAndroid::IsPaymentInstrumentComplete( autofill::CreditCard* card, autofill::AutofillProfile* address) { @@ -1437,6 +1428,20 @@ void UiControllerAndroid::OnUserDataChanged( const auto& selected_contact_errors = user_data::GetContactValidationErrors( selected_contact_profile, *collect_user_data_options); + const autofill::AutofillProfile* selected_shipping_address = + state->selected_address(collect_user_data_options->shipping_address_name); + auto jselected_shipping_address = + selected_shipping_address == nullptr + ? nullptr + : Java_AssistantCollectUserDataModel_createAutofillAddress( + env, jcontext, + autofill::PersonalDataManagerAndroid:: + CreateJavaProfileFromNative(env, + *selected_shipping_address)); + const auto& selected_shipping_address_errors = + user_data::GetShippingAddressValidationErrors(selected_shipping_address, + *collect_user_data_options); + if (field_change == UserData::FieldChange::ALL || field_change == UserData::FieldChange::AVAILABLE_PROFILES) { // Contact profiles. @@ -1467,26 +1472,26 @@ void UiControllerAndroid::OnUserDataChanged( env, jmodel, jselected_contact, base::android::ToJavaArrayOfStrings(env, selected_contact_errors)); - // Billing addresses profiles. + // Billing address profiles. auto jbillinglist = - Java_AssistantCollectUserDataModel_createAutofillAddressList(env); + Java_AssistantCollectUserDataModel_createBillingAddressList(env); for (const auto& profile : state->available_profiles_) { auto jaddress = Java_AssistantCollectUserDataModel_createAutofillAddress( env, jcontext, autofill::PersonalDataManagerAndroid::CreateJavaProfileFromNative( env, *profile)); if (jaddress) { - Java_AssistantCollectUserDataModel_addAutofillAddress(env, jbillinglist, - jaddress); + Java_AssistantCollectUserDataModel_addBillingAddress(env, jbillinglist, + jaddress); } } Java_AssistantCollectUserDataModel_setAvailableBillingAddresses( env, jmodel, jbillinglist); - // Address profiles. + // Shipping address profiles. auto jshippinglist = - Java_AssistantCollectUserDataModel_createAutofillAddressList(env); - auto address_indices = SortAddressesByCompleteness( + Java_AssistantCollectUserDataModel_createShippingAddressList(env); + auto address_indices = user_data::SortShippingAddressesByCompleteness( *collect_user_data_options, state->available_profiles_); for (int index : address_indices) { auto jaddress = Java_AssistantCollectUserDataModel_createAutofillAddress( @@ -1494,25 +1499,20 @@ void UiControllerAndroid::OnUserDataChanged( autofill::PersonalDataManagerAndroid::CreateJavaProfileFromNative( env, *state->available_profiles_[index])); if (jaddress) { - Java_AssistantCollectUserDataModel_addAutofillAddress( - env, jshippinglist, jaddress); + const auto& errors = user_data::GetShippingAddressValidationErrors( + state->available_profiles_[index].get(), + *collect_user_data_options); + Java_AssistantCollectUserDataModel_addShippingAddress( + env, jshippinglist, jaddress, + base::android::ToJavaArrayOfStrings(env, errors)); } } Java_AssistantCollectUserDataModel_setAvailableShippingAddresses( env, jmodel, jshippinglist); - - // Ignore changes to FieldChange::SHIPPING_ADDRESS, this is already coming - // from the view. - const autofill::AutofillProfile* shipping_address = state->selected_address( - collect_user_data_options->shipping_address_name); Java_AssistantCollectUserDataModel_setSelectedShippingAddress( - env, jmodel, - shipping_address == nullptr - ? nullptr - : Java_AssistantCollectUserDataModel_createAutofillAddress( - env, jcontext, - autofill::PersonalDataManagerAndroid:: - CreateJavaProfileFromNative(env, *shipping_address))); + env, jmodel, jselected_shipping_address, + base::android::ToJavaArrayOfStrings(env, + selected_shipping_address_errors)); } if (field_change == UserData::FieldChange::CONTACT_PROFILE) { // The selection is already known in Java, but it has no errors. The PDM @@ -1521,6 +1521,14 @@ void UiControllerAndroid::OnUserDataChanged( env, jmodel, jselected_contact, base::android::ToJavaArrayOfStrings(env, selected_contact_errors)); } + if (field_change == UserData::FieldChange::SHIPPING_ADDRESS) { + // The selection is already known in Java, but it has no errors. The PDM + // off case does not set updated shipping addresses. + Java_AssistantCollectUserDataModel_setSelectedShippingAddress( + env, jmodel, jselected_shipping_address, + base::android::ToJavaArrayOfStrings(env, + selected_shipping_address_errors)); + } if (field_change == UserData::FieldChange::ALL || field_change == UserData::FieldChange::AVAILABLE_PAYMENT_INSTRUMENTS) { diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.h b/chrome/browser/android/autofill_assistant/ui_controller_android.h index afaed9d990ecc2..3eda3ee2fa2d53 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.h +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.h @@ -162,7 +162,6 @@ class UiControllerAndroid : public ControllerObserver { void OnDateTimeRangeEndTimeSlotCleared(); void OnKeyValueChanged(const std::string& key, const ValueProto& value); void OnInputTextFocusChanged(bool is_text_focused); - bool IsShippingAddressComplete(autofill::AutofillProfile* address); bool IsPaymentInstrumentComplete(autofill::CreditCard* card, autofill::AutofillProfile* address); diff --git a/components/autofill_assistant/browser/actions/collect_user_data_action.cc b/components/autofill_assistant/browser/actions/collect_user_data_action.cc index 8057bfb5eb0dcd..5e1be68a43c1ae 100644 --- a/components/autofill_assistant/browser/actions/collect_user_data_action.cc +++ b/components/autofill_assistant/browser/actions/collect_user_data_action.cc @@ -762,11 +762,6 @@ bool CollectUserDataAction::CreateOptionsFromProto() { collect_user_data.supported_basic_card_networks().end(), std::back_inserter( collect_user_data_options_->supported_basic_card_networks)); - - collect_user_data_options_->shipping_address_name = - collect_user_data.shipping_address_name(); - collect_user_data_options_->request_shipping = - !collect_user_data.shipping_address_name().empty(); collect_user_data_options_->request_payment_method = collect_user_data.request_payment_method(); collect_user_data_options_->require_billing_postal_code = @@ -785,7 +780,6 @@ bool CollectUserDataAction::CreateOptionsFromProto() { VLOG(1) << "Required payment method without address name"; return false; } - collect_user_data_options_->credit_card_expired_text = collect_user_data.credit_card_expired_text(); // TODO(b/146195295): Remove fallback and enforce non-empty backend string. @@ -794,6 +788,18 @@ bool CollectUserDataAction::CreateOptionsFromProto() { l10n_util::GetStringUTF8( IDS_PAYMENTS_VALIDATION_INVALID_CREDIT_CARD_EXPIRED); } + + collect_user_data_options_->shipping_address_name = + collect_user_data.shipping_address_name(); + collect_user_data_options_->request_shipping = + !collect_user_data.shipping_address_name().empty(); + if (collect_user_data_options_->request_shipping) { + collect_user_data_options_->required_shipping_address_data_pieces = + std::vector<RequiredDataPiece>( + collect_user_data.required_shipping_address_data_piece().begin(), + collect_user_data.required_shipping_address_data_piece().end()); + } + collect_user_data_options_->request_login_choice = collect_user_data.has_login_details(); collect_user_data_options_->login_section_title.assign( @@ -984,8 +990,9 @@ bool CollectUserDataAction::CheckInitialAutofillDataComplete( if (collect_user_data_options_->request_shipping) { auto completeAddressIter = std::find_if( profiles.begin(), profiles.end(), [this](const auto* profile) { - return IsCompleteShippingAddress( - profile, *this->collect_user_data_options_.get()); + return user_data::GetShippingAddressValidationErrors( + profile, *this->collect_user_data_options_.get()) + .empty(); }); if (completeAddressIter == profiles.end()) { return false; @@ -1031,7 +1038,9 @@ bool CollectUserDataAction::IsUserDataComplete( user_data.selected_address(options.shipping_address_name); return user_data::GetContactValidationErrors(selected_profile, options) .empty() && - IsCompleteShippingAddress(shipping_address, options) && + user_data::GetShippingAddressValidationErrors(shipping_address, + options) + .empty() && IsCompleteCreditCard(user_data.selected_card(), billing_address, options) && IsValidLoginChoice(user_data.login_choice_identifier_, options) && @@ -1317,7 +1326,7 @@ void CollectUserDataAction::UpdatePersonalDataManagerProfiles( if (!user_data->has_selected_address( collect_user_data_options_->shipping_address_name) && collect_user_data_options_->request_shipping) { - int default_selection = GetDefaultAddressProfile( + int default_selection = user_data::GetDefaultShippingAddressProfile( *collect_user_data_options_, user_data->available_profiles_); if (default_selection != -1) { delegate_->GetUserModel()->SetSelectedAutofillProfile( diff --git a/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc b/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc index 99f65c1fdcba0f..f6422c5b3644dd 100644 --- a/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc +++ b/components/autofill_assistant/browser/actions/collect_user_data_action_unittest.cc @@ -1083,6 +1083,8 @@ TEST_F(CollectUserDataActionTest, UserDataComplete_ShippingAddress) { CollectUserDataOptions options; options.request_shipping = true; options.shipping_address_name = "shipping_address"; + options.required_shipping_address_data_pieces.push_back( + MakeRequiredDataPiece(autofill::ServerFieldType::EMAIL_ADDRESS)); EXPECT_FALSE(CollectUserDataAction::IsUserDataComplete(user_data, user_model_, options)); @@ -1091,9 +1093,9 @@ TEST_F(CollectUserDataActionTest, UserDataComplete_ShippingAddress) { user_model_.SetSelectedAutofillProfile( "shipping_address", std::make_unique<autofill::AutofillProfile>(profile), &user_data); - autofill::test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison", - "marion@me.xyz", "Fox", "123 Zoo St.", - "unit 5", "Hollywood", "CA", + autofill::test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison", "", + "Fox", "123 Zoo St.", "unit 5", "Hollywood", + "CA", /* zipcode = */ "", "US", "16505678910"); user_model_.SetSelectedAutofillProfile( "shipping_address", std::make_unique<autofill::AutofillProfile>(profile), @@ -1101,6 +1103,15 @@ TEST_F(CollectUserDataActionTest, UserDataComplete_ShippingAddress) { EXPECT_FALSE(CollectUserDataAction::IsUserDataComplete(user_data, user_model_, options)); + // Complete for Assistant but not for AddressEditor. + profile.SetRawInfo(autofill::EMAIL_ADDRESS, u"marion@me.xyz"); + user_model_.SetSelectedAutofillProfile( + "shipping_address", std::make_unique<autofill::AutofillProfile>(profile), + &user_data); + EXPECT_FALSE(CollectUserDataAction::IsUserDataComplete(user_data, user_model_, + options)); + + // Complete. profile.SetRawInfo(autofill::ADDRESS_HOME_ZIP, u"91601"); user_model_.SetSelectedAutofillProfile( "shipping_address", std::make_unique<autofill::AutofillProfile>(profile), diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 5fe6480fb63a49..f4ef6c3c07265b 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto @@ -2350,8 +2350,10 @@ message CollectUserDataProto { // contact_details.contact_details_name}. NOTE: when clearing the billing // address, the selected credit card should also be cleared! repeated string clear_previous_profile_selection = 30; + // Defines how to evaluate validitiy of an address or credit card. + repeated RequiredDataPiece required_shipping_address_data_piece = 34; - reserved 7, 26, 34 to 36; + reserved 7, 26, 35 to 36; } // Stop Autofill Assistant. diff --git a/components/autofill_assistant/browser/user_data.h b/components/autofill_assistant/browser/user_data.h index 829df06fac0e19..0f21772a7c7451 100644 --- a/components/autofill_assistant/browser/user_data.h +++ b/components/autofill_assistant/browser/user_data.h @@ -193,6 +193,7 @@ struct CollectUserDataOptions { std::string credit_card_expired_text; std::vector<RequiredDataPiece> required_contact_data_pieces; + std::vector<RequiredDataPiece> required_shipping_address_data_pieces; // If empty, terms and conditions should not be shown. std::string accept_terms_and_conditions_text; diff --git a/components/autofill_assistant/browser/user_data_util.cc b/components/autofill_assistant/browser/user_data_util.cc index b69fa8e9aabadd..4c7cd70c9d8c1e 100644 --- a/components/autofill_assistant/browser/user_data_util.cc +++ b/components/autofill_assistant/browser/user_data_util.cc @@ -16,9 +16,11 @@ #include "components/autofill_assistant/browser/field_formatter.h" #include "components/autofill_assistant/browser/url_utils.h" #include "components/autofill_assistant/browser/website_login_manager.h" +#include "components/strings/grit/components_strings.h" #include "third_party/libaddressinput/chromium/addressinput_util.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h" #include "third_party/re2/src/re2/re2.h" +#include "ui/base/l10n/l10n_util.h" namespace autofill_assistant { namespace { @@ -33,33 +35,6 @@ std::u16string GetProfileFullName(const autofill::AutofillProfile& profile) { profile.GetRawInfo(autofill::NAME_LAST)); } -int GetAddressCompletenessRating(const CollectUserDataOptions& options, - const autofill::AutofillProfile& profile) { - auto address_data = autofill::i18n::CreateAddressDataFromAutofillProfile( - profile, kDefaultLocale); - std::multimap<i18n::addressinput::AddressField, - i18n::addressinput::AddressProblem> - problems; - autofill::addressinput::ValidateRequiredFields( - *address_data, /* filter= */ nullptr, &problems); - return -problems.size(); -} - -// Helper function that compares instances of AutofillProfile by completeness -// in regards to the current options. Full profiles should be ordered before -// empty ones and fall back to compare the profile's name in case of equality. -bool CompletenessCompareAddresses(const CollectUserDataOptions& options, - const autofill::AutofillProfile& a, - const autofill::AutofillProfile& b) { - int complete_fields_a = GetAddressCompletenessRating(options, a); - int complete_fields_b = GetAddressCompletenessRating(options, b); - if (complete_fields_a == complete_fields_b) { - return base::i18n::ToLower(GetProfileFullName(a)) - .compare(base::i18n::ToLower(GetProfileFullName(b))) < 0; - } - return complete_fields_a > complete_fields_b; -} - int CountCompletePaymentInstrumentFields(const CollectUserDataOptions& options, const PaymentInstrument& instrument) { int complete_fields = 0; @@ -220,11 +195,56 @@ bool CompletenessCompareContacts(const CollectUserDataOptions& options, field_formatter::CreateAutofillMappings(b, kDefaultLocale), options.required_contact_data_pieces) .size(); - if (incomplete_fields_a == incomplete_fields_b) { - return base::i18n::ToLower(GetProfileFullName(a)) - .compare(base::i18n::ToLower(GetProfileFullName(b))) < 0; + if (incomplete_fields_a != incomplete_fields_b) { + return incomplete_fields_a <= incomplete_fields_b; } - return incomplete_fields_a <= incomplete_fields_b; + + return base::i18n::ToLower(GetProfileFullName(a)) + .compare(base::i18n::ToLower(GetProfileFullName(b))) < 0; +} + +int GetAddressEditorCompletenessRating( + const autofill::AutofillProfile& profile) { + auto address_data = autofill::i18n::CreateAddressDataFromAutofillProfile( + profile, kDefaultLocale); + std::multimap<i18n::addressinput::AddressField, + i18n::addressinput::AddressProblem> + problems; + autofill::addressinput::ValidateRequiredFields( + *address_data, /* filter= */ nullptr, &problems); + return problems.size(); +} + +// Helper function that compares instances of AutofillProfile by completeness +// in regards to the current options. Full profiles should be ordered before +// empty ones and fall back to compare the profile's name in case of equality. +bool CompletenessCompareShippingAddresses(const CollectUserDataOptions& options, + const autofill::AutofillProfile& a, + const autofill::AutofillProfile& b) { + // Compare by editor completeness first. This is done because the + // AddressEditor only allows storing addresses it considers complete. + int incomplete_fields_a = GetAddressEditorCompletenessRating(a); + int incomplete_fields_b = GetAddressEditorCompletenessRating(b); + if (incomplete_fields_a != incomplete_fields_b) { + return incomplete_fields_a <= incomplete_fields_b; + } + + incomplete_fields_a = + GetValidationErrors( + field_formatter::CreateAutofillMappings(a, kDefaultLocale), + options.required_shipping_address_data_pieces) + .size(); + incomplete_fields_b = + GetValidationErrors( + field_formatter::CreateAutofillMappings(b, kDefaultLocale), + options.required_shipping_address_data_pieces) + .size(); + if (incomplete_fields_a != incomplete_fields_b) { + return incomplete_fields_a <= incomplete_fields_b; + } + + return base::i18n::ToLower(GetProfileFullName(a)) + .compare(base::i18n::ToLower(GetProfileFullName(b))) < 0; } } // namespace @@ -277,41 +297,70 @@ int GetDefaultContactProfile( return sorted_indices[0]; } -} // namespace user_data +std::vector<std::string> GetShippingAddressValidationErrors( + const autofill::AutofillProfile* profile, + const CollectUserDataOptions& collect_user_data_options) { + std::vector<std::string> errors; + if (!collect_user_data_options.request_shipping) { + return errors; + } -std::unique_ptr<autofill::AutofillProfile> MakeUniqueFromProfile( - const autofill::AutofillProfile& profile) { - auto unique_profile = std::make_unique<autofill::AutofillProfile>(profile); - // Temporary workaround so that fields like first/last name a properly - // populated. - unique_profile->FinalizeAfterImport(); - return unique_profile; + if (!collect_user_data_options.required_shipping_address_data_pieces + .empty()) { + errors = GetValidationErrors( + profile + ? field_formatter::CreateAutofillMappings(*profile, kDefaultLocale) + : std::map<std::string, std::string>(), + collect_user_data_options.required_shipping_address_data_pieces); + } + + // Require address editor completeness if Assistant validation succeeds. If + // Assistant validation fails, the editor has to be opened and requires + // completeness to save the change, do not append the (potentially duplicate) + // error in this case. + if (errors.empty() && (profile == nullptr || + GetAddressEditorCompletenessRating(*profile) != 0)) { + errors.push_back(l10n_util::GetStringUTF8( + IDS_AUTOFILL_ASSISTANT_PAYMENT_INFORMATION_MISSING)); + } + return errors; } -std::vector<int> SortAddressesByCompleteness( +std::vector<int> SortShippingAddressesByCompleteness( const CollectUserDataOptions& collect_user_data_options, const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles) { std::vector<int> profile_indices(profiles.size()); std::iota(std::begin(profile_indices), std::end(profile_indices), 0); std::sort(profile_indices.begin(), profile_indices.end(), [&collect_user_data_options, &profiles](int i, int j) { - return CompletenessCompareAddresses(collect_user_data_options, - *profiles[i], *profiles[j]); + return CompletenessCompareShippingAddresses( + collect_user_data_options, *profiles[i], *profiles[j]); }); return profile_indices; } -int GetDefaultAddressProfile( +int GetDefaultShippingAddressProfile( const CollectUserDataOptions& collect_user_data_options, const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles) { if (profiles.empty()) { return -1; } auto sorted_indices = - SortAddressesByCompleteness(collect_user_data_options, profiles); + SortShippingAddressesByCompleteness(collect_user_data_options, profiles); return sorted_indices[0]; } +} // namespace user_data + +std::unique_ptr<autofill::AutofillProfile> MakeUniqueFromProfile( + const autofill::AutofillProfile& profile) { + auto unique_profile = std::make_unique<autofill::AutofillProfile>(profile); + // Temporary workaround so that fields like first/last name a properly + // populated. + unique_profile->FinalizeAfterImport(); + return unique_profile; +} + std::vector<int> SortPaymentInstrumentsByCompleteness( const CollectUserDataOptions& collect_user_data_options, const std::vector<std::unique_ptr<PaymentInstrument>>& @@ -372,13 +421,6 @@ bool CompareContactDetails( return true; } -bool IsCompleteShippingAddress( - const autofill::AutofillProfile* profile, - const CollectUserDataOptions& collect_user_data_options) { - return !collect_user_data_options.request_shipping || - IsCompleteAddress(profile, /* require_postal_code = */ false); -} - bool IsCompleteCreditCard( const autofill::CreditCard* credit_card, const autofill::AutofillProfile* billing_profile, diff --git a/components/autofill_assistant/browser/user_data_util.h b/components/autofill_assistant/browser/user_data_util.h index 81e0024d0d5e77..b408bf0bfef010 100644 --- a/components/autofill_assistant/browser/user_data_util.h +++ b/components/autofill_assistant/browser/user_data_util.h @@ -39,25 +39,29 @@ int GetDefaultContactProfile( const CollectUserDataOptions& collect_user_data_options, const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles); -} // namespace user_data - -std::unique_ptr<autofill::AutofillProfile> MakeUniqueFromProfile( - const autofill::AutofillProfile& profile); +std::vector<std::string> GetShippingAddressValidationErrors( + const autofill::AutofillProfile* profile, + const CollectUserDataOptions& collect_user_data_options); // Sorts the given autofill profiles based on completeness, and returns a // vector of profile indices in sorted order. Full profiles will be ordered // before empty ones, and for equally complete profiles, this falls back to // sorting based on the profile names. -std::vector<int> SortAddressesByCompleteness( +std::vector<int> SortShippingAddressesByCompleteness( const CollectUserDataOptions& collect_user_data_options, const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles); // Get the default selection for the current list of profiles. Returns -1 if no // default selection is possible. -int GetDefaultAddressProfile( +int GetDefaultShippingAddressProfile( const CollectUserDataOptions& collect_user_data_options, const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles); +} // namespace user_data + +std::unique_ptr<autofill::AutofillProfile> MakeUniqueFromProfile( + const autofill::AutofillProfile& profile); + // Sorts the given payment instruments by completeness, and returns a vector // of payment instrument indices in sorted order. Full payment instruments will // be ordered before empty ones, and for equally complete payment instruments, @@ -80,10 +84,6 @@ bool CompareContactDetails( const autofill::AutofillProfile* a, const autofill::AutofillProfile* b); -bool IsCompleteShippingAddress( - const autofill::AutofillProfile* profile, - const CollectUserDataOptions& collect_user_data_options); - bool IsCompleteCreditCard( const autofill::CreditCard* credit_card, const autofill::AutofillProfile* billing_profile, diff --git a/components/autofill_assistant/browser/user_data_util_unittest.cc b/components/autofill_assistant/browser/user_data_util_unittest.cc index 559b4f3bef2e9c..8480cfd39f1c93 100644 --- a/components/autofill_assistant/browser/user_data_util_unittest.cc +++ b/components/autofill_assistant/browser/user_data_util_unittest.cc @@ -210,12 +210,12 @@ TEST(UserDataUtilTest, SortsCompleteAddressesAlphabetically) { CollectUserDataOptions options; std::vector<int> profile_indices = - autofill_assistant::SortAddressesByCompleteness(options, profiles); + user_data::SortShippingAddressesByCompleteness(options, profiles); EXPECT_THAT(profile_indices, SizeIs(profiles.size())); EXPECT_THAT(profile_indices, ElementsAre(1, 0)); } -TEST(UserDataUtilTest, SortsAddressesByCompleteness) { +TEST(UserDataUtilTest, SortsAddressesByEditorCompleteness) { // Adding email address and phone number to demonstrate that they are not // checked for completeness. auto profile_no_street = std::make_unique<autofill::AutofillProfile>(); @@ -226,7 +226,7 @@ TEST(UserDataUtilTest, SortsAddressesByCompleteness) { auto profile_complete = std::make_unique<autofill::AutofillProfile>(); autofill::test::SetProfileInfo(profile_complete.get(), "Berta", "", "West", "", "", "Brandschenkestrasse 110", "", - "Zurich", "", "8002", "UK", ""); + "Zurich", "", "8002", "CH", ""); // Specify profiles in reverse order to force sorting. std::vector<std::unique_ptr<autofill::AutofillProfile>> profiles; @@ -236,7 +236,33 @@ TEST(UserDataUtilTest, SortsAddressesByCompleteness) { CollectUserDataOptions options; std::vector<int> profile_indices = - autofill_assistant::SortAddressesByCompleteness(options, profiles); + user_data::SortShippingAddressesByCompleteness(options, profiles); + EXPECT_THAT(profile_indices, SizeIs(profiles.size())); + EXPECT_THAT(profile_indices, ElementsAre(1, 0)); +} + +TEST(UserDataUtilTest, SortsAddressesByAssistantCompleteness) { + auto profile_no_email = std::make_unique<autofill::AutofillProfile>(); + autofill::test::SetProfileInfo(profile_no_email.get(), "Adam", "", "West", "", + "", "Brandschenkestrasse 110", "", "Zurich", + "", "8002", "CH", ""); + + auto profile_complete = std::make_unique<autofill::AutofillProfile>(); + autofill::test::SetProfileInfo( + profile_complete.get(), "Berta", "", "West", "berta.west@gmail.com", "", + "Brandschenkestrasse 110", "", "Zurich", "", "8002", "CH", ""); + + // Specify profiles in reverse order to force sorting. + std::vector<std::unique_ptr<autofill::AutofillProfile>> profiles; + profiles.emplace_back(std::move(profile_no_email)); + profiles.emplace_back(std::move(profile_complete)); + + CollectUserDataOptions options; + options.required_shipping_address_data_pieces.push_back( + MakeRequiredDataPiece(autofill::ServerFieldType::EMAIL_ADDRESS)); + + std::vector<int> profile_indices = + user_data::SortShippingAddressesByCompleteness(options, profiles); EXPECT_THAT(profile_indices, SizeIs(profiles.size())); EXPECT_THAT(profile_indices, ElementsAre(1, 0)); } @@ -245,7 +271,8 @@ TEST(UserDataUtilTest, GetDefaultAddressSelectionForEmptyProfiles) { std::vector<std::unique_ptr<autofill::AutofillProfile>> profiles; CollectUserDataOptions options; - EXPECT_THAT(GetDefaultAddressProfile(options, profiles), -1); + EXPECT_THAT(user_data::GetDefaultShippingAddressProfile(options, profiles), + -1); } TEST(UserDataUtilTest, GetDefaultAddressSelectionForCompleteProfiles) { @@ -270,7 +297,8 @@ TEST(UserDataUtilTest, GetDefaultAddressSelectionForCompleteProfiles) { CollectUserDataOptions options; - EXPECT_THAT(GetDefaultAddressProfile(options, profiles), 1); + EXPECT_THAT(user_data::GetDefaultShippingAddressProfile(options, profiles), + 1); } TEST(UserDataUtilTest, SortsCreditCardsByCompleteness) { @@ -625,25 +653,74 @@ TEST(UserDataUtilTest, CompleteShippingAddressNotRequired) { CollectUserDataOptions not_required_options; not_required_options.request_shipping = false; - EXPECT_TRUE(IsCompleteShippingAddress(nullptr, not_required_options)); + EXPECT_THAT(user_data::GetShippingAddressValidationErrors( + nullptr, not_required_options), + IsEmpty()); } -TEST(UserDataUtilTest, CompleteShippingAddressRequired) { +TEST(UserDataUtilTest, CompleteShippingAddressForAssistant) { autofill::AutofillProfile address; CollectUserDataOptions require_shipping_options; require_shipping_options.request_shipping = true; - + require_shipping_options.required_shipping_address_data_pieces.push_back( + MakeRequiredDataPiece( + autofill::ServerFieldType::ADDRESS_HOME_STREET_ADDRESS)); + require_shipping_options.required_shipping_address_data_pieces.push_back( + MakeRequiredDataPiece(autofill::ServerFieldType::ADDRESS_HOME_ZIP)); + require_shipping_options.required_shipping_address_data_pieces.push_back( + MakeRequiredDataPiece(autofill::ServerFieldType::ADDRESS_HOME_COUNTRY)); + + EXPECT_THAT(user_data::GetShippingAddressValidationErrors( + nullptr, require_shipping_options), + ElementsAre("77", "35", "36")); autofill::test::SetProfileInfo(&address, "John", "", "Doe", "john.doe@gmail.com", "", /* address1= */ "", /* address2= */ "", /* city= */ "", /* state= */ "", /* zip_code= */ "", - /* country= */ "", "+41"); - EXPECT_FALSE(IsCompleteShippingAddress(&address, require_shipping_options)); + /* country= */ "", /* phone= */ ""); + EXPECT_THAT(user_data::GetShippingAddressValidationErrors( + &address, require_shipping_options), + ElementsAre("77", "35", "36")); + autofill::test::SetProfileInfo(&address, "John", "", "Doe", + /* email= */ "", "", "Brandschenkestrasse 110", + "", "Zurich", "Zurich", /* zip_code= */ "", + "CH", + /* phone= */ ""); + EXPECT_THAT(user_data::GetShippingAddressValidationErrors( + &address, require_shipping_options), + ElementsAre("35")); + autofill::test::SetProfileInfo(&address, "John", "", "Doe", + /* email= */ "", "", "Brandschenkestrasse 110", + "", "Zurich", "Zurich", "8002", "CH", + /* phone= */ ""); + EXPECT_THAT(user_data::GetShippingAddressValidationErrors( + &address, require_shipping_options), + IsEmpty()); +} + +TEST(UserDataUtilTest, CompleteShippingAddressForEditor) { + autofill::AutofillProfile address; + CollectUserDataOptions require_shipping_options; + require_shipping_options.request_shipping = true; + + EXPECT_THAT(user_data::GetShippingAddressValidationErrors( + nullptr, require_shipping_options), + ElementsAre(_)); + autofill::test::SetProfileInfo(&address, "John", "", "Doe", + /* email= */ "", "", "Brandschenkestrasse 110", + "", "Zurich", "Zurich", /* zip_code= */ "", + "CH", + /* phone= */ ""); + EXPECT_THAT(user_data::GetShippingAddressValidationErrors( + &address, require_shipping_options), + ElementsAre(_)); autofill::test::SetProfileInfo(&address, "John", "", "Doe", /* email= */ "", "", "Brandschenkestrasse 110", "", "Zurich", "Zurich", "8002", "CH", /* phone= */ ""); - EXPECT_TRUE(IsCompleteShippingAddress(&address, require_shipping_options)); + EXPECT_THAT(user_data::GetShippingAddressValidationErrors( + &address, require_shipping_options), + IsEmpty()); } TEST(UserDataUtilTest, CompleteCreditCardNotRequired) { diff --git a/components/autofill_assistant_strings.grdp b/components/autofill_assistant_strings.grdp index 30c1712b14597f..aa52aff3fe2839 100644 --- a/components/autofill_assistant_strings.grdp +++ b/components/autofill_assistant_strings.grdp @@ -3,6 +3,9 @@ <message name="IDS_AUTOFILL_ASSISTANT_PAYMENT_INFO_CONFIRM" desc="Text on the payment request primary button to confirm payment information [CHAR_LIMIT=32]"> Continue </message> + <message name="IDS_AUTOFILL_ASSISTANT_PAYMENT_INFORMATION_MISSING" desc="Text label that is shown when a payment request entry (e.g., contact details or payment method) is incomplete."> + Information missing + </message> <message name="IDS_AUTOFILL_ASSISTANT_DEFAULT_ERROR" desc="Text label that is shown when autofill assistant cannot help anymore, because something went wrong."> Sorry, something went wrong. </message> diff --git a/components/autofill_assistant_strings_grdp/IDS_AUTOFILL_ASSISTANT_PAYMENT_INFORMATION_MISSING.png.sha1 b/components/autofill_assistant_strings_grdp/IDS_AUTOFILL_ASSISTANT_PAYMENT_INFORMATION_MISSING.png.sha1 new file mode 100644 index 00000000000000..0c2f037886da2e --- /dev/null +++ b/components/autofill_assistant_strings_grdp/IDS_AUTOFILL_ASSISTANT_PAYMENT_INFORMATION_MISSING.png.sha1 @@ -0,0 +1 @@ +a9e1c5e944e0445776057beb4d5193e39514e77a \ No newline at end of file From 566af05ec4f84744ac02f3572b9d991dc51da7cc Mon Sep 17 00:00:00 2001 From: Charlie Hu <chenleihu@google.com> Date: Tue, 1 Jun 2021 14:00:35 +0000 Subject: [PATCH 71/81] [UseCounter] Only report features in HTTP/HTTPS page to browser |MetricsWebContentsObserver::DoesTimingUpdateHaveError| on the browser side discards all new feature observations in non HTTP/HTTPS pages. This CL filters outgoing observation events from renderer to avoid unnecessary IPC traffic. Bug: 1196402 Change-Id: I997613d6d6bdfd006a90d5d5b4f01f86128c360d Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2892802 Reviewed-by: Daniel Cheng <dcheng@chromium.org> Reviewed-by: Ian Clelland <iclelland@chromium.org> Commit-Queue: Charlie Hu <chenleihu@google.com> Cr-Commit-Position: refs/heads/master@{#887948} --- .../renderer/core/frame/use_counter_impl.cc | 47 +++++++-------- .../core/frame/use_counter_impl_test.cc | 59 ++++++++++++++++++- .../histograms_xml/blink/histograms.xml | 8 +-- 3 files changed, 86 insertions(+), 28 deletions(-) diff --git a/third_party/blink/renderer/core/frame/use_counter_impl.cc b/third_party/blink/renderer/core/frame/use_counter_impl.cc index 3dacfcce543298..fda2ad0a77870b 100644 --- a/third_party/blink/renderer/core/frame/use_counter_impl.cc +++ b/third_party/blink/renderer/core/frame/use_counter_impl.cc @@ -104,10 +104,16 @@ void UseCounterImpl::Trace(Visitor* visitor) const { void UseCounterImpl::DidCommitLoad(const LocalFrame* frame) { const KURL url = frame->GetDocument()->Url(); - if (url.ProtocolIs("chrome-extension")) + if (url.ProtocolIs("chrome-extension")) { context_ = kExtensionContext; - if (url.ProtocolIs("file")) + } else if (url.ProtocolIs("file")) { context_ = kFileContext; + } else if (url.ProtocolIsInHTTPFamily()) { + context_ = kDefaultContext; + } else { + // UseCounter is disabled for all other URL schemes. + context_ = kDisabledContext; + } DCHECK_EQ(kPreCommit, commit_state_); commit_state_ = kCommited; @@ -123,7 +129,6 @@ void UseCounterImpl::DidCommitLoad(const LocalFrame* frame) { TraceMeasurement(feature); } - // TODO(crbug.com/1196402): move extension histogram to the browser side. if (context_ == kExtensionContext || context_ == kFileContext) { CountFeature(WebFeature::kPageVisits); } @@ -213,8 +218,6 @@ void UseCounterImpl::NotifyFeatureCounted(WebFeature feature) { observers_.RemoveAll(to_be_removed); } -// TODO(crbug.com/1196402): Remove this method after all histograms are -// counted on browser side. void UseCounterImpl::CountFeature(WebFeature feature) const { switch (context_) { case kDefaultContext: @@ -246,26 +249,24 @@ bool UseCounterImpl::ReportMeasurement(const UseCounterFeature& feature, return false; auto* client = frame->Client(); - switch (feature.type()) { - case mojom::blink::UseCounterFeatureType::kWebFeature: { - WebFeature web_feature = static_cast<WebFeature>(feature.value()); - if (context_ != kDefaultContext) - CountFeature(web_feature); - NotifyFeatureCounted(web_feature); - break; - } - case mojom::blink::UseCounterFeatureType::kAnimatedCssProperty: - case mojom::blink::UseCounterFeatureType::kCssProperty: - if (context_ == kExtensionContext) - return false; - break; - case mojom::blink::UseCounterFeatureType:: - kPermissionsPolicyViolationEnforce: - break; + if (feature.type() == mojom::blink::UseCounterFeatureType::kWebFeature) + NotifyFeatureCounted(static_cast<WebFeature>(feature.value())); + + // Report to browser about observed event only when URL is HTTP/HTTPS, + // as other URL schemes are filtered out in + // |MetricsWebContentsObserver::DoesTimingUpdateHaveError| anyway. + if (context_ == kDefaultContext) { + client->DidObserveNewFeatureUsage(feature); + return true; + } + + // WebFeatures in non-default contexts are counted on renderer side. + if (feature.type() == mojom::blink::UseCounterFeatureType::kWebFeature) { + CountFeature(static_cast<WebFeature>(feature.value())); + return true; } - client->DidObserveNewFeatureUsage(feature); - return true; + return false; } // Note that HTTPArchive tooling looks specifically for this event - see diff --git a/third_party/blink/renderer/core/frame/use_counter_impl_test.cc b/third_party/blink/renderer/core/frame/use_counter_impl_test.cc index c08488615e0ac1..70b081dd274a6f 100644 --- a/third_party/blink/renderer/core/frame/use_counter_impl_test.cc +++ b/third_party/blink/renderer/core/frame/use_counter_impl_test.cc @@ -12,6 +12,7 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html/html_html_element.h" #include "third_party/blink/renderer/core/loader/document_loader.h" +#include "third_party/blink/renderer/core/loader/empty_clients.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" @@ -41,7 +42,26 @@ using WebFeature = mojom::WebFeature; class UseCounterImplTest : public testing::Test { public: - UseCounterImplTest() : dummy_(std::make_unique<DummyPageHolder>()) { + class DummyLocalFrameClient : public EmptyLocalFrameClient { + public: + DummyLocalFrameClient() = default; + const std::vector<UseCounterFeature>& observed_features() const { + return observed_features_; + } + + private: + void DidObserveNewFeatureUsage(const UseCounterFeature& feature) override { + observed_features_.push_back(feature); + } + std::vector<UseCounterFeature> observed_features_; + }; + + UseCounterImplTest() + : dummy_(std::make_unique<DummyPageHolder>( + /* initial_view_size= */ IntSize(), + /* chrome_client= */ nullptr, + /* local_frame_client= */ + MakeGarbageCollected<DummyLocalFrameClient>())) { Page::InsertOrdinaryPageForTesting(&dummy_->GetPage()); } @@ -67,6 +87,43 @@ class UseCounterImplTest : public testing::Test { } }; +class UseCounterImplBrowserReportTest + : public UseCounterImplTest, + public ::testing::WithParamInterface</* URL */ const char*> {}; + +INSTANTIATE_TEST_SUITE_P(All, + UseCounterImplBrowserReportTest, + ::testing::Values("chrome-extension://dummysite/", + "file://dummyfile", + "data:;base64,", + "ftp://ftp.dummy/dummy.txt", + "http://foo.com", + "https://bar.com")); + +// UseCounter should not send events to browser when handling page with +// Non HTTP Family URLs, as these events will be discarded on the browser side +// in |MetricsWebContentsObserver::DoesTimingUpdateHaveError|. +TEST_P(UseCounterImplBrowserReportTest, ReportOnlyHTTPFamily) { + KURL url = url_test_helpers::ToKURL(GetParam()); + SetURL(url); + UseCounterImpl use_counter; + use_counter.DidCommitLoad(GetFrame()); + + // Count every feature types in UseCounterFeatureType. + use_counter.Count(mojom::WebFeature::kFetch, GetFrame()); + use_counter.Count(CSSPropertyID::kHeight, + UseCounterImpl::CSSPropertyType::kDefault, GetFrame()); + use_counter.Count(CSSPropertyID::kHeight, + UseCounterImpl::CSSPropertyType::kAnimation, GetFrame()); + + auto* dummy_client = + static_cast<UseCounterImplBrowserReportTest::DummyLocalFrameClient*>( + GetFrame()->Client()); + + EXPECT_EQ(!dummy_client->observed_features().empty(), + url.ProtocolIsInHTTPFamily()); +} + TEST_F(UseCounterImplTest, RecordingExtensions) { const std::string histogram = kExtensionFeaturesHistogramName; constexpr auto item = mojom::WebFeature::kFetch; diff --git a/tools/metrics/histograms/histograms_xml/blink/histograms.xml b/tools/metrics/histograms/histograms_xml/blink/histograms.xml index c3bf4e13d897a9..436280e7d59c30 100644 --- a/tools/metrics/histograms/histograms_xml/blink/histograms.xml +++ b/tools/metrics/histograms/histograms_xml/blink/histograms.xml @@ -2898,10 +2898,10 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. UseCounterPageLoadMetricsObserver. </summary> <details> - Note that features used inside of SVG images are tracked separately in the - Blink.UseCounter.SVGImage.Features histogram. Features used inside of - extension pages are tracked separately in the - Blink.UseCounter.Extensions.Features histogram. + Note that this histogram only counts page with HTTP/HTTPS URL scheme. + Feature used in pages with other URL schemes might be counted in other + histograms: "extension://" : Blink.UseCounter.Extensions.Features + "file://" : Blink.UseCounter.File.Features </details> </histogram> From bf9a037bced1eaa4d7ebfc1dafdb23617bea52c3 Mon Sep 17 00:00:00 2001 From: kylechar <kylechar@chromium.org> Date: Tue, 1 Jun 2021 14:00:48 +0000 Subject: [PATCH 72/81] Add NoInterrupt to DisableSwapUntilResize() IPC There have been security issues with re-enetrant IPCs while waiting for the synchronous response to DisableSwapUntilResize(). Add NoInterrupt to prevent re-entrant IPCs. Bug: 1087238 Change-Id: I7d1c07e55483ddbedf4883de8dcbcc0208be4e8b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928603 Commit-Queue: kylechar <kylechar@chromium.org> Reviewed-by: Ken Buchanan <kenrb@chromium.org> Cr-Commit-Position: refs/heads/master@{#887949} --- services/viz/privileged/mojom/compositing/display_private.mojom | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/viz/privileged/mojom/compositing/display_private.mojom b/services/viz/privileged/mojom/compositing/display_private.mojom index 409115f95787e3..03ad7c39128fc4 100644 --- a/services/viz/privileged/mojom/compositing/display_private.mojom +++ b/services/viz/privileged/mojom/compositing/display_private.mojom @@ -22,7 +22,7 @@ interface DisplayPrivate { // Attempts to immediately swap a frame with the current size if possible, // then will no longer swap until Resize() is called with a non-empty size. - [EnableIf=is_win, Sync] + [EnableIf=is_win, Sync, NoInterrupt] DisableSwapUntilResize() => (); // Resizes the display. From 852446efd70ddbfec6d5dcab4427fc97ec49ee76 Mon Sep 17 00:00:00 2001 From: Alice Wang <aliceywang@chromium.org> Date: Tue, 1 Jun 2021 14:01:42 +0000 Subject: [PATCH 73/81] [Android] Remove unused method AccountManagerFacade#isGooglePlayServicesAvailable() This CL removes the unused method isGooglePlayServicesAvailable() from AccountManagerFacade and AccountManagerDelegate interfaces. Bug: 1194581 Change-Id: I45f2cbb234500a350c663a759ada8732b95aee5a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928763 Reviewed-by: Tanmoy Mollik <triploblastic@chromium.org> Commit-Queue: Alice Wang <aliceywang@chromium.org> Cr-Commit-Position: refs/heads/master@{#887950} --- .../components/signin/AccountManagerDelegate.java | 5 ----- .../chromium/components/signin/AccountManagerFacade.java | 6 ------ .../components/signin/AccountManagerFacadeImpl.java | 8 -------- .../components/signin/SystemAccountManagerDelegate.java | 3 +-- .../signin/test/util/FakeAccountManagerDelegate.java | 5 ----- .../signin/test/util/FakeAccountManagerFacade.java | 5 ----- 6 files changed, 1 insertion(+), 31 deletions(-) diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java b/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java index e5e31e84aa41c1..2441f5c947c03e 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java @@ -119,9 +119,4 @@ default ProfileDataSource getProfileDataSource() { @WorkerThread @Nullable String getAccountGaiaId(String accountEmail); - - /** - * Checks whether Google Play services is available. - */ - boolean isGooglePlayServicesAvailable(); } diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacade.java b/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacade.java index 8f69ac804f1064..e69cbc9b4fb761 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacade.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacade.java @@ -148,10 +148,4 @@ void updateCredentials( @WorkerThread @Nullable String getAccountGaiaId(String accountEmail); - - /** - * Checks whether Google Play services is available. - */ - @AnyThread - boolean isGooglePlayServicesAvailable(); } diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacadeImpl.java b/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacadeImpl.java index d38565ad446963..6a5441f8a527da 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacadeImpl.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/AccountManagerFacadeImpl.java @@ -264,14 +264,6 @@ public String getAccountGaiaId(String accountEmail) { return mDelegate.getAccountGaiaId(accountEmail); } - /** - * Checks whether Google Play services is available. - */ - @Override - public boolean isGooglePlayServicesAvailable() { - return mDelegate.isGooglePlayServicesAvailable(); - } - private void updateCanOfferExtendedSyncPromos(List<Account> accounts) { new AsyncTask<Void>() { @Override diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java b/components/signin/public/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java index 982dc71d04c087..6d2322236872d8 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java @@ -226,8 +226,7 @@ public String getAccountGaiaId(String accountEmail) { } } - @Override - public boolean isGooglePlayServicesAvailable() { + protected boolean isGooglePlayServicesAvailable() { return ExternalAuthUtils.getInstance().canUseGooglePlayServices(); } diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java b/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java index c809e991d7d2c3..b5eccb8bbd0c74 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java @@ -60,11 +60,6 @@ public String getAccountGaiaId(String accountEmail) { return "gaia-id-" + accountEmail.replace("@", "_at_"); } - @Override - public boolean isGooglePlayServicesAvailable() { - return true; - } - @Override public void attachAccountsChangeObserver(AccountsChangeObserver observer) { mObserver = observer; diff --git a/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java b/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java index 2ea832f89160a3..e196f4648aa2b8 100644 --- a/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java +++ b/components/signin/public/android/java/src/org/chromium/components/signin/test/util/FakeAccountManagerFacade.java @@ -138,11 +138,6 @@ public String getAccountGaiaId(String accountEmail) { return "gaia-id-" + accountEmail.replace("@", "_at_"); } - @Override - public boolean isGooglePlayServicesAvailable() { - return true; - } - /** * Adds an account to the fake AccountManagerFacade. */ From cfc668ecb55157167f5449399940b04cac48d16e Mon Sep 17 00:00:00 2001 From: Elad Alon <eladalon@chromium.org> Date: Tue, 1 Jun 2021 14:01:55 +0000 Subject: [PATCH 74/81] [Capture Handle] Add browser tests Add browser tests coverage for Capture Handle. Bug: 1213866 Change-Id: If22bb65019bd029c74356977dc5db2015c021455 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2919713 Reviewed-by: Guido Urdaneta <guidou@chromium.org> Reviewed-by: Thomas Guilbert <tguilbert@chromium.org> Reviewed-by: Olga Sharonova <olka@chromium.org> Commit-Queue: Elad Alon <eladalon@chromium.org> Cr-Commit-Position: refs/heads/master@{#887951} --- .../webrtc/capture_handle_browsertest.cc | 561 ++++++++++++++++++ .../desktop_media_list_controller.cc | 17 +- .../desktop_media_list_controller.h | 7 +- chrome/common/chrome_switches.cc | 9 + chrome/common/chrome_switches.h | 1 + chrome/test/BUILD.gn | 1 + .../test/data/webrtc/captured_page_main.html | 62 ++ .../test/data/webrtc/captured_page_other.html | 28 + .../test/data/webrtc/capturing_page_main.html | 89 +++ 9 files changed, 768 insertions(+), 7 deletions(-) create mode 100644 chrome/browser/media/webrtc/capture_handle_browsertest.cc create mode 100644 chrome/test/data/webrtc/captured_page_main.html create mode 100644 chrome/test/data/webrtc/captured_page_other.html create mode 100644 chrome/test/data/webrtc/capturing_page_main.html diff --git a/chrome/browser/media/webrtc/capture_handle_browsertest.cc b/chrome/browser/media/webrtc/capture_handle_browsertest.cc new file mode 100644 index 00000000000000..0cd998c922d9fd --- /dev/null +++ b/chrome/browser/media/webrtc/capture_handle_browsertest.cc @@ -0,0 +1,561 @@ +// Copyright 2021 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 <string> +#include <vector> + +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "base/strings/strcat.h" +#include "base/strings/stringprintf.h" +#include "build/buildflag.h" +#include "chrome/browser/media/webrtc/webrtc_browsertest_base.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_tabstrip.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/permissions/permission_request_manager.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_base.h" +#include "content/public/test/browser_test_utils.h" + +// TODO(crbug.com/1215089): Enable this test suite on Lacros. +#if !BUILDFLAG(IS_CHROMEOS_LACROS) + +using content::WebContents; + +namespace { + +// The captured tab is identified by its title. +const char kCapturedTabTitle[] = "totally-unique-captured-page-title"; + +// Capturing page. +const char kCapturingPageMain[] = "/webrtc/capturing_page_main.html"; +// Captured page. +const char kCapturedPageMain[] = "/webrtc/captured_page_main.html"; +// Similar contents to kCapturedPageMain, but on a different page, which can +// be served same-origin or cross-origin. +const char kCapturedPageOther[] = "/webrtc/captured_page_other.html"; + +const char* kArbitraryOrigin = "https://arbitrary-origin.com"; +const char* kNoCaptureHandle = "no-capture-handle"; + +std::string StringifyPermittedOrigins( + const std::vector<std::string>& permitted_origins) { + if (permitted_origins.empty()) { + return "[]"; + } + return base::StrCat( + {"[\"", base::JoinString(permitted_origins, "\", \""), "\"]"}); +} + +std::string StringifyCaptureHandle(WebContents* web_contents, + bool expose_origin, + const std::string& handle) { + if (!expose_origin && handle.empty()) { + return ""; + } + + std::string origin_str; + if (expose_origin) { + const auto origin = + url::Origin::Create(web_contents->GetLastCommittedURL()); + origin_str = + base::StringPrintf(",\"origin\":\"%s\"", origin.Serialize().c_str()); + } + + return base::StringPrintf("{\"handle\":\"%s\"%s}", handle.c_str(), + origin_str.c_str()); +} + +// Conveniently pack together a captured tab and the capture-handle that +// is expected to be observed by capturers from a permitted origin. +struct TabInfo { + void StartCapturing() { + std::string script_result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + web_contents->GetMainFrame(), "captureOtherTab();", &script_result)); + EXPECT_EQ(script_result, "capture-success"); + } + + url::Origin GetOrigin() const { + return url::Origin::Create(web_contents->GetLastCommittedURL()); + } + + std::string GetOriginAsString() const { return GetOrigin().Serialize(); } + + void SetCaptureHandleConfig( + bool expose_origin, + const std::string& handle, + const std::vector<std::string>& permitted_origins) { + std::string script_result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + web_contents->GetMainFrame(), + base::StringPrintf( + "callSetCaptureHandleConfig(%s, \"%s\", %s);", + expose_origin ? "true" : "false", handle.c_str(), + StringifyPermittedOrigins(permitted_origins).c_str()), + &script_result)); + EXPECT_EQ(script_result, "capture-handle-set"); + + capture_handle = + StringifyCaptureHandle(web_contents, expose_origin, handle); + } + + std::string ReadCaptureHandleFromSettings() { + std::string script_result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + web_contents->GetMainFrame(), "readCaptureHandleFromSettings();", + &script_result)); + return script_result; + } + + void Navigate(Browser* browser, GURL url, bool expect_handle_reset = false) { + std::string script_result; + ASSERT_TRUE(content::ExecuteScriptAndExtractString( + web_contents->GetMainFrame(), + base::StringPrintf("clickLinkToUrl(\"%s\");", url.spec().c_str()), + &script_result)); + ASSERT_EQ(script_result, "link-success"); + + if (expect_handle_reset) { + capture_handle = ""; + } + } + + std::string LastEvent() { + std::string script_result = "error-not-modified"; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + web_contents->GetMainFrame(), "readLastEvent();", &script_result)); + return script_result; + } + + WebContents* web_contents; + std::string capture_handle; // Expected value for those who may observe. +}; + +TabInfo MakeTabInfo(WebContents* web_contents, + bool expose_origin, + const std::string& handle) { + return TabInfo{web_contents, + StringifyCaptureHandle(web_contents, expose_origin, handle)}; +} + +} // namespace + +// Essentially depends on InProcessBrowserTest, but WebRtcTestBase provides +// detection of JS errors. +class CaptureHandleBrowserTest : public WebRtcTestBase { + public: + void SetUpInProcessBrowserTestFixture() override { + WebRtcTestBase::SetUpInProcessBrowserTestFixture(); + + DetectErrorsInJavaScript(); + + base::FilePath test_dir; + ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_dir)); + + for (size_t i = 0; i < 3; ++i) { + servers_.emplace_back(std::make_unique<net::EmbeddedTestServer>()); + servers_[i]->ServeFilesFromDirectory(test_dir); + ASSERT_TRUE(servers_[i]->Start()); + } + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch( + switches::kEnableExperimentalWebPlatformFeatures); + command_line->AppendSwitchASCII( + switches::kAutoSelectTabCaptureSourceByTitle, kCapturedTabTitle); + } + + void TearDownOnMainThread() override { + for (auto& server : servers_) { + if (server) { + ASSERT_TRUE(server->ShutdownAndWaitUntilComplete()); + } + } + + WebRtcTestBase::TearDownOnMainThread(); + } + + // Same as WebRtcTestBase::OpenTestPageInNewTab, but does not assume + // a single embedded server is used for all pages. + WebContents* OpenTestPageInNewTab(const std::string& test_page, + net::EmbeddedTestServer* server) const { + chrome::AddTabAt(browser(), GURL(url::kAboutBlankURL), -1, true); + GURL url = server->GetURL(test_page); + ui_test_utils::NavigateToURL(browser(), url); + WebContents* new_tab = browser()->tab_strip_model()->GetActiveWebContents(); + permissions::PermissionRequestManager::FromWebContents(new_tab) + ->set_auto_response_for_test( + permissions::PermissionRequestManager::ACCEPT_ALL); + return new_tab; + } + + TabInfo SetUpCapturingPage(bool start_capturing) { + auto* const web_contents = OpenTestPageInNewTab( + kCapturingPageMain, servers_[kCapturingServer].get()); + + auto result = MakeTabInfo(web_contents, true, "capturing_page"); + if (start_capturing) { + result.StartCapturing(); + } + + event_sinks_.push_back(web_contents); + + return result; + } + + TabInfo SetUpCapturedPage(bool expose_origin, + const std::string& handle, + const std::vector<std::string>& permitted_origins, + bool self_capture = false) { + // Normally, the captured page has its own server (=origin) and own file. + // But if self-capture is tested, use the origin and page of the capturer. + const char* page = self_capture ? kCapturingPageMain : kCapturedPageMain; + const int server_index = self_capture ? kCapturingServer : kCapturedServer; + + auto* const web_contents = + OpenTestPageInNewTab(page, servers_[server_index].get()); + + // The target for getDisplayMedia is determined via the title. If we want + // the capturing page to capture itself, then it has to change its title. + if (self_capture) { + std::string script_result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + web_contents->GetMainFrame(), + base::StringPrintf("setTitle(\"%s\");", kCapturedTabTitle), + &script_result)); + EXPECT_EQ(script_result, "title-changed"); + } + + auto tab_info = MakeTabInfo(web_contents, expose_origin, handle); + + tab_info.SetCaptureHandleConfig(expose_origin, handle, permitted_origins); + + return tab_info; + } + + static constexpr size_t kCapturedServer = 0; + static constexpr size_t kCapturingServer = 1; + static constexpr size_t kOtherCapturedServer = 2; + + // Checked for no unconsumed events. + std::vector<WebContents*> event_sinks_; + + // Three servers to create three origins (different ports). One server for the + // captured page, one for the top-level capturer and one for the embedded + // capturer. Some tests will use one server for multiple pages so as to + // make them same-origin. + std::vector<std::unique_ptr<net::EmbeddedTestServer>> servers_; +}; + +IN_PROC_BROWSER_TEST_F(CaptureHandleBrowserTest, + HandleAndOriginExposedIfAllPermitted) { + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/true, "handle", {"*"}); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // The capture handle set by the captured tab is observable by the capturer. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); +} + +IN_PROC_BROWSER_TEST_F(CaptureHandleBrowserTest, + HandleAndOriginExposedIfCapturerOriginPermitted) { + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/false); + + TabInfo captured_tab = SetUpCapturedPage(/*expose_origin=*/true, "handle", + {capturing_tab.GetOriginAsString()}); + + capturing_tab.StartCapturing(); + + // The capture handle set by the captured tab is observable by the capturer. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); +} + +IN_PROC_BROWSER_TEST_F(CaptureHandleBrowserTest, + HandleAndOriginNotExposedIfCapturerOriginNotPermitted) { + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/false); + + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/true, "handle", {kArbitraryOrigin}); + + capturing_tab.StartCapturing(); + + // The capture handle isn't observable by the capturer. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), kNoCaptureHandle); +} + +IN_PROC_BROWSER_TEST_F(CaptureHandleBrowserTest, CanExposeOnlyHandle) { + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/false, "handle", {"*"}); + ASSERT_EQ(captured_tab.capture_handle.find("origin"), std::string::npos); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // The capture handle set by the captured tab is observable by the capturer. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); +} + +IN_PROC_BROWSER_TEST_F(CaptureHandleBrowserTest, + CanExposeEmptyHandleIfExposingOrigin) { + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/true, /*handle=*/"", {"*"}); + // Still expecting "handle: \"\"" in there. + ASSERT_NE(captured_tab.capture_handle.find("handle"), std::string::npos); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // The capture handle set by the captured tab is observable by the capturer. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); +} + +IN_PROC_BROWSER_TEST_F(CaptureHandleBrowserTest, + EmptyCaptureHandleConfigMeansCaptureHandleNotExposed) { + // Note - even if we set permitted origins, the empty config is empty. + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/false, /*handle=*/"", {"*"}); + // Not expecting "handle: \"\"" in there, nor "origin:..." + ASSERT_EQ(captured_tab.capture_handle, ""); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // The capture handle isn't observable by the capturer. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), kNoCaptureHandle); +} + +IN_PROC_BROWSER_TEST_F( + CaptureHandleBrowserTest, + CallingSetCaptureHandleConfigWithEmptyConfigFiresEventAndClearsValue) { + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/true, "handle", {"*"}); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // The capture handle set by the captured tab is observable by the capturer. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); + + // New CaptureHandleConfig set by captured tab triggers an event, and all + // subsequent calls to getSettings produce the new values. + captured_tab.SetCaptureHandleConfig(/*expose_origin=*/false, "", {}); + EXPECT_EQ(capturing_tab.LastEvent(), "{}"); + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), kNoCaptureHandle); +} + +IN_PROC_BROWSER_TEST_F( + CaptureHandleBrowserTest, + CallingSetCaptureHandleConfigWithNewHandleChangesConfigAndFiresEvent) { + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/true, "handle", {"*"}); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // The capture handle set by the captured tab is observable by the capturer. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); + + // New CaptureHandleConfig set by captured tab triggers an event, and all + // subsequent calls to getSettings produce the new values. + captured_tab.SetCaptureHandleConfig(/*expose_origin=*/true, "new_handle", + {"*"}); + EXPECT_EQ(capturing_tab.LastEvent(), captured_tab.capture_handle); + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); +} + +IN_PROC_BROWSER_TEST_F( + CaptureHandleBrowserTest, + CallingSetCaptureHandleConfigWithNewOriginValueChangesConfigAndFiresEvent) { + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/true, "handle", {"*"}); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // The capture handle set by the captured tab is observable by the capturer. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); + + // New CaptureHandleConfig set by captured tab triggers an event, and all + // subsequent calls to getSettings produce the new values. + captured_tab.SetCaptureHandleConfig(/*expose_origin=*/false, "handle", {"*"}); + EXPECT_EQ(capturing_tab.LastEvent(), captured_tab.capture_handle); + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); +} + +IN_PROC_BROWSER_TEST_F( + CaptureHandleBrowserTest, + PermittedOriginsChangeThatRemovesCapturerCausesEventAndEmptyConfig) { + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/true, "handle", {"*"}); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // The capture handle set by the captured tab is observable by the capturer. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); + + // New CaptureHandleConfig set by captured tab triggers an event, and all + // subsequent calls to getSettings produce the new values. + captured_tab.SetCaptureHandleConfig(/*expose_origin=*/true, "handle", + {kArbitraryOrigin}); + EXPECT_EQ(capturing_tab.LastEvent(), "{}"); + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), kNoCaptureHandle); +} + +IN_PROC_BROWSER_TEST_F( + CaptureHandleBrowserTest, + PermittedOriginsChangeThatAddsCapturerCausesEventAndConfigExposure) { + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/true, "handle", {kArbitraryOrigin}); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // The capture handle set by the captured tab is observable by the capturer. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), kNoCaptureHandle); + + // New CaptureHandleConfig set by captured tab triggers an event, and all + // subsequent calls to getSettings produce the new values. + captured_tab.SetCaptureHandleConfig(/*expose_origin=*/true, "handle", {"*"}); + EXPECT_EQ(capturing_tab.LastEvent(), captured_tab.capture_handle); + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); +} + +IN_PROC_BROWSER_TEST_F( + CaptureHandleBrowserTest, + PermittedOriginsChangeThatDoesNotAffectCapturerDoesNotCauseEventOrChange) { + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/true, "handle", {"*"}); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // The capture handle set by the captured tab is observable by the capturer. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); + + // New CaptureHandleConfig set by captured tab triggers an event, and all + // subsequent calls to getSettings produce the new values. + captured_tab.SetCaptureHandleConfig(/*expose_origin=*/true, "handle", + {capturing_tab.GetOriginAsString()}); + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); +} + +IN_PROC_BROWSER_TEST_F(CaptureHandleBrowserTest, + SameDocumentNavigationDoesNotClearTheCaptureHandle) { + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/true, "handle", {"*"}); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // Sanity test - there was an initial handle. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); + + // In-document navigation does not change the capture handle (config). + std::string navigation_result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + captured_tab.web_contents->GetMainFrame(), "clickLinkToPageBottom();", + &navigation_result)); + ASSERT_EQ(navigation_result, "navigated"); + + // No event was fired (verified in teardown) and getSettings returns the + // same configuration as previously. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); +} + +IN_PROC_BROWSER_TEST_F(CaptureHandleBrowserTest, + CrossDocumentNavigationClearsTheCaptureHandle) { + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/true, "handle", {"*"}); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // Sanity test - there was an initial handle. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); + + // Cross-document navigation clears the capture handle (config). + captured_tab.Navigate(browser(), + servers_[kCapturedServer]->GetURL(kCapturedPageOther), + /*expect_handle_reset=*/true); + + // Navigation cleared the the capture handle, and that fired an event + // with the empty CaptureHandle. + EXPECT_EQ(capturing_tab.LastEvent(), "{}"); + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), kNoCaptureHandle); +} + +IN_PROC_BROWSER_TEST_F(CaptureHandleBrowserTest, + CrossOriginNavigationClearsTheCaptureHandle) { + TabInfo captured_tab = + SetUpCapturedPage(/*expose_origin=*/true, "handle", {"*"}); + + TabInfo capturing_tab = SetUpCapturingPage(/*start_capturing=*/true); + + // Sanity test - there was an initial handle. + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), + captured_tab.capture_handle); + + // Sanity over the test itself - the new server has a different origin. + ASSERT_FALSE(url::Origin::Create(servers_[kOtherCapturedServer]->base_url()) + .IsSameOriginWith(captured_tab.GetOrigin())); + + // Cross-origin navigation clears the capture handle (config) and fires + // an event with the empty CaptureHandle. + captured_tab.Navigate( + browser(), servers_[kOtherCapturedServer]->GetURL(kCapturedPageOther), + /*expect_handle_reset=*/true); + EXPECT_EQ(capturing_tab.LastEvent(), "{}"); + EXPECT_EQ(capturing_tab.ReadCaptureHandleFromSettings(), kNoCaptureHandle); +} + +IN_PROC_BROWSER_TEST_F(CaptureHandleBrowserTest, + SelfCaptureSanityWhenPermitted) { + TabInfo tab = SetUpCapturedPage(/*expose_origin=*/true, "handle", {"*"}, + /*self_capture=*/true); + tab.StartCapturing(); + + // Correct initial value read. + EXPECT_EQ(tab.ReadCaptureHandleFromSettings(), tab.capture_handle); + + // Events correctly fired when self-capturing. + tab.SetCaptureHandleConfig(/*expose_origin=*/true, "new_handle", {"*"}); + EXPECT_EQ(tab.LastEvent(), tab.capture_handle); + EXPECT_EQ(tab.ReadCaptureHandleFromSettings(), tab.capture_handle); +} + +IN_PROC_BROWSER_TEST_F(CaptureHandleBrowserTest, + SelfCaptureSanityWhenNotPermitted) { + TabInfo tab = + SetUpCapturedPage(/*expose_origin=*/true, "handle", {kArbitraryOrigin}, + /*self_capture=*/true); + + ASSERT_TRUE(tab.GetOrigin().IsSameOriginWith(tab.GetOrigin())); + + tab.StartCapturing(); + + // Correct initial value read. + EXPECT_EQ(tab.ReadCaptureHandleFromSettings(), kNoCaptureHandle); + + // No events fired when self-capturing but not allowed to observe.. + tab.SetCaptureHandleConfig(/*expose_origin=*/true, "new_handle", + {kArbitraryOrigin}); + EXPECT_EQ(tab.ReadCaptureHandleFromSettings(), kNoCaptureHandle); +} + +#endif // !BUILDFLAG(IS_CHROMEOS_LACROS) diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.cc index 1afd384d2d188e..1af567d949e05e 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.cc @@ -23,13 +23,16 @@ DesktopMediaListController::DesktopMediaListController( std::unique_ptr<DesktopMediaList> media_list) : dialog_(parent), media_list_(std::move(media_list)), + auto_select_tab_( + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kAutoSelectTabCaptureSourceByTitle)), auto_select_source_( base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kAutoSelectDesktopCaptureSource)), - auto_accept_tab_capture_( + auto_accept_this_tab_capture_( base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kThisTabCaptureAutoAccept)), - auto_reject_tab_capture_( + auto_reject_this_tab_capture_( base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kThisTabCaptureAutoReject)) {} @@ -171,7 +174,13 @@ void DesktopMediaListController::OnViewIsDeleting(views::View* view) { bool DesktopMediaListController::ShouldAutoAccept( const DesktopMediaList::Source& source) const { if (media_list_->GetMediaListType() == DesktopMediaList::Type::kCurrentTab) { - return auto_accept_tab_capture_; + return auto_accept_this_tab_capture_; + } else if (media_list_->GetMediaListType() == + DesktopMediaList::Type::kWebContents && + !auto_select_tab_.empty() && + source.name.find(base::ASCIIToUTF16(auto_select_tab_)) != + std::u16string::npos) { + return true; } return (!auto_select_source_.empty() && @@ -182,7 +191,7 @@ bool DesktopMediaListController::ShouldAutoAccept( bool DesktopMediaListController::ShouldAutoReject( const DesktopMediaList::Source& source) const { if (media_list_->GetMediaListType() == DesktopMediaList::Type::kCurrentTab) { - return auto_reject_tab_capture_; + return auto_reject_this_tab_capture_; } return false; } diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.h b/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.h index f6636c405ed34a..3f03ab48af6a94 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.h +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_list_controller.h @@ -132,9 +132,10 @@ class DesktopMediaListController : public DesktopMediaListObserver, view_observations_{this}; // Auto-selection. Used only in tests. - const std::string auto_select_source_; - const bool auto_accept_tab_capture_; - const bool auto_reject_tab_capture_; + const std::string auto_select_tab_; // Only tabs, by title. + const std::string auto_select_source_; // Any source by its title. + const bool auto_accept_this_tab_capture_; // Only for current-tab capture. + const bool auto_reject_this_tab_capture_; // Only for current-tab capture. base::WeakPtrFactory<DesktopMediaListController> weak_factory_{this}; }; diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 314e5528af40fa..e27edd38d9fa0a 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -96,6 +96,15 @@ const char kAutoOpenDevToolsForTabs[] = "auto-open-devtools-for-tabs"; const char kAutoSelectDesktopCaptureSource[] = "auto-select-desktop-capture-source"; +// This flag makes Chrome auto-select a tab with the provided title when +// the media-picker should otherwise be displayed to the user. This switch +// is very similar to kAutoSelectDesktopCaptureSource, but limits selection +// to tabs. This solves the issue of kAutoSelectDesktopCaptureSource being +// liable to accidentally capturing the Chromium window instead of the tab, +// as both have the same title if the tab is focused. +const char kAutoSelectTabCaptureSourceByTitle[] = + "auto-select-tab-capture-source-by-title"; + // How often (in seconds) to check for updates. Should only be used for testing // purposes. const char kCheckForUpdateIntervalSec[] = "check-for-update-interval"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 4a7726314c6fc2..6cd006e6f1f46b 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -53,6 +53,7 @@ extern const char kAppsGalleryURL[]; extern const char kAuthServerAllowlist[]; extern const char kAutoOpenDevToolsForTabs[]; extern const char kAutoSelectDesktopCaptureSource[]; +extern const char kAutoSelectTabCaptureSourceByTitle[]; extern const char kCheckForUpdateIntervalSec[]; extern const char kCipherSuiteBlacklist[]; extern const char kCloudPrintFile[]; diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 304ce09dd59432..c9db518b97592b 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn @@ -1442,6 +1442,7 @@ if (!is_android) { "../browser/media/test_license_server.h", "../browser/media/test_license_server_config.h", "../browser/media/unified_autoplay_browsertest.cc", + "../browser/media/webrtc/capture_handle_browsertest.cc", "../browser/media/webrtc/media_stream_devices_controller_browsertest.cc", "../browser/media/webrtc/media_stream_permission_browsertest.cc", "../browser/media/webrtc/test_stats_dictionary.cc", diff --git a/chrome/test/data/webrtc/captured_page_main.html b/chrome/test/data/webrtc/captured_page_main.html new file mode 100644 index 00000000000000..27cb73fba92471 --- /dev/null +++ b/chrome/test/data/webrtc/captured_page_main.html @@ -0,0 +1,62 @@ +<html> + <head> + <!-- The test scans for which source to share according to the title. --> + <title> + Capture Handle Test - Captured Page (totally-unique-captured-page-title) + </title> + <link rel="icon" href="data:," /> + <script> + "use strict"; + + function callSetCaptureHandleConfig( + exposeOrigin, + handle, + permittedOrigins + ) { + navigator.mediaDevices.setCaptureHandleConfig({ + exposeOrigin: exposeOrigin, + handle: handle, + permittedOrigins: permittedOrigins, + }); + window.domAutomationController.send("capture-handle-set"); + } + + function clickLinkToPageBottom() { + document.getElementById("link_to_bottom").click(); + window.domAutomationController.send("navigated"); + } + + function clickLinkToUrl(url) { + let link = document.getElementById("link"); + link.href = url; + link.click(); + window.domAutomationController.send("link-success"); + } + </script> + </head> + <body> + <h1 id="page_top">Capture Handle Test - Captured Page</h1> + <a href="#" id="link">Link</a> + <a href="#page_bottom" id="link_to_bottom">bottom</a> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> + <h2 id="page_bottom">Bottom</h2> + <a href="#page_top" id="link_to_top">top</a> + </body> +</html> diff --git a/chrome/test/data/webrtc/captured_page_other.html b/chrome/test/data/webrtc/captured_page_other.html new file mode 100644 index 00000000000000..b3c6e95f108c1c --- /dev/null +++ b/chrome/test/data/webrtc/captured_page_other.html @@ -0,0 +1,28 @@ +<html> + <head> + <!-- The test scans for which source to share according to the title. --> + <title> + Capture Handle Test - Captured Page Copy (totally-unique-DIFFERENT-captured-page-title) + </title> + <link rel="icon" href="data:," /> + <script> + "use strict"; + + function callSetCaptureHandleConfig( + exposeOrigin, + handle, + permittedOrigins + ) { + navigator.mediaDevices.setCaptureHandleConfig({ + exposeOrigin: exposeOrigin, + handle: handle, + permittedOrigins: permittedOrigins, + }); + window.domAutomationController.send("capture-handle-set"); + } + </script> + </head> + <body> + <h1>Capture Handle Test - Captured Page</h1> + </body> +</html> diff --git a/chrome/test/data/webrtc/capturing_page_main.html b/chrome/test/data/webrtc/capturing_page_main.html new file mode 100644 index 00000000000000..f223bf846bcc8a --- /dev/null +++ b/chrome/test/data/webrtc/capturing_page_main.html @@ -0,0 +1,89 @@ +<html> + <head> + <title>Capture Handle Test - Capturing Page</title> + <link rel="icon" href="data:," /> + <script> + "use strict"; + + let capturedStream; + let capturedVideoTrack; + + function captureOtherTab() { + navigator.mediaDevices + .getDisplayMedia({ video: true }) + .then(handleCaptureSuccess) + .catch(handleCaptureError); + } + + function readLastEvent() { + // Blocks until onCaptureHandleChange() unblocks. + } + + function readCaptureHandleFromSettings() { + if (!capturedVideoTrack) { + window.domAutomationController.send("error-no-video-track"); + return; + } + + let settings = capturedVideoTrack.getSettings(); + if (!settings.captureHandle) { + window.domAutomationController.send("no-capture-handle"); + return; + } + + window.domAutomationController.send( + JSON.stringify(settings.captureHandle) + ); + } + + function handleCaptureSuccess(stream) { + if (capturedStream) { + window.domAutomationController.send("error-multiple-captures"); + return; + } + + capturedStream = stream; + capturedVideoTrack = stream.getVideoTracks()[0]; + + capturedVideoTrack.oncapturehandlechange = onCaptureHandleChange; + + window.domAutomationController.send("capture-success"); + } + + function handleCaptureError(error) { + window.domAutomationController.send("capture-failure"); + } + + function onCaptureHandleChange(event) { + if (event == undefined || event.captureHandle == undefined) { + throw "Unexpected event type."; + } + window.domAutomationController.send( + JSON.stringify(event.captureHandle) + ); + } + + function setTitle(title) { + document.title = title; + window.domAutomationController.send("title-changed"); + } + + // Duplicated from the captured-page in order to test self-capture. + function callSetCaptureHandleConfig( + exposeOrigin, + handle, + permittedOrigins + ) { + navigator.mediaDevices.setCaptureHandleConfig({ + exposeOrigin: exposeOrigin, + handle: handle, + permittedOrigins: permittedOrigins, + }); + window.domAutomationController.send("capture-handle-set"); + } + </script> + </head> + <body> + <h1>Capture Handle Test - Capturing Page</h1> + </body> +</html> From d708fecf3a0a1d7439db2fce566e617024750ea2 Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 14:05:32 +0000 Subject: [PATCH 75/81] Roll vulkan-deps from 7d19f5261090 to 3f59a9b275fb (2 revisions) https://chromium.googlesource.com/vulkan-deps.git/+log/7d19f5261090..3f59a9b275fb Changed dependencies: * spirv-tools: https://chromium.googlesource.com/external/github.com/KhronosGroup/SPIRV-Tools.git/+log/ec1bc3e2e5..0861a8fa21 If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/vulkan-deps-chromium-autoroll Please CC radial-bots+chrome-roll@google.com,ynovikov@google.com,enga@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win-asan;luci.chromium.try:win_optional_gpu_tests_rel;luci.chromium.try:linux-swangle-try-x64;luci.chromium.try:win-swangle-try-x86;luci.chromium.try:dawn-linux-x64-deps-rel Bug: None Tbr: radial-bots+chrome-roll@google.com,ynovikov@google.com,enga@google.com Change-Id: I07fbed17a61dba0236a5ae0310cb80bea4161234 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2927722 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887952} --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index f67c40d40ee631..ace995e8c985f2 100644 --- a/DEPS +++ b/DEPS @@ -1547,7 +1547,7 @@ deps = { 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '22ba62ffe79c3881581ab430368bf3764d9533eb', - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@7d19f5261090fbb07bd30679184538c36bee229c', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@3f59a9b275fbae45d3388732b2345c112a1e0a45', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '732a76d9d3c70d6aa487216495eeb28518349c3a', From 8bfa91a169ea0c4ffc7c100c3922992482733dbf Mon Sep 17 00:00:00 2001 From: Maksim Ivanov <emaxx@chromium.org> Date: Tue, 1 Jun 2021 14:08:01 +0000 Subject: [PATCH 76/81] Fix potential use-after-move in //components/os_crypt/ Fix the potential scenario in which the already-moved-from variable could be used again in key_storage_linux.cc. The problem was found by the clang-tidy bugprone-use-after-move diagnostics: key_storage_linux.cc:186: 'application_name' used after it was moved key_storage_linux.cc:173: move occurred here Bug: 1122844 Change-Id: Idb6ad5ae353c6ddd5192ae05f750ff59255a46e3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929176 Reviewed-by: Christos Froussios <cfroussios@chromium.org> Commit-Queue: Christos Froussios <cfroussios@chromium.org> Auto-Submit: Maksim Ivanov <emaxx@chromium.org> Cr-Commit-Position: refs/heads/master@{#887953} --- components/os_crypt/key_storage_linux.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/os_crypt/key_storage_linux.cc b/components/os_crypt/key_storage_linux.cc index 53b1903ff04043..7faca2d58fa595 100644 --- a/components/os_crypt/key_storage_linux.cc +++ b/components/os_crypt/key_storage_linux.cc @@ -170,7 +170,7 @@ std::unique_ptr<KeyStorageLinux> KeyStorageLinux::CreateServiceInternal( #if defined(USE_LIBSECRET) if (selected_backend == os_crypt::SelectedLinuxBackend::GNOME_ANY || selected_backend == os_crypt::SelectedLinuxBackend::GNOME_LIBSECRET) { - key_storage = std::make_unique<KeyStorageLibsecret>(std::move(application_name)); + key_storage = std::make_unique<KeyStorageLibsecret>(application_name); if (key_storage->WaitForInitOnTaskRunner()) { VLOG(1) << "OSCrypt using Libsecret as backend."; return key_storage; @@ -183,7 +183,7 @@ std::unique_ptr<KeyStorageLinux> KeyStorageLinux::CreateServiceInternal( if (selected_backend == os_crypt::SelectedLinuxBackend::GNOME_ANY || selected_backend == os_crypt::SelectedLinuxBackend::GNOME_KEYRING) { key_storage = std::make_unique<KeyStorageKeyring>(config.main_thread_runner, - std::move(application_name)); + application_name); if (key_storage->WaitForInitOnTaskRunner()) { VLOG(1) << "OSCrypt using Keyring as backend."; return key_storage; From c96ab8d23b45d41df2c8303c41ea248b5899029a Mon Sep 17 00:00:00 2001 From: Jit Yao Yap <jityao@google.com> Date: Tue, 1 Jun 2021 14:13:33 +0000 Subject: [PATCH 77/81] [protosync] Server-side -> client Sync changes from cl/365859465, cl/356812494 and cl/371955944. Change-Id: Ib0b68fef4b11d0d251d5cb92773f47fa401b5874 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929182 Reviewed-by: Alexander Hendrich <hendrich@chromium.org> Commit-Queue: Jit Yao Yap <jityao@google.com> Cr-Commit-Position: refs/heads/master@{#887954} --- components/policy/proto/device_management_backend.proto | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index ac2908a56225b1..c74b916e393e19 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto @@ -748,7 +748,7 @@ message PolicyFetchResponse { // Please note that |new_public_key| is also included inside this data // field. Thus we have new public key signed with old version of private key // (if client indicated to us that it has old key version), and - // new public key data signed by master verification key (if client told + // new public key data signed by primary verification key (if client told // us that it has public verification key - see |verification_key_id| field // of |PolicyFetchRequest|). In most cases, both signatures will be provided. // However, client might not have old policy signing key - for example, when @@ -1952,8 +1952,8 @@ message ChromeDesktopReportRequest { // TODO(crbug.com/1105938): This will also replace the computer_name and // serial_number fields. optional BrowserDeviceIdentifier browser_device_identifier = 9; - // A list of flags indicates that the report only contains particular - // information. When list is empty or unset, the report should contains all + // A list of flags indicating that the report only contains particular + // information. When the list is empty or unset, the report should contain all // information. repeated PartialReportType partial_report_types = 10; // Public key that can be used for attesting the machine. @@ -2414,6 +2414,8 @@ message DeviceInitialEnrollmentStateResponse { CHROME_ENTERPRISE = 1; // Education SKU. CHROME_EDUCATION = 2; + // Terminal SKU + CHROME_TERMINAL = 3; } // LINT.ThenChange(//depot/google3/google/chrome/licensepackaging/v1/service.proto) From 773fc0e7c8fa5e419a79335b3d24b9c690b63972 Mon Sep 17 00:00:00 2001 From: Dave Tapuska <dtapuska@chromium.org> Date: Tue, 1 Jun 2021 14:15:26 +0000 Subject: [PATCH 78/81] Add a web_view_ member to RenderViewTest. Reduce the number of callers to GetWebView by storing the blink::WebView inside the RenderViewTest. This lays the ground work for RenderViewTest eventually owning the WebView itself. BUG=1155202 Change-Id: I0e69678de320c83de050424378910a5edd5194c1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2929039 Reviewed-by: Avi Drissman <avi@chromium.org> Commit-Queue: Dave Tapuska <dtapuska@chromium.org> Owners-Override: Dave Tapuska <dtapuska@chromium.org> Cr-Commit-Position: refs/heads/master@{#887955} --- ...orm_control_click_detection_browsertest.cc | 10 +- .../form_autofill_util_browsertest.cc | 2 +- content/public/test/render_view_test.cc | 14 +-- content/public/test/render_view_test.h | 4 + .../renderer/render_frame_impl_browsertest.cc | 5 +- content/renderer/render_view_browsertest.cc | 95 ++++++++----------- content/renderer/render_widget_browsertest.cc | 2 +- 7 files changed, 63 insertions(+), 69 deletions(-) diff --git a/chrome/renderer/autofill/form_control_click_detection_browsertest.cc b/chrome/renderer/autofill/form_control_click_detection_browsertest.cc index d81433d18263df..b684ece1ac94bf 100644 --- a/chrome/renderer/autofill/form_control_click_detection_browsertest.cc +++ b/chrome/renderer/autofill/form_control_click_detection_browsertest.cc @@ -23,7 +23,7 @@ class FormControlClickDetectionTest : public ChromeRenderViewTest { void SetUp() override { ChromeRenderViewTest::SetUp(); // Must be set before loading HTML. - view_->GetWebView()->SetDefaultPageScaleLimits(1, 4); + web_view_->SetDefaultPageScaleLimits(1, 4); LoadHTML( "<form>" @@ -170,8 +170,8 @@ TEST_F(FormControlClickDetectionTest, TextAreaFocusedAndClicked) { TEST_F(FormControlClickDetectionTest, ScaledTextareaClicked) { ClearAutofillAgentTestState(); EXPECT_NE(textarea_, textarea_.GetDocument().FocusedElement()); - view_->GetWebView()->SetPageScaleFactor(3); - view_->GetWebView()->SetVisualViewportOffset(gfx::PointF(50, 50)); + web_view_->SetPageScaleFactor(3); + web_view_->SetVisualViewportOffset(gfx::PointF(50, 50)); // Click textarea_1. SimulatePointClick(gfx::Point(30, 30)); @@ -183,8 +183,8 @@ TEST_F(FormControlClickDetectionTest, ScaledTextareaClicked) { TEST_F(FormControlClickDetectionTest, ScaledTextareaTapped) { ClearAutofillAgentTestState(); EXPECT_NE(textarea_, textarea_.GetDocument().FocusedElement()); - view_->GetWebView()->SetPageScaleFactor(3); - view_->GetWebView()->SetVisualViewportOffset(gfx::PointF(50, 50)); + web_view_->SetPageScaleFactor(3); + web_view_->SetVisualViewportOffset(gfx::PointF(50, 50)); // Tap textarea_1. SimulateRectTap(gfx::Rect(30, 30, 30, 30)); diff --git a/components/autofill/content/renderer/form_autofill_util_browsertest.cc b/components/autofill/content/renderer/form_autofill_util_browsertest.cc index 2c2ec4528eb057..dfb08a380b1d00 100644 --- a/components/autofill/content/renderer/form_autofill_util_browsertest.cc +++ b/components/autofill/content/renderer/form_autofill_util_browsertest.cc @@ -982,7 +982,7 @@ TEST_F(FormAutofillUtilsTest, IsVisibleIframeTest) { </body>)"); // Ensure that Android runs at default page scale. - view_->GetWebView()->SetPageScaleFactor(1.0); + web_view_->SetPageScaleFactor(1.0); std::vector<WebElement> iframes = [this] { WebDocument doc = GetMainFrame()->GetDocument(); diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc index b6a94c58cf15e4..d764f7a486a708 100644 --- a/content/public/test/render_view_test.cc +++ b/content/public/test/render_view_test.cc @@ -324,7 +324,7 @@ RenderViewTest::RenderViewTest(bool hook_render_frame_creation) RenderViewTest::~RenderViewTest() = default; WebLocalFrame* RenderViewTest::GetMainFrame() { - return view_->GetWebView()->MainFrame()->ToWebLocalFrame(); + return web_view_->MainFrame()->ToWebLocalFrame(); } void RenderViewTest::ExecuteJavaScriptForTests(const char* js) { @@ -371,7 +371,7 @@ void RenderViewTest::LoadHTML(const char* html) { // The load may happen asynchronously, so we pump messages to process // the pending continuation. waiter.Wait(); - view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + web_view_->MainFrameWidget()->UpdateAllLifecyclePhases( blink::DocumentUpdateReason::kTest); } @@ -384,7 +384,7 @@ void RenderViewTest::LoadHTMLWithUrlOverride(const char* html, // The load may happen asynchronously, so we pump messages to process // the pending continuation. waiter.Wait(); - view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + web_view_->MainFrameWidget()->UpdateAllLifecyclePhases( blink::DocumentUpdateReason::kTest); } @@ -538,6 +538,7 @@ void RenderViewTest::SetUp() { waiter.Wait(); view_ = view; + web_view_ = view->GetWebView(); } void RenderViewTest::TearDown() { @@ -558,6 +559,7 @@ void RenderViewTest::TearDown() { // |view_| is ref-counted and deletes itself during the RunUntilIdle() call // below. view_ = nullptr; + web_view_ = nullptr; process_.reset(); // After telling the view to close and resetting process_ we may get @@ -773,7 +775,7 @@ void RenderViewTest::Reload(const GURL& url) { FrameLoadWaiter waiter(frame); frame->Navigate(std::move(common_params), std::move(commit_params)); waiter.Wait(); - view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + web_view_->MainFrameWidget()->UpdateAllLifecyclePhases( blink::DocumentUpdateReason::kTest); } @@ -853,7 +855,7 @@ void RenderViewTest::SetUseZoomForDSFEnabled(bool enabled) { } blink::WebFrameWidget* RenderViewTest::GetWebFrameWidget() { - return view_->GetWebView()->MainFrameWidget(); + return web_view_->MainFrameWidget(); } ContentClient* RenderViewTest::CreateContentClient() { @@ -886,7 +888,7 @@ void RenderViewTest::GoToOffset(int offset, const GURL& url, const blink::PageState& state) { RenderViewImpl* view = static_cast<RenderViewImpl*>(view_); - blink::WebView* webview = view->GetWebView(); + blink::WebView* webview = web_view_; int history_list_length = webview->HistoryBackListCount() + webview->HistoryForwardListCount() + 1; int pending_offset = offset + webview->HistoryBackListCount(); diff --git a/content/public/test/render_view_test.h b/content/public/test/render_view_test.h index 977e619a02ad61..873be598b3c6c9 100644 --- a/content/public/test/render_view_test.h +++ b/content/public/test/render_view_test.h @@ -214,6 +214,10 @@ class RenderViewTest : public testing::Test { // We use a naked pointer because we don't want to expose RenderViewImpl in // the embedder's namespace. RenderView* view_ = nullptr; + // The WebView is owned by `view_` but provided as a raw pointer here. This + // will provide a transition of eventually removing RenderView and owning + // it directly here. See https://crbug.com/1155202. + blink::WebView* web_view_ = nullptr; RendererBlinkPlatformImplTestOverride blink_platform_impl_; std::unique_ptr<ContentClient> content_client_; std::unique_ptr<ContentBrowserClient> content_browser_client_; diff --git a/content/renderer/render_frame_impl_browsertest.cc b/content/renderer/render_frame_impl_browsertest.cc index 93db5889081ab2..48db49fc561e7e 100644 --- a/content/renderer/render_frame_impl_browsertest.cc +++ b/content/renderer/render_frame_impl_browsertest.cc @@ -260,9 +260,8 @@ TEST_F(RenderFrameImplTest, FrameResize) { main_frame_widget->ApplyVisualProperties(visual_properties); // The main frame widget's size is the "widget size", not the visible viewport // size, which is given to blink separately. - EXPECT_EQ(gfx::Size(view_->GetWebView()->MainFrameWidget()->Size()), - widget_size); - EXPECT_EQ(gfx::SizeF(view_->GetWebView()->VisualViewportSize()), + EXPECT_EQ(gfx::Size(web_view_->MainFrameWidget()->Size()), widget_size); + EXPECT_EQ(gfx::SizeF(web_view_->VisualViewportSize()), gfx::SizeF(visible_size)); // The main frame doesn't change other local roots directly. EXPECT_NE(gfx::Size(frame_widget()->Size()), visible_size); diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index 1778b5d944edb4..e27e610510b294 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc @@ -337,14 +337,11 @@ class RenderViewImplTest : public RenderViewTest { return render_widget_host_->LastCompositionBounds(); } - void ReceiveDisableDeviceEmulation(RenderViewImpl* view) { - view->GetWebView()->DisableDeviceEmulation(); - } + void ReceiveDisableDeviceEmulation() { web_view_->DisableDeviceEmulation(); } void ReceiveEnableDeviceEmulation( - RenderViewImpl* view, const blink::DeviceEmulationParams& params) { - view->GetWebView()->EnableDeviceEmulation(params); + web_view_->EnableDeviceEmulation(params); } void GoToOffsetWithParams(int offset, @@ -352,7 +349,7 @@ class RenderViewImplTest : public RenderViewTest { mojom::CommonNavigationParamsPtr common_params, mojom::CommitNavigationParamsPtr commit_params) { EXPECT_TRUE(common_params->transition & ui::PAGE_TRANSITION_FORWARD_BACK); - blink::WebView* webview = view()->GetWebView(); + blink::WebView* webview = web_view_; int pending_offset = offset + webview->HistoryBackListCount(); commit_params->page_state = state; @@ -511,14 +508,12 @@ class RenderViewImplTest : public RenderViewTest { } void EnablePreferredSizeMode() { - blink::WebView* webview = view()->GetWebView(); - webview->EnablePreferredSizeChangedMode(); + web_view_->EnablePreferredSizeChangedMode(); } gfx::Size GetPreferredSize() { - blink::WebView* webview = view()->GetWebView(); - webview->UpdatePreferredSize(); - return gfx::Size(webview->GetPreferredSizeForTest()); + web_view_->UpdatePreferredSize(); + return gfx::Size(web_view_->GetPreferredSizeForTest()); } gfx::Size MainWidgetSizeInDIPS() { @@ -529,9 +524,8 @@ class RenderViewImplTest : public RenderViewTest { } int GetScrollbarWidth() { - blink::WebView* webview = view()->GetWebView(); - return webview->MainFrameWidget()->Size().width() - - webview->MainFrame() + return web_view_->MainFrameWidget()->Size().width() - + web_view_->MainFrame() ->ToWebLocalFrame() ->VisibleContentRect() .width(); @@ -545,7 +539,7 @@ class RenderViewImplBlinkSettingsTest : public RenderViewImplTest { public: virtual void DoSetUp() { RenderViewImplTest::SetUp(); } - blink::WebSettings* settings() { return view()->GetWebView()->GetSettings(); } + blink::WebSettings* settings() { return web_view_->GetSettings(); } protected: // Blink settings may be specified on the command line, which must @@ -582,8 +576,7 @@ class RenderViewImplScaleFactorTest : public RenderViewImplTest { visual_properties.new_size = gfx::Size(100, 100); visual_properties.compositor_viewport_pixel_rect = gfx::Rect(200, 200); visual_properties.visible_viewport_size = visual_properties.new_size; - visual_properties.auto_resize_enabled = - view()->GetWebView()->AutoResizeMode(); + visual_properties.auto_resize_enabled = web_view_->AutoResizeMode(); visual_properties.min_size_for_auto_resize = min_size_for_autoresize_; visual_properties.max_size_for_auto_resize = max_size_for_autoresize_; visual_properties.local_surface_id = @@ -601,7 +594,7 @@ class RenderViewImplScaleFactorTest : public RenderViewImplTest { blink::DeviceEmulationParams params; params.view_size = gfx::Size(width, height); params.device_scale_factor = dpr; - ReceiveEnableDeviceEmulation(view(), params); + ReceiveEnableDeviceEmulation(params); EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_width, &emulated_width)); EXPECT_EQ(width, emulated_width); EXPECT_TRUE( @@ -616,8 +609,7 @@ class RenderViewImplScaleFactorTest : public RenderViewImplTest { void EnableAutoResize(const gfx::Size& min_size, const gfx::Size& max_size) { min_size_for_autoresize_ = min_size; max_size_for_autoresize_ = max_size; - blink::WebView* webview = view()->GetWebView(); - webview->EnableAutoResizeForTesting(min_size, max_size); + web_view_->EnableAutoResizeForTesting(min_size, max_size); } private: @@ -684,7 +676,7 @@ TEST_F(RenderViewImplTest, IsPinchGestureActivePropagatesToProxies) { args.browser_controls_constraint = cc::BrowserControlsState::kHidden; args.scroll_gesture_did_end = false; - view()->GetWebView()->MainFrameWidget()->ApplyViewportChangesForTesting(args); + web_view_->MainFrameWidget()->ApplyViewportChangesForTesting(args); EXPECT_TRUE(root_web_frame->FirstChild() ->ToWebRemoteFrame() ->GetPendingVisualPropertiesForTesting() @@ -707,7 +699,7 @@ TEST_F(RenderViewImplTest, IsPinchGestureActivePropagatesToProxies) { // Reset the flag, make sure both children respond. args.is_pinch_gesture_active = false; - view()->GetWebView()->MainFrameWidget()->ApplyViewportChangesForTesting(args); + web_view_->MainFrameWidget()->ApplyViewportChangesForTesting(args); EXPECT_FALSE(root_web_frame->FirstChild() ->ToWebRemoteFrame() ->GetPendingVisualPropertiesForTesting() @@ -916,10 +908,9 @@ TEST_F(RenderViewImplTest, BeginNavigation) { } TEST_F(RenderViewImplTest, BeginNavigationHandlesAllTopLevel) { - blink::RendererPreferences prefs = - view()->GetWebView()->GetRendererPreferences(); + blink::RendererPreferences prefs = web_view_->GetRendererPreferences(); prefs.browser_handles_all_top_level_requests = true; - view()->GetWebView()->SetRendererPreferences(prefs); + web_view_->SetRendererPreferences(prefs); const blink::WebNavigationType kNavTypes[] = { blink::kWebNavigationTypeLinkClicked, @@ -1085,10 +1076,10 @@ TEST_F(RenderViewImplScaleFactorTest, DeviceEmulationWithOOPIF) { EXPECT_EQ(device_scale, main_frame_widget()->GetOriginalScreenInfo().device_scale_factor); - ReceiveDisableDeviceEmulation(view()); + ReceiveDisableDeviceEmulation(); blink::DeviceEmulationParams params; - ReceiveEnableDeviceEmulation(view(), params); + ReceiveEnableDeviceEmulation(params); // Don't disable here to test that emulation is being shutdown properly. } @@ -1156,7 +1147,7 @@ TEST_F(RenderViewImplEnableZoomForDSFTest, static_cast<mojom::Frame*>(frame())->Unload( kProxyRoutingId, true, replication_state->Clone(), blink::RemoteFrameToken(), CreateStubRemoteFrameInterfaces()); - EXPECT_TRUE(view()->GetWebView()->MainFrame()->IsWebRemoteFrame()); + EXPECT_TRUE(web_view_->MainFrame()->IsWebRemoteFrame()); // Do the remote-to-local transition for the proxy, which is to create a // provisional local frame. @@ -1215,8 +1206,7 @@ TEST_F(RenderViewImplEnableZoomForDSFTest, base::RunLoop().RunUntilIdle(); EXPECT_EQ(device_scale, view()->GetMainRenderFrame()->GetDeviceScaleFactor()); - EXPECT_EQ(device_scale, - view()->GetWebView()->ZoomFactorForDeviceScaleFactor()); + EXPECT_EQ(device_scale, web_view_->ZoomFactorForDeviceScaleFactor()); double device_pixel_ratio; std::u16string get_dpr = u"Number(window.devicePixelRatio)"; @@ -1227,8 +1217,7 @@ TEST_F(RenderViewImplEnableZoomForDSFTest, int width; std::u16string get_width = u"Number(document.documentElement.clientWidth)"; EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_width, &width)); - EXPECT_EQ(view()->GetWebView()->MainFrameWidget()->Size().width(), - width * device_scale); + EXPECT_EQ(web_view_->MainFrameWidget()->Size().width(), width * device_scale); } // Test that when a parent detaches a remote child after the provisional @@ -1297,7 +1286,7 @@ TEST_F(RenderViewImplEnableZoomForDSFTest, ->Unload(kProxyRoutingId, true, ReconstructReplicationStateForTesting(main_frame), blink::RemoteFrameToken(), CreateStubRemoteFrameInterfaces()); - EXPECT_TRUE(view()->GetWebView()->MainFrame()->IsWebRemoteFrame()); + EXPECT_TRUE(web_view_->MainFrame()->IsWebRemoteFrame()); } class TextInputStateFakeRenderWidgetHost : public FakeRenderWidgetHost { @@ -2042,7 +2031,7 @@ TEST_F(RenderViewImplTest, ImeComposition) { // result. const int kMaxOutputCharacters = 128; std::u16string output = TestWebFrameContentDumper::DumpWebViewAsText( - view()->GetWebView(), kMaxOutputCharacters) + web_view_, kMaxOutputCharacters) .Utf16(); EXPECT_EQ(base::WideToUTF16(ime_message->result), output); } @@ -2093,7 +2082,7 @@ TEST_F(RenderViewImplTest, OnSetTextDirection) { // expected result. const int kMaxOutputCharacters = 16; std::u16string output = TestWebFrameContentDumper::DumpWebViewAsText( - view()->GetWebView(), kMaxOutputCharacters) + web_view_, kMaxOutputCharacters) .Utf16(); EXPECT_EQ(base::WideToUTF16(test_case.expected_result), output); } @@ -2528,7 +2517,7 @@ TEST_F(RenderViewImplTest, NavigateSubframe) { // expected result. const int kMaxOutputCharacters = 256; std::string output = TestWebFrameContentDumper::DumpWebViewAsText( - view()->GetWebView(), kMaxOutputCharacters) + web_view_, kMaxOutputCharacters) .Utf8(); EXPECT_EQ(output, "hello \n\nworld"); } @@ -2645,7 +2634,7 @@ TEST_F(RendererErrorPageTest, RegularError) { FrameLoadWaiter(main_frame).Wait(); const int kMaxOutputCharacters = 22; EXPECT_EQ("A suffusion of yellow.", - TestWebFrameContentDumper::DumpWebViewAsText(view()->GetWebView(), + TestWebFrameContentDumper::DumpWebViewAsText(web_view_, kMaxOutputCharacters) .Ascii()); } @@ -2864,7 +2853,7 @@ TEST_F(RenderViewImplTest, PreferredSizeZoomed) { main_frame_widget()->SetZoomLevelForTesting( blink::PageZoomFactorToZoomLevel(2.0)); - view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + web_view_->MainFrameWidget()->UpdateAllLifecyclePhases( blink::DocumentUpdateReason::kTest); size = GetPreferredSize(); EXPECT_EQ(gfx::Size(800 + scrollbar_width, 800), size); @@ -2895,7 +2884,7 @@ TEST_F(RenderViewImplScaleFactorTest, PreferredSizeWithScaleFactor) { // Ensure the RenderViewImpl history list is properly updated when starting a // new browser-initiated navigation. TEST_F(RenderViewImplTest, HistoryIsProperlyUpdatedOnNavigation) { - blink::WebView* webview = view()->GetWebView(); + blink::WebView* webview = web_view_; EXPECT_EQ(0, webview->HistoryBackListCount()); EXPECT_EQ(0, webview->HistoryBackListCount() + webview->HistoryForwardListCount() + 1); @@ -2915,7 +2904,7 @@ TEST_F(RenderViewImplTest, HistoryIsProperlyUpdatedOnNavigation) { // Ensure the RenderViewImpl history list is properly updated when starting a // new history browser-initiated navigation. TEST_F(RenderViewImplTest, HistoryIsProperlyUpdatedOnHistoryNavigation) { - blink::WebView* webview = view()->GetWebView(); + blink::WebView* webview = web_view_; EXPECT_EQ(0, webview->HistoryBackListCount()); EXPECT_EQ(0, webview->HistoryBackListCount() + webview->HistoryForwardListCount() + 1); @@ -2937,7 +2926,7 @@ TEST_F(RenderViewImplTest, HistoryIsProperlyUpdatedOnHistoryNavigation) { // Ensure the RenderViewImpl history list is properly updated when starting a // new history browser-initiated navigation with should_clear_history_list TEST_F(RenderViewImplTest, HistoryIsProperlyUpdatedOnShouldClearHistoryList) { - blink::WebView* webview = view()->GetWebView(); + blink::WebView* webview = web_view_; EXPECT_EQ(0, webview->HistoryBackListCount()); EXPECT_EQ(0, webview->HistoryBackListCount() + webview->HistoryForwardListCount() + 1); @@ -3096,18 +3085,18 @@ TEST_F(RenderViewImplBlinkSettingsTest, DefaultPageScaleSettings) { "}" "</style>"); - EXPECT_EQ(1.f, view()->GetWebView()->PageScaleFactor()); - EXPECT_EQ(1.f, view()->GetWebView()->MinimumPageScaleFactor()); + EXPECT_EQ(1.f, web_view_->PageScaleFactor()); + EXPECT_EQ(1.f, web_view_->MinimumPageScaleFactor()); blink::web_pref::WebPreferences prefs; prefs.shrinks_viewport_contents_to_fit = true; prefs.default_minimum_page_scale_factor = 0.1f; prefs.default_maximum_page_scale_factor = 5.5f; - view()->GetWebView()->SetWebPreferences(prefs); + web_view_->SetWebPreferences(prefs); - EXPECT_EQ(1.f, view()->GetWebView()->PageScaleFactor()); - EXPECT_EQ(1.f, view()->GetWebView()->MinimumPageScaleFactor()); - EXPECT_EQ(5.5f, view()->GetWebView()->MaximumPageScaleFactor()); + EXPECT_EQ(1.f, web_view_->PageScaleFactor()); + EXPECT_EQ(1.f, web_view_->MinimumPageScaleFactor()); + EXPECT_EQ(5.5f, web_view_->MaximumPageScaleFactor()); } TEST_F(RenderViewImplDisableZoomForDSFTest, @@ -3139,10 +3128,10 @@ TEST_F(RenderViewImplScaleFactorTest, ScreenMetricsEmulationWithOriginalDSF1) { TestEmulatedSizeDprDsf(1005, 1102, 3.f, 1.f); } - ReceiveDisableDeviceEmulation(view()); + ReceiveDisableDeviceEmulation(); blink::DeviceEmulationParams params; - ReceiveEnableDeviceEmulation(view(), params); + ReceiveEnableDeviceEmulation(params); // Don't disable here to test that emulation is being shutdown properly. } @@ -3168,10 +3157,10 @@ TEST_F(RenderViewImplScaleFactorTest, ScreenMetricsEmulationWithOriginalDSF2) { TestEmulatedSizeDprDsf(1005, 1102, 3.f, device_scale); } - ReceiveDisableDeviceEmulation(view()); + ReceiveDisableDeviceEmulation(); blink::DeviceEmulationParams params; - ReceiveEnableDeviceEmulation(view(), params); + ReceiveEnableDeviceEmulation(params); // Don't disable here to test that emulation is being shutdown properly. } @@ -3278,13 +3267,13 @@ TEST_F(RenderViewImplScaleFactorTest, AutoResizeWithoutZoomForDSF) { TEST_F(RenderViewImplTest, ZoomLevelUpdate) { // 0 will use the minimum zoom level, which is the default, nothing will // change. - EXPECT_FLOAT_EQ(0u, view()->GetWebView()->ZoomLevel()); + EXPECT_FLOAT_EQ(0u, web_view_->ZoomLevel()); double zoom_level = blink::PageZoomFactorToZoomLevel(0.25); // Change the zoom level to 25% and check if the view gets the change. main_frame_widget()->SetZoomLevelForTesting(zoom_level); // Use EXPECT_FLOAT_EQ here because view()->GetZoomLevel returns a float. - EXPECT_FLOAT_EQ(zoom_level, view()->GetWebView()->ZoomLevel()); + EXPECT_FLOAT_EQ(zoom_level, web_view_->ZoomLevel()); } #endif diff --git a/content/renderer/render_widget_browsertest.cc b/content/renderer/render_widget_browsertest.cc index 322f95c9c38227..94401fca2077ae 100644 --- a/content/renderer/render_widget_browsertest.cc +++ b/content/renderer/render_widget_browsertest.cc @@ -114,7 +114,7 @@ TEST_F(RenderWidgetTest, CompositorIdHitTestAPI) { float scale_factors[] = {1, 1.5, 2}; for (float factor : scale_factors) { - view_->GetWebView()->SetPageScaleFactor(factor); + web_view_->SetPageScaleFactor(factor); // Hit the root EXPECT_EQ(GetCompositorElementId(), From ba5149012d527b338b6db9b20c9fd63bf0b1b34d Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 14:16:07 +0000 Subject: [PATCH 79/81] Roll ChromeOS Bigcore AFDO profile from 92-4484.0-1621852288-benchmark-92.0.4515.32-r1 to 93-4484.0-1621851890-benchmark-93.0.4522.0-r1 If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/cros-afdo-bigcore-chromium Please CC c-compiler-chrome@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Tbr: c-compiler-chrome@google.com Change-Id: I7a01f75eecba21eb474b6b6d3649908c0c9f9727 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2930258 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887956} --- chromeos/profiles/bigcore.afdo.newest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt index e7a1b05f920f09..3e43a2ce8ca47e 100644 --- a/chromeos/profiles/bigcore.afdo.newest.txt +++ b/chromeos/profiles/bigcore.afdo.newest.txt @@ -1 +1 @@ -chromeos-chrome-amd64-bigcore-92-4484.0-1621852288-benchmark-92.0.4515.32-r1-redacted.afdo.xz +chromeos-chrome-amd64-bigcore-93-4484.0-1621851890-benchmark-93.0.4522.0-r1-redacted.afdo.xz From 7ae6f3fde62d6234b0ba72b451600f8499d3612c Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 14:16:32 +0000 Subject: [PATCH 80/81] Roll Skia from fe9b4316d8de to 9af0bca3de2b (1 revision) https://skia.googlesource.com/skia.git/+log/fe9b4316d8de..9af0bca3de2b 2021-06-01 robertphillips@google.com Minor GrSurfaceDrawContext retraction If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-autoroll Please CC lovisolo@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux-blink-rel;luci.chromium.try:linux-chromeos-compile-dbg;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel Cq-Do-Not-Cancel-Tryjobs: true Bug: None Tbr: lovisolo@google.com Change-Id: Ifcb56b8c8f0eaff5b68e93796362ef3624d77816 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2928330 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887957} --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index ace995e8c985f2..56424c3ccbd857 100644 --- a/DEPS +++ b/DEPS @@ -209,7 +209,7 @@ vars = { # 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': 'fe9b4316d8de469749812376684957347b0709cd', + 'skia_revision': '9af0bca3de2b56c9a8062a4617d5e0490ab90396', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. From 4f8038a274106fe97f6e93e852864819e0519ed6 Mon Sep 17 00:00:00 2001 From: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Date: Tue, 1 Jun 2021 14:17:28 +0000 Subject: [PATCH 81/81] Roll ChromeOS Atom AFDO profile from 92-4484.0-1621849150-benchmark-92.0.4515.32-r1 to 93-4484.0-1621851457-benchmark-93.0.4522.0-r1 If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/cros-afdo-atom-chromium Please CC c-compiler-chrome@google.com on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/master/autoroll/README.md Tbr: c-compiler-chrome@google.com Change-Id: If8f6c4c892af625d4d6cbac38f41dabfa427cb26 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2930280 Commit-Queue: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Bot-Commit: chromium-autoroll <chromium-autoroll@skia-public.iam.gserviceaccount.com> Cr-Commit-Position: refs/heads/master@{#887958} --- chromeos/profiles/atom.afdo.newest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt index b334404b129dc0..79f6c3123375b2 100644 --- a/chromeos/profiles/atom.afdo.newest.txt +++ b/chromeos/profiles/atom.afdo.newest.txt @@ -1 +1 @@ -chromeos-chrome-amd64-atom-92-4484.0-1621849150-benchmark-92.0.4515.32-r1-redacted.afdo.xz +chromeos-chrome-amd64-atom-93-4484.0-1621851457-benchmark-93.0.4522.0-r1-redacted.afdo.xz